#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,
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:
{
}
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:
--- /dev/null
+/*
+ * 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);
+
+}
//
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;
+}
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
ULONG LastLogicBlockAddress; // last block address
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+
+
//
// max lun command identifier
//
// scsi.c routines
//
NTSTATUS
-USBSTOR_SendInquiryCmd(
- IN PDEVICE_OBJECT DeviceObject);
-
-NTSTATUS
-USBSTOR_SendCapacityCmd(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-NTSTATUS
-USBSTOR_SendModeSenseCmd(
+USBSTOR_HandleExecuteSCSI(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
+//---------------------------------------------------------------------
+//
+// disk.c routines
+//
NTSTATUS
-USBSTOR_SendReadWriteCmd(
+USBSTOR_HandleInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
-USBSTOR_SendTestUnitCmd(
+USBSTOR_HandleDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
//---------------------------------------------------------------------
//
-// disk.c routines
+// queue.c routines
//
-NTSTATUS
-USBSTOR_HandleInternalDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+VOID
+NTAPI
+USBSTOR_StartIo(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
-NTSTATUS
-USBSTOR_HandleDeviceControl(
+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);