From be12088a55a58dfd0fccd26383b44a26cf65c034 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 14 May 2011 18:09:00 +0000 Subject: [PATCH] [USBSTOR] - Start implementing queued srb handling - Implement SRB_FUNCTION_RELEASE_QUEUE, SRB_FUNCTION_FLUSH, SRB_FUNCTION_FLUSH_QUEUE - WIP, not yet working perfectly svn path=/branches/usb-bringup/; revision=51739 --- drivers/usb/usbstor/CMakeLists.txt | 2 +- drivers/usb/usbstor/disk.c | 171 ++++----- drivers/usb/usbstor/fdo.c | 5 + drivers/usb/usbstor/queue.c | 561 +++++++++++++++++++++++++++++ drivers/usb/usbstor/scsi.c | 91 +++++ drivers/usb/usbstor/usbstor.c | 17 +- drivers/usb/usbstor/usbstor.h | 58 ++- 7 files changed, 777 insertions(+), 128 deletions(-) create mode 100644 drivers/usb/usbstor/queue.c diff --git a/drivers/usb/usbstor/CMakeLists.txt b/drivers/usb/usbstor/CMakeLists.txt index a6e039506e6..7eea2d0c369 100644 --- a/drivers/usb/usbstor/CMakeLists.txt +++ b/drivers/usb/usbstor/CMakeLists.txt @@ -3,7 +3,7 @@ add_definitions(-DDEBUG_MODE) include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include) -add_library(usbstor SHARED descriptor.c disk.c fdo.c misc.c pdo.c scsi.c usbstor.c usbstor.rc) +add_library(usbstor SHARED descriptor.c disk.c fdo.c misc.c pdo.c queue.c scsi.c usbstor.c usbstor.rc) set_module_type(usbstor kernelmodedriver) add_importlibs(usbstor ntoskrnl hal usbd) diff --git a/drivers/usb/usbstor/disk.c b/drivers/usb/usbstor/disk.c index 099c0e1780a..96152c3afce 100644 --- a/drivers/usb/usbstor/disk.c +++ b/drivers/usb/usbstor/disk.c @@ -11,87 +11,6 @@ #include "usbstor.h" -NTSTATUS -USBSTOR_HandleExecuteSCSI( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN OUT PSCSI_REQUEST_BLOCK Request, - IN PPDO_DEVICE_EXTENSION PDODeviceExtension) -{ - PCDB pCDB; - NTSTATUS Status; - - // - // get SCSI command data block - // - pCDB = (PCDB)Request->Cdb; - - DPRINT1("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]); - - - if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY) - { - // - // sanity checks - // - ASSERT(Request->DataBuffer); - - DPRINT1("SCSIOP_READ_CAPACITY Length %\n", Request->DataTransferLength); - Status = USBSTOR_SendCapacityCmd(DeviceObject, Irp); - } - else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE) - { - DPRINT1("SCSIOP_MODE_SENSE DataTransferLength %lu\n", Request->DataTransferLength); - ASSERT(pCDB->MODE_SENSE.AllocationLength == Request->DataTransferLength); - ASSERT(Request->DataBuffer); - - // - // send mode sense command - // - Status = USBSTOR_SendModeSenseCmd(DeviceObject, Irp); - } - else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ /*|| pCDB->MODE_SENSE.OperationCode == SCSIOP_WRITE*/) - { - DPRINT1("SCSIOP_READ / SCSIOP_WRITE DataTransferLength %lu\n", Request->DataTransferLength); - - // - // send read / write command - // - Status = USBSTOR_SendReadWriteCmd(DeviceObject, Irp); - } - else if (pCDB->AsByte[0] == SCSIOP_MEDIUM_REMOVAL) - { - DPRINT1("SCSIOP_MEDIUM_REMOVAL\n"); - - // - // just complete the request - // - Request->SrbStatus = SRB_STATUS_SUCCESS; - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = Request->DataTransferLength; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_TEST_UNIT_READY) - { - DPRINT1("SCSIOP_TEST_UNIT_READY\n"); - - // - // send test unit command - // - Status = USBSTOR_SendTestUnitCmd(DeviceObject, Irp); - } - else - { - UNIMPLEMENTED; - Request->SrbStatus = SRB_STATUS_ERROR; - Status = STATUS_NOT_SUPPORTED; - DbgBreakPoint(); - } - - return Status; -} - NTSTATUS USBSTOR_HandleInternalDeviceControl( IN PDEVICE_OBJECT DeviceObject, @@ -128,7 +47,58 @@ USBSTOR_HandleInternalDeviceControl( case SRB_FUNCTION_EXECUTE_SCSI: { DPRINT1("SRB_FUNCTION_EXECUTE_SCSI\n"); - return USBSTOR_HandleExecuteSCSI(DeviceObject, Irp, Request, PDODeviceExtension); + + // + // check if request is valid + // + if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) + { + // + // data is transferred with this irp + // + if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) || + Request->DataTransferLength == 0 || + Irp->MdlAddress == NULL) + { + // + // invalid parameter + // + Status = STATUS_INVALID_PARAMETER; + break; + } + } + else + { + // + // sense buffer request + // + if (Request->DataTransferLength || + Request->DataBuffer || + Irp->MdlAddress) + { + // + // invalid parameter + // + Status = STATUS_INVALID_PARAMETER; + break; + } + } + + // + // add the request + // + if (!USBSTOR_QueueAddIrp(DeviceObject, Irp)) + { + // + // irp was not added to the queue + // + IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo); + } + + // + // irp pending + // + return STATUS_PENDING; } case SRB_FUNCTION_RELEASE_DEVICE: { @@ -179,20 +149,37 @@ USBSTOR_HandleInternalDeviceControl( } case SRB_FUNCTION_RELEASE_QUEUE: { - DPRINT1("SRB_FUNCTION_RELEASE_QUEUE UNIMPLEMENTED\n"); - Status = STATUS_NOT_IMPLEMENTED; + DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n"); + + // + // release queue + // + USBSTOR_QueueRelease(DeviceObject); + + + // + // set status success + // + Request->SrbStatus = SRB_STATUS_SUCCESS; + Status = STATUS_SUCCESS; break; } + case SRB_FUNCTION_FLUSH: + case SRB_FUNCTION_FLUSH_QUEUE: { - DPRINT1("SRB_FUNCTION_FLUSH UNIMPLEMENTED\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case SRB_FUNCTION_SET_LINK_TIMEOUT: - { - DPRINT1("SRB_FUNCTION_FLUSH UNIMPLEMENTED\n"); - Status = STATUS_NOT_IMPLEMENTED; + DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE\n"); + + // + // flush all requests + // + USBSTOR_QueueFlushIrps(DeviceObject); + + // + // set status success + // + Request->SrbStatus = SRB_STATUS_SUCCESS; + Status = STATUS_SUCCESS; break; } default: diff --git a/drivers/usb/usbstor/fdo.c b/drivers/usb/usbstor/fdo.c index 017e1ea3ff2..8251ec54c66 100644 --- a/drivers/usb/usbstor/fdo.c +++ b/drivers/usb/usbstor/fdo.c @@ -141,6 +141,11 @@ USBSTOR_FdoHandleStartDevice( return Status; } + // + // intialize irp queue + // + USBSTOR_QueueInitialize(DeviceExtension); + // // first get device & configuration & string descriptor // diff --git a/drivers/usb/usbstor/queue.c b/drivers/usb/usbstor/queue.c new file mode 100644 index 00000000000..c726c7052a8 --- /dev/null +++ b/drivers/usb/usbstor/queue.c @@ -0,0 +1,561 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/queue.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin@reactos.org) + * Johannes Anderwald (johannes.anderwald@reactos.org) + */ + +#include "usbstor.h" + +VOID +USBSTOR_QueueInitialize( + PFDO_DEVICE_EXTENSION FDODeviceExtension) +{ + + // + // initialize queue lock + // + KeInitializeSpinLock(&FDODeviceExtension->IrpListLock); + + // + // initialize irp list head + // + InitializeListHead(&FDODeviceExtension->IrpListHead); +} + + +VOID +NTAPI +USBSTOR_CancelIo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire irp list lock + // + KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock); + + // + // now release the cancel lock + // + IoReleaseCancelSpinLock(Irp->CancelIrql); + + // + // remove the irp from the list + // + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + + // + // release irp list lock + // + KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock); + + // + // set cancel status + // + Irp->IoStatus.Status = STATUS_CANCELLED; + + // + // now cancel the irp + // + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + + +BOOLEAN +USBSTOR_QueueAddIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PDRIVER_CANCEL OldDriverCancel; + KIRQL OldLevel; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + BOOLEAN IrpListFreeze; + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // mark irp pending + // + IoMarkIrpPending(Irp); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // add irp to queue + // + InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry); + + // + // now set the driver cancel routine + // + OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo); + + // + // check if the irp has already been cancelled + // + if (Irp->Cancel && OldDriverCancel == NULL) + { + // + // the irp has already been cancelled + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // cancel routine requires that cancel spinlock is held + // + IoAcquireCancelSpinLock(&Irp->CancelIrql); + + // + // cancel irp + // + USBSTOR_CancelIo(DeviceObject, Irp); + + // + // irp was cancelled + // + return FALSE; + } + + // + // check if queue is freezed + // + IrpListFreeze = FDODeviceExtension->IrpListFreeze; + + // + // release list lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // if list is freezed, dont start this packet + // + return IrpListFreeze; +} + +PIRP +USBSTOR_RemoveIrp( + IN PDEVICE_OBJECT DeviceObject) +{ + KIRQL OldLevel; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PLIST_ENTRY Entry; + PIRP Irp = NULL; + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // check if list is empty + // + if (!IsListEmpty(&FDODeviceExtension->IrpListHead)) + { + // + // remove entry + // + Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead); + + // + // get offset to start of irp + // + Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); + } + + // + // release list lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // return result + // + return Irp; +} + +VOID +USBSTOR_QueueFlushIrps( + IN PDEVICE_OBJECT DeviceObject) +{ + KIRQL OldLevel; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PLIST_ENTRY Entry; + PIRP Irp; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // complete all irps with status cancelled + // + while(!IsListEmpty(&FDODeviceExtension->IrpListHead)) + { + // + // remove irp + // + Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead); + + // + // get start of irp structure + // + Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get request block + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // sanity check + // + ASSERT(Request); + + // + // set srb status to flushed + // + Request->SrbStatus = SRB_STATUS_REQUEST_FLUSHED; + + // + // set unsuccessful status + // + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + + // + // complete request + // + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); +} + +VOID +USBSTOR_QueueNextRequest( + IN PDEVICE_OBJECT DeviceObject) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PIRP Irp; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // remove first irp from list + // + Irp = USBSTOR_RemoveIrp(DeviceObject); + + // + // is there an irp pending + // + if (!Irp) + { + // + // no work to do + // + return; + } + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get srb + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // start next packet + // + IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo); +} + +VOID +USBSTOR_QueueRelease( + IN PDEVICE_OBJECT DeviceObject) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PIRP Irp; + KIRQL OldLevel; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // clear freezed status + // + FDODeviceExtension->IrpListFreeze = FALSE; + + // + // release irp list lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // grab newest irp + // + Irp = USBSTOR_RemoveIrp(DeviceObject); + + // + // is there an irp + // + if (!Irp) + { + // + // no irp + // + return; + } + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get srb + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // start new packet + // + IoStartPacket(PDODeviceExtension->LowerDeviceObject, // FDO + Irp, + &Request->QueueSortKey, + USBSTOR_CancelIo); +} + + +VOID +NTAPI +USBSTOR_StartIo( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + KIRQL OldLevel; + NTSTATUS Status; + + DPRINT1("USBSTOR_StartIo\n"); + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire cancel spinlock + // + IoAcquireCancelSpinLock(&OldLevel); + + // + // set cancel routine to zero + // + IoSetCancelRoutine(Irp, NULL); + + // + // check if the irp has been cancelled + // + if (Irp->Cancel) + { + // + // irp has been cancelled, release cancel spinlock + // + IoReleaseCancelSpinLock(OldLevel); + + // + // irp is cancelled + // + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + // + // complete request + // + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // + // check if the queue has been frozen + // + if (FDODeviceExtension->IrpListFreeze == FALSE) + { + // + // queue next request + // + USBSTOR_QueueNextRequest(DeviceObject); + + // + // start next request + // + IoStartNextPacket(DeviceObject, TRUE); + } + + // + // done + // + return; + } + + // + // release cancel spinlock + // + IoReleaseCancelSpinLock(OldLevel); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // remove irp from list + // + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // execute scsi + // + Status = USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp); + + // + // FIXME: synchronize action with error handling + // + USBSTOR_QueueNextRequest(IoStack->DeviceObject); + + // + // start next request + // + IoStartNextPacket(DeviceObject, TRUE); + +} diff --git a/drivers/usb/usbstor/scsi.c b/drivers/usb/usbstor/scsi.c index cb39572b62d..0e2b9262320 100644 --- a/drivers/usb/usbstor/scsi.c +++ b/drivers/usb/usbstor/scsi.c @@ -1002,3 +1002,94 @@ USBSTOR_SendTestUnitCmd( // return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_TEST_UNIT_CMD_LEN, (PUCHAR)&Cmd, 0, NULL); } + + +NTSTATUS +USBSTOR_HandleExecuteSCSI( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PCDB pCDB; + NTSTATUS Status; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get request block + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // get SCSI command data block + // + pCDB = (PCDB)Request->Cdb; + + DPRINT1("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]); + + if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY) + { + // + // sanity checks + // + ASSERT(Request->DataBuffer); + + DPRINT1("SCSIOP_READ_CAPACITY Length %\n", Request->DataTransferLength); + Status = USBSTOR_SendCapacityCmd(DeviceObject, Irp); + } + else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE) + { + DPRINT1("SCSIOP_MODE_SENSE DataTransferLength %lu\n", Request->DataTransferLength); + ASSERT(pCDB->MODE_SENSE.AllocationLength == Request->DataTransferLength); + ASSERT(Request->DataBuffer); + + // + // send mode sense command + // + Status = USBSTOR_SendModeSenseCmd(DeviceObject, Irp); + } + else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ /*|| pCDB->MODE_SENSE.OperationCode == SCSIOP_WRITE*/) + { + DPRINT1("SCSIOP_READ / SCSIOP_WRITE DataTransferLength %lu\n", Request->DataTransferLength); + + // + // send read / write command + // + Status = USBSTOR_SendReadWriteCmd(DeviceObject, Irp); + } + else if (pCDB->AsByte[0] == SCSIOP_MEDIUM_REMOVAL) + { + DPRINT1("SCSIOP_MEDIUM_REMOVAL\n"); + + // + // just complete the request + // + Request->SrbStatus = SRB_STATUS_SUCCESS; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = Request->DataTransferLength; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_TEST_UNIT_READY) + { + DPRINT1("SCSIOP_TEST_UNIT_READY\n"); + + // + // send test unit command + // + Status = USBSTOR_SendTestUnitCmd(DeviceObject, Irp); + } + else + { + UNIMPLEMENTED; + Request->SrbStatus = SRB_STATUS_ERROR; + Status = STATUS_NOT_SUPPORTED; + DbgBreakPoint(); + } + + return Status; +} diff --git a/drivers/usb/usbstor/usbstor.c b/drivers/usb/usbstor/usbstor.c index 12b2c0a3e39..dc2d6e7bdd3 100644 --- a/drivers/usb/usbstor/usbstor.c +++ b/drivers/usb/usbstor/usbstor.c @@ -99,18 +99,6 @@ USBSTOR_Unload( // } -VOID -NTAPI -USBSTOR_StartIo( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - // - // implement me - // - UNIMPLEMENTED -} - NTSTATUS NTAPI USBSTOR_DispatchClose( @@ -251,10 +239,9 @@ DriverEntry( DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice; // - // FIXME: driver start i/o routine + // driver start i/o routine // - //DriverObject->DriverStartIo = USBSTOR_StartIo; - + DriverObject->DriverStartIo = USBSTOR_StartIo; // // create / close diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h index e8374692b47..a1938625b20 100644 --- a/drivers/usb/usbstor/usbstor.h +++ b/drivers/usb/usbstor/usbstor.h @@ -63,6 +63,9 @@ typedef struct UCHAR BulkOutPipeIndex; // bulk out pipe index UCHAR MaxLUN; // max lun for device PDEVICE_OBJECT ChildPDO[16]; // max 16 child pdo devices + KSPIN_LOCK IrpListLock; // irp list lock + LIST_ENTRY IrpListHead; // irp list head + BOOLEAN IrpListFreeze; // if true the irp list is freezed }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; typedef struct @@ -76,6 +79,9 @@ typedef struct ULONG LastLogicBlockAddress; // last block address }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; + + + // // max lun command identifier // @@ -361,26 +367,7 @@ USBSTOR_GetPipeHandles( // scsi.c routines // NTSTATUS -USBSTOR_SendInquiryCmd( - IN PDEVICE_OBJECT DeviceObject); - -NTSTATUS -USBSTOR_SendCapacityCmd( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -USBSTOR_SendModeSenseCmd( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -USBSTOR_SendReadWriteCmd( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -USBSTOR_SendTestUnitCmd( +USBSTOR_HandleExecuteSCSI( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); @@ -398,4 +385,35 @@ USBSTOR_HandleDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +//--------------------------------------------------------------------- +// +// queue.c routines +// +VOID +NTAPI +USBSTOR_StartIo( + PDEVICE_OBJECT DeviceObject, + PIRP Irp); +VOID +USBSTOR_QueueFlushIrps( + IN PDEVICE_OBJECT DeviceObject); + +VOID +USBSTOR_QueueRelease( + IN PDEVICE_OBJECT DeviceObject); + +BOOLEAN +USBSTOR_QueueAddIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +VOID +NTAPI +USBSTOR_CancelIo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +VOID +USBSTOR_QueueInitialize( + PFDO_DEVICE_EXTENSION FDODeviceExtension);