/***************************************************************************** * * COPYRIGHT 1993 - COLORADO MEMORY SYSTEMS, INC. * ALL RIGHTS RESERVED. * ****************************************************************************** * * FILE: \SE\DRIVER\Q117KDI\NT\SRC\0X15A05.C * * FUNCTION: kdi_ThreadRun * * PURPOSE: * * HISTORY: * $Log: J:\se.vcs\driver\q117kdi\nt\src\0x15a05.c $ * * Rev 1.2 10 Aug 1994 09:53:18 BOBLEHMA * Changed cast from a dUDDWordPtr to dSDDWordPtr. * * Rev 1.1 18 Jan 1994 16:24:16 KEVINKES * Updated the debug code and fixed compile errors. * * Rev 1.0 02 Dec 1993 15:08:44 KEVINKES * Initial Revision. * *****************************************************************************/ #define FCT_ID 0x15A05 #include "include\public\adi_api.h" #include "include\public\frb_api.h" #include "q117kdi\include\kdiwhio.h" #include "q117kdi\include\kdiwpriv.h" #include "include\private\kdi_pub.h" #include "include\private\cqd_pub.h" /*endinclude*/ dVoid kdi_ThreadRun ( /* INPUT PARAMETERS: */ KdiContextPtr kdi_context /* UPDATE PARAMETERS: */ /* OUTPUT PARAMETERS: */ ) /* COMMENTS: ***************************************************************** * * Routine Description: * * This is the code executed by the system thread created when the * floppy driver initializes. This thread loops forever (or until a * flag is set telling the thread to kill itself) processing packets * put into the queue by the dispatch routines. * * For each packet, this thread calls appropriate routines to process * the request, and then calls FlFinishOperation() to complete the * packet. * * Arguments: * * kdi_context - a pointer to our data area for the controller being * supported (there is one thread per controller). * * Return Value: * * None. * * DEFINITIONS: *************************************************************/ { /* DATA: ********************************************************************/ PIRP irp; PIO_STACK_LOCATION irp_stack_ptr; PLIST_ENTRY request; NTSTATUS ntStatus = 0; ADIRequestHdrPtr frb; dStatus status; /* CODE: ********************************************************************/ /* Set thread priority to lowest realtime level. */ KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY); do { /* Wait for a request from the dispatch routines. */ /* KeWaitForSingleObject won't return error here - this thread */ /* isn't alertable and won't take APCs, and we're not passing in */ /* a timeout. */ (dVoid) KeWaitForSingleObject( (dVoidPtr) &kdi_context->request_semaphore, UserRequest, KernelMode, dFALSE, (dSDDWordPtr) dNULL_PTR ); if ( kdi_context->unloading_driver ) { kdi_CheckedDump(QIC117INFO, "q117i: Thread asked to kill itself\n", 0l); PsTerminateSystemThread( STATUS_SUCCESS ); } while ( !IsListEmpty( &( kdi_context->list_entry ) ) ) { /* Get the request from the queue. We know there is one, */ /* because of the check above. */ request = ExInterlockedRemoveHeadList( &kdi_context->list_entry, &kdi_context->list_spin_lock ); kdi_context->queue_empty = IsListEmpty( &( kdi_context->list_entry ) ); irp = CONTAINING_RECORD( request, IRP, Tail.Overlay.ListEntry ); irp_stack_ptr = IoGetCurrentIrpStackLocation( irp ); if ( kdi_context->clear_queue || irp_stack_ptr->Parameters.DeviceIoControl.IoControlCode == IOCTL_QIC117_CLEAR_QUEUE) { if (irp_stack_ptr->Parameters.DeviceIoControl.IoControlCode == IOCTL_QIC117_CLEAR_QUEUE) { kdi_CheckedDump(QIC117INFO, "Q117i: processing IOCTL_QIC117_CLEAR_QUEUE : TRUE\n", 0l); irp->IoStatus.Status = kdi_ClearIO( irp ); /* NOTE: This is temporary until we ca find how to */ /* correctly free the Mdl using the io subsytem. */ if (irp->MdlAddress != NULL) { IoFreeMdl(irp->MdlAddress); irp->MdlAddress = NULL; } IoCompleteRequest( irp, IO_DISK_INCREMENT ); (VOID) KeSetEvent( &kdi_context->clear_queue_event, (KPRIORITY) 0, FALSE ); } else { kdi_CheckedDump(QIC117INFO, "Q117i: processing IOCTL_QIC117_DRIVE_REQUEST : TRUE\n", 0l); irp->IoStatus.Status = STATUS_CANCELLED; /* NOTE: This is temporary until we ca find how to */ /* correctly free the Mdl using the io subsytem. */ if (irp->MdlAddress != dNULL_PTR) { IoFreeMdl(irp->MdlAddress); irp->MdlAddress = dNULL_PTR; } IoCompleteRequest( irp, IO_DISK_INCREMENT ); } } else { // kdi_context->current_irp = irp; frb = (ADIRequestHdrPtr)irp_stack_ptr->Parameters.DeviceIoControl.Type3InputBuffer; if (irp->MdlAddress != dNULL_PTR) { frb->drv_physical_ptr = irp->MdlAddress; frb->drv_logical_ptr = MmGetSystemAddressForMdl(irp->MdlAddress); } status = cqd_ProcessFRB( kdi_context->cqd_context, frb); irp->IoStatus.Status = kdi_TranslateError( kdi_context->device_object, status ); /* NOTE: This is temporary until we ca find how to */ /* correctly free the Mdl using the io subsytem. */ if (irp->MdlAddress != NULL) { IoFreeMdl(irp->MdlAddress); irp->MdlAddress = NULL; } IoCompleteRequest( irp, IO_DISK_INCREMENT ); } } /* while there's packets to process */ } while ( TRUE ); }