[USBSTOR]

- Queue inquriry & format capacity command with an irp

svn path=/trunk/; revision=55695
This commit is contained in:
Johannes Anderwald 2012-02-19 02:47:35 +00:00
parent fa51806949
commit 53bd8f1e21
4 changed files with 472 additions and 290 deletions

View file

@ -115,6 +115,14 @@ USBSTOR_HandleTransferError(
PSCSI_REQUEST_BLOCK Request;
PCDB pCDB;
//
// sanity checks
//
ASSERT(Context);
ASSERT(Context->PDODeviceExtension);
ASSERT(Context->PDODeviceExtension->Self);
ASSERT(Context->Irp);
//
// first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
//
@ -134,91 +142,51 @@ USBSTOR_HandleTransferError(
}
}
if (Context->Irp)
//
// get next stack location
//
Stack = IoGetCurrentIrpStackLocation(Context->Irp);
//
// get request block
//
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
ASSERT(Request);
//
// obtain request type
//
pCDB = (PCDB)Request->Cdb;
ASSERT(pCDB);
if (Status != STATUS_SUCCESS)
{
//
// get next stack location
// Complete the master IRP
//
Stack = IoGetCurrentIrpStackLocation(Context->Irp);
Context->Irp->IoStatus.Status = Status;
Context->Irp->IoStatus.Information = 0;
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
//
// get request block
// Start the next request
//
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
ASSERT(Request);
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
//
// obtain request type
// srb handling finished
//
pCDB = (PCDB)Request->Cdb;
ASSERT(pCDB);
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
//
// Cleanup the IRP context
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
{
FreeItem(Context->TransferData);
}
if (Status != STATUS_SUCCESS)
{
//
// Complete the master IRP
//
Context->Irp->IoStatus.Status = Status;
Context->Irp->IoStatus.Information = 0;
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
//
// Start the next request
//
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
//
// srb handling finished
//
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
//
// clear timer srb
//
Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
}
// clear timer srb
//
Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
}
else
{
if (Status != STATUS_SUCCESS)
{
//
// Signal the context event
//
ASSERT(Context->Event);
KeSetEvent(Context->Event, 0, FALSE);
//
// srb handling finished
//
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
//
// clear timer srb
//
Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
}
}
if (NT_SUCCESS(Status))
{
//
// FIXME: inquiry cmd / read format capacity are send w/o irp
//
ASSERT(Context);
ASSERT(Context->PDODeviceExtension);
ASSERT(Context->PDODeviceExtension->Self);
ASSERT(Context->Irp);
DPRINT1("Retrying Count %x %p\n", Context->RetryCount, Context->PDODeviceExtension->Self);
DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self);
//
// re-schedule request

View file

