mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 14:45:06 +00:00
[USBSTOR]
- Rewrite error handling - Check if CSW is valid - Check if the error handling was already started - Reset device if required - Error handling was completely broken and did not follow the reset procedure as defined in USB Mass Storage Specification Bulk Only Section 5.3.4 - Mass storage device now longer hang when receiving the read capacity request and ReactOS assigns a symbolic link - Mass storage devices not yet fully working svn path=/trunk/; revision=55601
This commit is contained in:
parent
377558ac5a
commit
58df973ed5
|
@ -110,106 +110,159 @@ USBSTOR_HandleTransferError(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP_CONTEXT Context)
|
PIRP_CONTEXT Context)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
USBD_PIPE_HANDLE PipeHandle;
|
//USBD_PIPE_HANDLE PipeHandle;
|
||||||
PSCSI_REQUEST_BLOCK Request;
|
PSCSI_REQUEST_BLOCK Request;
|
||||||
PCDB pCDB;
|
PCDB pCDB;
|
||||||
|
|
||||||
DPRINT1("Entered Handle Transfer Error\n");
|
|
||||||
//
|
//
|
||||||
// Determine pipehandle
|
// first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
|
||||||
//
|
//
|
||||||
if (Context->cbw->CommandBlock[0] == SCSIOP_WRITE)
|
Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// write request used bulk out pipe
|
// step 2 reset bulk in pipe section 5.3.4
|
||||||
//
|
//
|
||||||
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
|
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// finally reset bulk out pipe
|
||||||
|
//
|
||||||
|
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//
|
if (Status != STATUS_SUCCESS)
|
||||||
// default bulk in pipe
|
|
||||||
//
|
|
||||||
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Context->Urb.UrbHeader.Status)
|
|
||||||
{
|
|
||||||
case USBD_STATUS_STALL_PID:
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// First attempt to reset the pipe
|
// Signal the context event
|
||||||
//
|
//
|
||||||
DPRINT1("Resetting Pipe\n");
|
ASSERT(Context->Event);
|
||||||
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, PipeHandle);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT1("Failed to reset pipe %x\n", Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// FIXME: Reset of pipe failed, attempt to reset port
|
|
||||||
//
|
|
||||||
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// FIXME: Handle more errors
|
|
||||||
//
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
DPRINT1("Error not handled\n");
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Context->Irp);
|
|
||||||
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
|
|
||||||
pCDB = (PCDB)Request->Cdb;
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* Signal the context event */
|
|
||||||
if (Context->Event)
|
|
||||||
KeSetEvent(Context->Event, 0, FALSE);
|
KeSetEvent(Context->Event, 0, FALSE);
|
||||||
|
}
|
||||||
/* Cleanup the IRP context */
|
|
||||||
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
|
|
||||||
FreeItem(Context->TransferData);
|
|
||||||
FreeItem(Context->cbw);
|
|
||||||
FreeItem(Context);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
||||||
DPRINT1("Retrying\n");
|
DPRINT1("Retrying\n");
|
||||||
Status = USBSTOR_HandleExecuteSCSI(*Context->PDODeviceExtension->PDODeviceObject, Context->Irp);
|
USBSTOR_HandleExecuteSCSI(*Context->PDODeviceExtension->PDODeviceObject, Context->Irp);
|
||||||
|
|
||||||
/* Cleanup the old IRP context */
|
|
||||||
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
|
|
||||||
FreeItem(Context->TransferData);
|
|
||||||
FreeItem(Context->cbw);
|
|
||||||
FreeItem(Context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// cleanup irp context
|
||||||
|
//
|
||||||
|
FreeItem(Context->cbw);
|
||||||
|
FreeItem(Context);
|
||||||
|
|
||||||
|
|
||||||
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
|
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
USBSTOR_ResetHandlerWorkItemRoutine(
|
||||||
|
PVOID Context)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
USHORT Value;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
|
||||||
|
|
||||||
|
//
|
||||||
|
// clear stall on BulkIn pipe
|
||||||
|
//
|
||||||
|
Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
|
||||||
|
DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get next stack location
|
||||||
|
//
|
||||||
|
|
||||||
|
IoStack = IoGetNextIrpStackLocation(WorkItemData->Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now initialize the urb for sending the csw
|
||||||
|
//
|
||||||
|
UsbBuildInterruptOrBulkTransferRequest(&WorkItemData->Context->Urb,
|
||||||
|
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
|
||||||
|
WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle,
|
||||||
|
WorkItemData->Context->csw,
|
||||||
|
NULL,
|
||||||
|
512, //FIXME
|
||||||
|
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize stack location
|
||||||
|
//
|
||||||
|
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
||||||
|
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
|
||||||
|
IoStack->Parameters.Others.Argument1 = (PVOID)&WorkItemData->Context->Urb;
|
||||||
|
IoStack->Parameters.DeviceIoControl.InputBufferLength = WorkItemData->Context->Urb.UrbHeader.Length;
|
||||||
|
WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// setup completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(WorkItemData->Irp, USBSTOR_CSWCompletionRoutine, Context, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// call driver
|
||||||
|
//
|
||||||
|
IoCallDriver(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Irp);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ErrorHandlerWorkItemRoutine(
|
ErrorHandlerWorkItemRoutine(
|
||||||
|
@ -217,8 +270,21 @@ ErrorHandlerWorkItemRoutine(
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
|
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
|
||||||
|
|
||||||
Status = USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
|
if (WorkItemData->Context->ErrorIndex == 2)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// reset device
|
||||||
|
//
|
||||||
|
Status = USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// clear stall
|
||||||
|
//
|
||||||
|
USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Free Work Item Data
|
// Free Work Item Data
|
||||||
|
|
|
@ -411,7 +411,6 @@ USBSTOR_ResetDevice(
|
||||||
// execute request
|
// execute request
|
||||||
//
|
//
|
||||||
Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
|
Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
|
||||||
DPRINT1("Status %x\n", Status);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// done
|
// done
|
||||||
|
|
|
@ -83,6 +83,75 @@ USBSTOR_AllocateIrpContext()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
USBSTOR_IsCSWValid(
|
||||||
|
PIRP_CONTEXT Context)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
if (Context->csw->Signature != CSW_SIGNATURE)
|
||||||
|
{
|
||||||
|
DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw->Signature);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Context->csw->Tag != (ULONG)Context->csw)
|
||||||
|
{
|
||||||
|
DPRINT1("[USBSTOR] Expected Tag %x but got %x\n", (ULONG)Context->csw, Context->csw->Tag);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Context->csw->Status != 0x00)
|
||||||
|
{
|
||||||
|
DPRINT1("[USBSTOR] Expected Status 0x00 but got %x\n", Context->csw->Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CSW is valid
|
||||||
|
//
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBSTOR_QueueWorkItem(
|
||||||
|
PIRP_CONTEXT Context,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate Work Item Data
|
||||||
|
//
|
||||||
|
ErrorHandlerWorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA), USB_STOR_TAG);
|
||||||
|
if (!ErrorHandlerWorkItemData)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and queue the work item to handle the error
|
||||||
|
//
|
||||||
|
ExInitializeWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem,
|
||||||
|
ErrorHandlerWorkItemRoutine,
|
||||||
|
ErrorHandlerWorkItemData);
|
||||||
|
|
||||||
|
ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject;
|
||||||
|
ErrorHandlerWorkItemData->Context = Context;
|
||||||
|
ErrorHandlerWorkItemData->Irp = Irp;
|
||||||
|
ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject;
|
||||||
|
|
||||||
|
DPRINT1("Queuing WorkItemROutine\n");
|
||||||
|
ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// driver verifier
|
// driver verifier
|
||||||
//
|
//
|
||||||
|
@ -102,7 +171,7 @@ USBSTOR_CSWCompletionRoutine(
|
||||||
PREAD_CAPACITY_DATA_EX CapacityDataEx;
|
PREAD_CAPACITY_DATA_EX CapacityDataEx;
|
||||||
PREAD_CAPACITY_DATA CapacityData;
|
PREAD_CAPACITY_DATA CapacityData;
|
||||||
PUFI_CAPACITY_RESPONSE Response;
|
PUFI_CAPACITY_RESPONSE Response;
|
||||||
PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PURB Urb;
|
PURB Urb;
|
||||||
|
|
||||||
|
@ -143,6 +212,48 @@ USBSTOR_CSWCompletionRoutine(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("USBSTOR_CSWCompletionRoutine Status %x\n", Irp->IoStatus.Status);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Irp->IoStatus.Information))
|
||||||
|
{
|
||||||
|
if (Context->ErrorIndex == 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// increment error index
|
||||||
|
//
|
||||||
|
Context->ErrorIndex = 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// clear stall and resend cbw
|
||||||
|
//
|
||||||
|
Status = USBSTOR_QueueWorkItem(Context, Irp);
|
||||||
|
ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// perform reset recovery
|
||||||
|
//
|
||||||
|
Context->ErrorIndex = 2;
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
Status = USBSTOR_QueueWorkItem(Context, NULL);
|
||||||
|
ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!USBSTOR_IsCSWValid(Context))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// perform reset recovery
|
||||||
|
//
|
||||||
|
Context->ErrorIndex = 2;
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
Status = USBSTOR_QueueWorkItem(Context, NULL);
|
||||||
|
ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Context->Irp)
|
if (Context->Irp)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -164,55 +275,6 @@ USBSTOR_CSWCompletionRoutine(
|
||||||
// get SCSI command data block
|
// get SCSI command data block
|
||||||
//
|
//
|
||||||
pCDB = (PCDB)Request->Cdb;
|
pCDB = (PCDB)Request->Cdb;
|
||||||
|
|
||||||
//
|
|
||||||
// check status
|
|
||||||
//
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Status %x\n", Status);
|
|
||||||
DPRINT1("UrbStatus %x\n", Urb->UrbHeader.Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check for errors that can be handled
|
|
||||||
// FIXME: Verify all usb errors that can be recovered via pipe reset/port reset/controller reset
|
|
||||||
//
|
|
||||||
if ((Urb->UrbHeader.Status & USB_RECOVERABLE_ERRORS) == Urb->UrbHeader.Status)
|
|
||||||
{
|
|
||||||
DPRINT1("Attempting Error Recovery\n");
|
|
||||||
//
|
|
||||||
// free the allocated irp
|
|
||||||
//
|
|
||||||
IoFreeIrp(Irp);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate Work Item Data
|
|
||||||
//
|
|
||||||
ErrorHandlerWorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA), USB_STOR_TAG);
|
|
||||||
if (!ErrorHandlerWorkItemData)
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to allocate memory\n");
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Initialize and queue the work item to handle the error
|
|
||||||
//
|
|
||||||
ExInitializeWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem,
|
|
||||||
ErrorHandlerWorkItemRoutine,
|
|
||||||
ErrorHandlerWorkItemData);
|
|
||||||
|
|
||||||
ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject;
|
|
||||||
ErrorHandlerWorkItemData->Context = Context;
|
|
||||||
DPRINT1("Queuing WorkItemROutine\n");
|
|
||||||
ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue);
|
|
||||||
|
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request->SrbStatus = SRB_STATUS_SUCCESS;
|
Request->SrbStatus = SRB_STATUS_SUCCESS;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -267,30 +329,11 @@ USBSTOR_CSWCompletionRoutine(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// sanity checks
|
|
||||||
//
|
|
||||||
if (Context->csw->Signature != CSW_SIGNATURE)
|
|
||||||
{
|
|
||||||
DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw->Signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Context->csw->Tag != (ULONG)Context->csw)
|
|
||||||
{
|
|
||||||
DPRINT1("[USBSTOR] Expected Tag %x but got %x\n", (ULONG)Context->csw, Context->csw->Tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Context->csw->Status != 0x00)
|
|
||||||
{
|
|
||||||
DPRINT1("[USBSTOR] Expected Status 0x00 but got %x\n", Context->csw->Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// free cbw
|
// free cbw
|
||||||
//
|
//
|
||||||
FreeItem(Context->cbw);
|
FreeItem(Context->cbw);
|
||||||
|
|
||||||
|
|
||||||
if (Context->Irp)
|
if (Context->Irp)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -511,6 +554,19 @@ USBSTOR_CBWCompletionRoutine(
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DumpCBW(
|
||||||
|
PUCHAR Block)
|
||||||
|
{
|
||||||
|
DPRINT1("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||||
|
Block[0] & 0xFF, Block[1] & 0xFF, Block[2] & 0xFF, Block[3] & 0xFF, Block[4] & 0xFF, Block[5] & 0xFF, Block[6] & 0xFF, Block[7] & 0xFF, Block[8] & 0xFF, Block[9] & 0xFF,
|
||||||
|
Block[10] & 0xFF, Block[11] & 0xFF, Block[12] & 0xFF, Block[13] & 0xFF, Block[14] & 0xFF, Block[15] & 0xFF, Block[16] & 0xFF, Block[17] & 0xFF, Block[18] & 0xFF, Block[19] & 0xFF,
|
||||||
|
Block[20] & 0xFF, Block[21] & 0xFF, Block[22] & 0xFF, Block[23] & 0xFF, Block[24] & 0xFF, Block[25] & 0xFF, Block[26] & 0xFF, Block[27] & 0xFF, Block[28] & 0xFF, Block[29] & 0xFF,
|
||||||
|
Block[30] & 0xFF);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
USBSTOR_SendRequest(
|
USBSTOR_SendRequest(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -561,6 +617,7 @@ USBSTOR_SendRequest(
|
||||||
Context->cbw);
|
Context->cbw);
|
||||||
|
|
||||||
DPRINT("CBW %p\n", Context->cbw);
|
DPRINT("CBW %p\n", Context->cbw);
|
||||||
|
DumpCBW((PUCHAR)Context->cbw);
|
||||||
|
|
||||||
//
|
//
|
||||||
// now initialize the urb
|
// now initialize the urb
|
||||||
|
@ -777,21 +834,6 @@ USBSTOR_SendInquiryCmd(
|
||||||
//
|
//
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
KeResetEvent(&Event);
|
|
||||||
DPRINT("Resending request\n");
|
|
||||||
|
|
||||||
//
|
|
||||||
// now send the request
|
|
||||||
//
|
|
||||||
Status = USBSTOR_SendRequest(DeviceObject, NULL, &Event, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_INQUIRY_RESPONSE), (PUCHAR)Response);
|
|
||||||
|
|
||||||
//
|
|
||||||
// wait for the action to complete
|
|
||||||
//
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DPRINT1("Response %p\n", Response);
|
DPRINT1("Response %p\n", Response);
|
||||||
DPRINT1("DeviceType %x\n", Response->DeviceType);
|
DPRINT1("DeviceType %x\n", Response->DeviceType);
|
||||||
DPRINT1("RMB %x\n", Response->RMB);
|
DPRINT1("RMB %x\n", Response->RMB);
|
||||||
|
|
|
@ -279,6 +279,7 @@ typedef struct
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||||
PMDL TransferBufferMDL;
|
PMDL TransferBufferMDL;
|
||||||
PKEVENT Event;
|
PKEVENT Event;
|
||||||
|
ULONG ErrorIndex;
|
||||||
}IRP_CONTEXT, *PIRP_CONTEXT;
|
}IRP_CONTEXT, *PIRP_CONTEXT;
|
||||||
|
|
||||||
typedef struct _ERRORHANDLER_WORKITEM_DATA
|
typedef struct _ERRORHANDLER_WORKITEM_DATA
|
||||||
|
@ -286,6 +287,7 @@ typedef struct _ERRORHANDLER_WORKITEM_DATA
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PIRP_CONTEXT Context;
|
PIRP_CONTEXT Context;
|
||||||
WORK_QUEUE_ITEM WorkQueueItem;
|
WORK_QUEUE_ITEM WorkQueueItem;
|
||||||
|
PIRP Irp;
|
||||||
} ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;
|
} ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
@ -390,6 +392,13 @@ NTSTATUS
|
||||||
USBSTOR_SendInquiryCmd(
|
USBSTOR_SendInquiryCmd(
|
||||||
IN PDEVICE_OBJECT DeviceObject);
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBSTOR_CSWCompletionRoutine(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PVOID Ctx);
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// disk.c routines
|
// disk.c routines
|
||||||
|
@ -442,6 +451,13 @@ NTAPI
|
||||||
ErrorHandlerWorkItemRoutine(
|
ErrorHandlerWorkItemRoutine(
|
||||||
PVOID Context);
|
PVOID Context);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ResetHandlerWorkItemRoutine(
|
||||||
|
PVOID Context);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
USBSTOR_QueueNextRequest(
|
USBSTOR_QueueNextRequest(
|
||||||
IN PDEVICE_OBJECT DeviceObject);
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
@ -458,3 +474,8 @@ USBSTOR_GetEndpointStatus(
|
||||||
IN UCHAR bEndpointAddress,
|
IN UCHAR bEndpointAddress,
|
||||||
OUT PUSHORT Value);
|
OUT PUSHORT Value);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBSTOR_ResetPipeWithHandle(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN USBD_PIPE_HANDLE PipeHandle);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue