Author: janderwald
Date: Sat May 14 18:09:00 2011
New Revision: 51739
URL:
http://svn.reactos.org/svn/reactos?rev=51739&view=rev
Log:
[USBSTOR]
- Start implementing queued srb handling
- Implement SRB_FUNCTION_RELEASE_QUEUE, SRB_FUNCTION_FLUSH, SRB_FUNCTION_FLUSH_QUEUE
- WIP, not yet working perfectly
Added:
branches/usb-bringup/drivers/usb/usbstor/queue.c (with props)
Modified:
branches/usb-bringup/drivers/usb/usbstor/CMakeLists.txt
branches/usb-bringup/drivers/usb/usbstor/disk.c
branches/usb-bringup/drivers/usb/usbstor/fdo.c
branches/usb-bringup/drivers/usb/usbstor/scsi.c
branches/usb-bringup/drivers/usb/usbstor/usbstor.c
branches/usb-bringup/drivers/usb/usbstor/usbstor.h
Modified: branches/usb-bringup/drivers/usb/usbstor/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/CMakeLists.txt [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/CMakeLists.txt [iso-8859-1] Sat May 14
18:09:00 2011
@@ -3,7 +3,7 @@
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)
Modified: branches/usb-bringup/drivers/usb/usbstor/disk.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] Sat May 14 18:09:00 2011
@@ -12,87 +12,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,
IN PIRP Irp)
@@ -128,7 +47,58 @@
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 @@
}
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:
- {
- 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;
+ case SRB_FUNCTION_FLUSH_QUEUE:
+ {
+ 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:
Modified: branches/usb-bringup/drivers/usb/usbstor/fdo.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/fdo.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/fdo.c [iso-8859-1] Sat May 14 18:09:00 2011
@@ -142,6 +142,11 @@
}
//
+ // intialize irp queue
+ //
+ USBSTOR_QueueInitialize(DeviceExtension);
+
+ //
// first get device & configuration & string descriptor
//
Status = USBSTOR_GetDescriptors(DeviceObject);
Added: branches/usb-bringup/drivers/usb/usbstor/queue.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/queue.c (added)
+++ branches/usb-bringup/drivers/usb/usbstor/queue.c [iso-8859-1] Sat May 14 18:09:00
2011
@@ -1,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(a)reactos.org)
+ * Johannes Anderwald (johannes.anderwald(a)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);
+
+}
Propchange: branches/usb-bringup/drivers/usb/usbstor/queue.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/usb-bringup/drivers/usb/usbstor/scsi.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/scsi.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/scsi.c [iso-8859-1] Sat May 14 18:09:00 2011
@@ -1002,3 +1002,94 @@
//
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;
+}
Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/usbstor.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/usbstor.c [iso-8859-1] Sat May 14 18:09:00
2011
@@ -99,18 +99,6 @@
//
}
-VOID
-NTAPI
-USBSTOR_StartIo(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- //
- // implement me
- //
- UNIMPLEMENTED
-}
-
NTSTATUS
NTAPI
USBSTOR_DispatchClose(
@@ -251,10 +239,9 @@
DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
//
- // FIXME: driver start i/o routine
- //
- //DriverObject->DriverStartIo = USBSTOR_StartIo;
-
+ // driver start i/o routine
+ //
+ DriverObject->DriverStartIo = USBSTOR_StartIo;
//
// create / close
Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] Sat May 14 18:09:00
2011
@@ -63,6 +63,9 @@
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
@@ -75,6 +78,9 @@
ULONG BlockLength;
// length of block
ULONG LastLogicBlockAddress;
// last block address
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+
+
//
// max lun command identifier
@@ -361,41 +367,53 @@
// scsi.c routines
//
NTSTATUS
-USBSTOR_SendInquiryCmd(
+USBSTOR_HandleExecuteSCSI(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+//---------------------------------------------------------------------
+//
+// disk.c routines
+//
+NTSTATUS
+USBSTOR_HandleInternalDeviceControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS
+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);
-NTSTATUS
-USBSTOR_SendCapacityCmd(
+VOID
+USBSTOR_QueueRelease(
+ IN PDEVICE_OBJECT DeviceObject);
+
+BOOLEAN
+USBSTOR_QueueAddIrp(
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(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-//---------------------------------------------------------------------
-//
-// disk.c routines
-//
-NTSTATUS
-USBSTOR_HandleInternalDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-NTSTATUS
-USBSTOR_HandleDeviceControl(
- 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);