@ -956,6 +956,299 @@ USBSTOR_PdoHandlePnp(
return Status;
}
NTSTATUS
NTAPI
USBSTOR_CompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Ctx)
{
PKEVENT Event = (PKEVENT)Ctx;
//
// signal event
//
KeSetEvent(Event, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
USBSTOR_AllocateIrp(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG DataTransferLength,
IN UCHAR OpCode,
IN PKEVENT Event,
OUT PSCSI_REQUEST_BLOCK *OutRequest,
OUT PIRP *OutIrp)
{
PIRP Irp;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
PCDB pCDB;
//
// allocate irp
//
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// get next stack location
//
IoStack = IoGetNextIrpStackLocation(Irp);
//
// create scsi block
//
Request = (PSCSI_REQUEST_BLOCK)ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK));
if (!Request)
{
//
// no memory
//
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// init request
//
RtlZeroMemory(Request, sizeof(SCSI_REQUEST_BLOCK));
//
// allocate data transfer block
//
Request->DataBuffer = ExAllocatePool(NonPagedPool, DataTransferLength);
if (!Request)
{
//
// no memory
//
IoFreeIrp(Irp);
ExFreePool(Request);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// allocate MDL
//
Irp->MdlAddress = IoAllocateMdl(Request->DataBuffer, DataTransferLength, FALSE, FALSE, NULL);
if (!Irp->MdlAddress)
{
//
// no memory
//
IoFreeIrp(Irp);
ExFreePool(Request);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// non paged pool
//
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
//
// init scsi block
//
Request->DataTransferLength = DataTransferLength;
Request->Function = SRB_FUNCTION_EXECUTE_SCSI;
Request->SrbFlags = SRB_FLAGS_DATA_IN;
RtlZeroMemory(Request->DataBuffer, DataTransferLength);
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
//
// set op code
//
pCDB->AsByte[0] = OpCode;
//
// store result
//
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.Others.Argument1 = Request;
IoStack->DeviceObject = DeviceObject;
//
// init event
//
KeInitializeEvent(Event, NotificationEvent, FALSE);
//
// lets setup a completion routine
//
IoSetCompletionRoutine(Irp, USBSTOR_CompletionRoutine, (PVOID)Event, TRUE, TRUE, TRUE);
//
// output result
//
*OutIrp = Irp;
*OutRequest = Request;
return STATUS_SUCCESS;
}
NTSTATUS
USBSTOR_SendIrp(
IN PDEVICE_OBJECT PDODeviceObject,
IN ULONG DataTransferLength,
IN UCHAR OpCode,
OUT PVOID *OutData)
{
NTSTATUS Status;
PIRP Irp;
KEVENT Event;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PSCSI_REQUEST_BLOCK Request;
//
// let's allocate an irp
//
Status = USBSTOR_AllocateIrp(PDODeviceObject, sizeof(UFI_INQUIRY_RESPONSE), SCSIOP_INQUIRY, &Event, &Request, &Irp);
if (!NT_SUCCESS(Status))
{
//
// failed
//
DPRINT1("[USBSTOR] Failed to build irp\n");
return Status;
}
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
//
// send irp
//
ASSERT(Irp);
ASSERT(PDODeviceExtension->LowerDeviceObject);
Status = IoCallDriver(PDODeviceExtension->Self, Irp);
if (Status == STATUS_PENDING)
{
//
// wait for completion
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = Irp->IoStatus.Status;
}
if (NT_SUCCESS(Status))
{
//
// store result
//
*OutData = Request->DataBuffer;
}
//
// free resources
//
ExFreePool(Request);
IoFreeIrp(Irp);
return Status;
}
NTSTATUS
USBSTOR_SendInquiryIrp(
IN PDEVICE_OBJECT PDODeviceObject)
{
NTSTATUS Status;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUFI_INQUIRY_RESPONSE Response;
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
//
// send request
//
Status = USBSTOR_SendIrp(PDODeviceObject, sizeof(UFI_INQUIRY_RESPONSE), SCSIOP_INQUIRY, (PVOID*)&Response);
if (!NT_SUCCESS(Status))
{
//
// command failed
//
DPRINT1("USBSTOR_SendInquiryIrp Failed with %x\n", Status);
return Status;
}
DPRINT1("Response %p\n", Response);
DPRINT1("DeviceType %x\n", Response->DeviceType);
DPRINT1("RMB %x\n", Response->RMB);
DPRINT1("Version %x\n", Response->Version);
DPRINT1("Format %x\n", Response->Format);
DPRINT1("Length %x\n", Response->Length);
DPRINT1("Reserved %x\n", Response->Reserved);
DPRINT1("Vendor %c%c%c%c%c%c%c%c\n", Response->Vendor[0], Response->Vendor[1], Response->Vendor[2], Response->Vendor[3], Response->Vendor[4], Response->Vendor[5], Response->Vendor[6], Response->Vendor[7]);
DPRINT1("Product %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", Response->Product[0], Response->Product[1], Response->Product[2], Response->Product[3],
Response->Product[4], Response->Product[5], Response->Product[6], Response->Product[7],
Response->Product[8], Response->Product[9], Response->Product[10], Response->Product[11],
Response->Product[12], Response->Product[13], Response->Product[14], Response->Product[15]);
DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], Response->Revision[1], Response->Revision[2], Response->Revision[3]);
//
// store result
//
PDODeviceExtension->InquiryData = (PVOID)Response;
return Status;
}
NTSTATUS
USBSTOR_SendFormatCapacityIrp(
IN PDEVICE_OBJECT PDODeviceObject)
{
NTSTATUS Status;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUCHAR Response;
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
//
// send request
//
Status = USBSTOR_SendIrp(PDODeviceObject, 0xFC, SCSIOP_READ_FORMATTED_CAPACITY, (PVOID*)&Response);
if (!NT_SUCCESS(Status))
{
//
// command failed
//
return Status;
}
//
// check if its a floppy
//
PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(Response, 0xFC /*FIXME*/, &PDODeviceExtension->MediumTypeCode);
//
// free response
//
ExFreePool(Response);
return Status;
}
NTSTATUS
USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject,
@ -1013,9 +1306,10 @@ USBSTOR_CreatePDO(
*ChildDeviceObject = PDO;
//
// FIXME: send inquiry command by irp
// send inquiry command by irp
//
USBSTOR_SendInquiryCmd(PDO, 0);
Status = USBSTOR_SendInquiryIrp(PDO);
ASSERT(Status == STATUS_SUCCESS);
//
// check response data
@ -1028,15 +1322,12 @@ USBSTOR_CreatePDO(
//
// check if it is a floppy
//
Status = USBSTOR_SendFormatCapacity(PDO, 0);
if (NT_SUCCESS(Status))
{
//
// check if its a floppy
//
PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(PDODeviceExtension->FormatData, PAGE_SIZE /*FIXME*/, &PDODeviceExtension->MediumTypeCode);
DPRINT1("[USBSTOR] IsFloppy %x MediumTypeCode %x\n", PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode);
}
Status = USBSTOR_SendFormatCapacityIrp(PDO);
//
// display result
//
DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode);
//
// failing command is non critical
@ -1044,7 +1335,6 @@ USBSTOR_CreatePDO(
Status = STATUS_SUCCESS;
}
//
// done
//

View file

@ -262,79 +262,75 @@ USBSTOR_CSWCompletionRoutine(
}
if (Context->Irp)
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Context->Irp);
//
// get request block
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
ASSERT(Request);
Status = Irp->IoStatus.Status;
Urb = &Context->Urb;
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
Request->SrbStatus = SRB_STATUS_SUCCESS;
//
// read capacity needs special work
//
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
{
//
// get current stack location
// get output buffer
//
IoStack = IoGetCurrentIrpStackLocation(Context->Irp);
Response = (PUFI_CAPACITY_RESPONSE)Context->TransferData;
//
// get request block
// store in pdo
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
ASSERT(Request);
Context->PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
Context->PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
Status = Irp->IoStatus.Status;
Urb = &Context->Urb;
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
Request->SrbStatus = SRB_STATUS_SUCCESS;
//
// read capacity needs special work
//
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
if (Request->DataTransferLength == sizeof(READ_CAPACITY_DATA_EX))
{
//
// get output buffer
// get input buffer
//
Response = (PUFI_CAPACITY_RESPONSE)Context->TransferData;
CapacityDataEx = (PREAD_CAPACITY_DATA_EX)Request->DataBuffer;
//
// store in pdo
// set result
//
Context->PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
Context->PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
if (Request->DataTransferLength == sizeof(READ_CAPACITY_DATA_EX))
{
//
// get input buffer
//
CapacityDataEx = (PREAD_CAPACITY_DATA_EX)Request->DataBuffer;
//
// set result
//
CapacityDataEx->BytesPerBlock = Response->BlockLength;
CapacityDataEx->LogicalBlockAddress.QuadPart = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA_EX);
}
else
{
//
// get input buffer
//
CapacityData = (PREAD_CAPACITY_DATA)Request->DataBuffer;
//
// set result
//
CapacityData->BytesPerBlock = Response->BlockLength;
CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA);
}
CapacityDataEx->BytesPerBlock = Response->BlockLength;
CapacityDataEx->LogicalBlockAddress.QuadPart = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA_EX);
}
else
{
//
// get input buffer
//
CapacityData = (PREAD_CAPACITY_DATA)Request->DataBuffer;
//
// free response
// set result
//
FreeItem(Context->TransferData);
}
CapacityData->BytesPerBlock = Response->BlockLength;
CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA);
}
//
// free response
//
FreeItem(Context->TransferData);
}
//
@ -342,37 +338,26 @@ USBSTOR_CSWCompletionRoutine(
//
FreeItem(Context->cbw);
if (Context->Irp)
{
//
// FIXME: check status
//
Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
Context->Irp->IoStatus.Information = Context->TransferDataLength;
//
// FIXME: check status
//
Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
Context->Irp->IoStatus.Information = Context->TransferDataLength;
//
// terminate current request
//
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
//
// terminate current request
//
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
//
// complete request
//
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
//
// complete request
//
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
//
// start next request
//
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
}
if (Context->Event)
{
//
// signal event
//
KeSetEvent(Context->Event, 0, FALSE);
}
//
// start next request
//
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
//
// free our allocated irp
@ -639,7 +624,6 @@ NTSTATUS
USBSTOR_SendRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP OriginalRequest,
IN OPTIONAL PKEVENT Event,
IN UCHAR CommandLength,
IN PUCHAR Command,
IN ULONG TransferDataLength,
@ -707,7 +691,6 @@ USBSTOR_SendRequest(
Context->TransferDataLength = TransferDataLength;
Context->FDODeviceExtension = FDODeviceExtension;
Context->PDODeviceExtension = PDODeviceExtension;
Context->Event = Event;
Context->RetryCount = RetryCount;
//
@ -836,90 +819,64 @@ USBSTOR_SendRequest(
NTSTATUS
USBSTOR_SendFormatCapacity(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
UFI_READ_FORMAT_CAPACITY Cmd;
NTSTATUS Status;
KEVENT Event;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUCHAR Response;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
//
// allocate inquiry response
// get current stack location
//
Response = AllocateItem(NonPagedPool, PAGE_SIZE);
if (!Response)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get PDO device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// get request block
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// initialize inquiry cmd
//
RtlZeroMemory(&Cmd, sizeof(UFI_READ_FORMAT_CAPACITY));
Cmd.Code = SCSIOP_READ_FORMATTED_CAPACITY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN) << 5;
Cmd.AllocationLengthLsb = 0xFC; // FIXME: compute some same value
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Cmd.AllocationLengthMsb = HTONS(Request->DataTransferLength & 0xFFFF) >> 8;
Cmd.AllocationLengthLsb = HTONS(Request->DataTransferLength & 0xFFFF) & 0xFF;
//
// now send the request
//
Status = USBSTOR_SendRequest(DeviceObject, NULL, &Event, UFI_READ_FORMAT_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_INQUIRY_RESPONSE), (PUCHAR)Response, RetryCount);
//
// wait for the action to complete
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
//
// store inquiry data
//
PDODeviceExtension->FormatData = Response;
//
// done
//
return Status;
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_FORMAT_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_SendInquiryCmd(
USBSTOR_SendInquiry(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
UFI_INQUIRY_CMD Cmd;
NTSTATUS Status;
KEVENT Event;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUFI_INQUIRY_RESPONSE Response;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
//
// allocate inquiry response
// get current stack location
//
Response = AllocateItem(NonPagedPool, PAGE_SIZE);
if (!Response)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get request block
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// get PDO device extension
@ -935,48 +892,18 @@ USBSTOR_SendInquiryCmd(
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
//
// initialize event
// sanity check
//
KeInitializeEvent(&Event, NotificationEvent, FALSE);
ASSERT(Request->DataTransferLength >= sizeof(UFI_INQUIRY_RESPONSE));
//
// now send the request
//
Status = USBSTOR_SendRequest(DeviceObject, NULL, &Event, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_INQUIRY_RESPONSE), (PUCHAR)Response, RetryCount);
//
// wait for the action to complete
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
DPRINT1("Response %p\n", Response);
DPRINT1("DeviceType %x\n", Response->DeviceType);
DPRINT1("RMB %x\n", Response->RMB);
DPRINT1("Version %x\n", Response->Version);
DPRINT1("Format %x\n", Response->Format);
DPRINT1("Length %x\n", Response->Length);
DPRINT1("Reserved %x\n", Response->Reserved);
DPRINT1("Vendor %c%c%c%c%c%c%c%c\n", Response->Vendor[0], Response->Vendor[1], Response->Vendor[2], Response->Vendor[3], Response->Vendor[4], Response->Vendor[5], Response->Vendor[6], Response->Vendor[7]);
DPRINT1("Product %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", Response->Product[0], Response->Product[1], Response->Product[2], Response->Product[3],
Response->Product[4], Response->Product[5], Response->Product[6], Response->Product[7],
Response->Product[8], Response->Product[9], Response->Product[10], Response->Product[11],
Response->Product[12], Response->Product[13], Response->Product[14], Response->Product[15]);
DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], Response->Revision[1], Response->Revision[2], Response->Revision[3]);
//
// store inquiry data
//
PDODeviceExtension->InquiryData = (PVOID)Response;
//
// done
//
return Status;
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_SendCapacityCmd(
USBSTOR_SendCapacity(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
@ -984,20 +911,12 @@ USBSTOR_SendCapacityCmd(
UFI_CAPACITY_CMD Cmd;
PUFI_CAPACITY_RESPONSE Response;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
//
// get PDO device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
//
// allocate capacity response
//
@ -1020,11 +939,11 @@ USBSTOR_SendCapacityCmd(
//
// send request, response will be freed in completion routine
//
return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_READ_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), (PUCHAR)Response, RetryCount);
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), (PUCHAR)Response, RetryCount);
}
NTSTATUS
USBSTOR_SendModeSenseCmd(
USBSTOR_SendModeSense(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
@ -1213,7 +1132,7 @@ USBSTOR_SendModeSenseCmd(
}
NTSTATUS
USBSTOR_SendReadWriteCmd(
USBSTOR_SendReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
@ -1248,7 +1167,7 @@ USBSTOR_SendReadWriteCmd(
//
// informal debug print
//
DPRINT("USBSTOR_SendReadWriteCmd DataTransferLength %lu, BlockLength %lu\n", Request->DataTransferLength, PDODeviceExtension->BlockLength);
DPRINT("USBSTOR_SendReadWrite DataTransferLength %lu, BlockLength %lu\n", Request->DataTransferLength, PDODeviceExtension->BlockLength);
//
// sanity check
@ -1279,16 +1198,16 @@ USBSTOR_SendReadWriteCmd(
Temp = (Cmd.ContiguousLogicBlocksByte0 << 8 | Cmd.ContiguousLogicBlocksByte1);
ASSERT(NTOHL(Temp == BlockCount));
DPRINT("USBSTOR_SendReadWriteCmd BlockAddress %x%x%x%x BlockCount %lu BlockLength %lu\n", Cmd.LogicalBlockByte0, Cmd.LogicalBlockByte1, Cmd.LogicalBlockByte2, Cmd.LogicalBlockByte3, BlockCount, PDODeviceExtension->BlockLength);
DPRINT("USBSTOR_SendReadWrite BlockAddress %x%x%x%x BlockCount %lu BlockLength %lu\n", Cmd.LogicalBlockByte0, Cmd.LogicalBlockByte1, Cmd.LogicalBlockByte2, Cmd.LogicalBlockByte3, BlockCount, PDODeviceExtension->BlockLength);
//
// send request
//
return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_READ_WRITE_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_WRITE_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_SendTestUnitCmd(
USBSTOR_SendTestUnit(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN ULONG RetryCount)
@ -1328,7 +1247,7 @@ USBSTOR_SendTestUnitCmd(
//
// send the request
//
return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_TEST_UNIT_CMD_LEN, (PUCHAR)&Cmd, 0, NULL, RetryCount);
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_TEST_UNIT_CMD_LEN, (PUCHAR)&Cmd, 0, NULL, RetryCount);
}
@ -1379,7 +1298,7 @@ USBSTOR_HandleExecuteSCSI(
ASSERT(Request->DataBuffer);
DPRINT("SCSIOP_READ_CAPACITY Length %lu\n", Request->DataTransferLength);
Status = USBSTOR_SendCapacityCmd(DeviceObject, Irp, RetryCount);
Status = USBSTOR_SendCapacity(DeviceObject, Irp, RetryCount);
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE)
{
@ -1390,7 +1309,25 @@ USBSTOR_HandleExecuteSCSI(
//
// send mode sense command
//
Status = USBSTOR_SendModeSenseCmd(DeviceObject, Irp, RetryCount);
Status = USBSTOR_SendModeSense(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_READ_FORMATTED_CAPACITY)
{
DPRINT("SCSIOP_READ_FORMATTED_CAPACITY DataTransferLength %lu\n", Request->DataTransferLength);
//
// send read format capacity
//
Status = USBSTOR_SendFormatCapacity(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_INQUIRY)
{
DPRINT("SCSIOP_INQUIRY DataTransferLength %lu\n", Request->DataTransferLength);
//
// send read format capacity
//
Status = USBSTOR_SendInquiry(DeviceObject, Irp, RetryCount);
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ || pCDB->MODE_SENSE.OperationCode == SCSIOP_WRITE)
{
@ -1399,7 +1336,7 @@ USBSTOR_HandleExecuteSCSI(
//
// send read / write command
//
Status = USBSTOR_SendReadWriteCmd(DeviceObject, Irp, RetryCount);
Status = USBSTOR_SendReadWrite(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_MEDIUM_REMOVAL)
{
@ -1428,7 +1365,7 @@ USBSTOR_HandleExecuteSCSI(
//
// send test unit command
//
Status = USBSTOR_SendTestUnitCmd(DeviceObject, Irp, RetryCount);
Status = USBSTOR_SendTestUnit(DeviceObject, Irp, RetryCount);
}
else
{

View file

@ -330,16 +330,15 @@ typedef struct
PFDO_DEVICE_EXTENSION FDODeviceExtension;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PMDL TransferBufferMDL;
PKEVENT Event;
ULONG ErrorIndex;
ULONG RetryCount;
}IRP_CONTEXT, *PIRP_CONTEXT;
typedef struct _ERRORHANDLER_WORKITEM_DATA
{
PDEVICE_OBJECT DeviceObject;
PIRP_CONTEXT Context;
WORK_QUEUE_ITEM WorkQueueItem;
PDEVICE_OBJECT DeviceObject;
PIRP_CONTEXT Context;
WORK_QUEUE_ITEM WorkQueueItem;
PIRP Irp;
} ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;
@ -448,18 +447,6 @@ USBSTOR_HandleExecuteSCSI(
IN PIRP Irp,
IN ULONG RetryCount);
NTSTATUS
USBSTOR_SendInquiryCmd(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG RetryCount);
NTSTATUS
USBSTOR_SendFormatCapacity(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG RetryCount);
NTSTATUS
NTAPI
USBSTOR_CSWCompletionRoutine(