mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[USBSTOR]
- Queue inquriry & format capacity command with an irp svn path=/trunk/; revision=55695
This commit is contained in:
parent
fa51806949
commit
53bd8f1e21
4 changed files with 472 additions and 290 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue