Index: drivers/usb/usbstor/disk.c =================================================================== --- drivers/usb/usbstor/disk.c (revision 70327) +++ drivers/usb/usbstor/disk.c (working copy) @@ -502,8 +502,8 @@ // AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); - AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value - AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value + AdapterDescriptor->MaximumTransferLength = 0x10000; //MAXULONG; //FIXME compute some sane value + AdapterDescriptor->MaximumPhysicalPages = 17; //25; //FIXME compute some sane value AdapterDescriptor->AlignmentMask = 0; AdapterDescriptor->AdapterUsesPio = FALSE; AdapterDescriptor->AdapterScansDown = FALSE; Index: drivers/usb/usbstor/error.c =================================================================== --- drivers/usb/usbstor/error.c (revision 70327) +++ drivers/usb/usbstor/error.c (working copy) @@ -109,15 +109,50 @@ NTSTATUS +NTAPI +USBSTOR_ResetRecovery( + IN PFDO_DEVICE_EXTENSION FDODeviceExtension) +{ + NTSTATUS Status; + + DPRINT("USBSTOR_ResetRecovery\n"); + + // + // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk-Only Specification + // + Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension); + if (NT_SUCCESS(Status)) + { + // + // step 2 reset Bulk-In pipe section 5.3.4 + // + Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle); + if (NT_SUCCESS(Status)) + { + // + // finally reset Bulk-Out pipe + // + Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle); + } + } + + return Status; +} + +NTSTATUS +NTAPI USBSTOR_HandleTransferError( - PDEVICE_OBJECT DeviceObject, - PIRP_CONTEXT Context) + PVOID ErrorContext) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION Stack; PSCSI_REQUEST_BLOCK Request; PCDB pCDB; + PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)ErrorContext; + PIRP_CONTEXT Context = WorkItemData->Context; + //DPRINT("USBSTOR_HandleTransferError: ErrorIndex - %x, RetryCount - %x\n", Context->ErrorIndex, Context->RetryCount); + // // sanity checks // @@ -127,23 +162,9 @@ ASSERT(Context->Irp); // - // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification + // perform Reset Recovery // - Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension); - if (NT_SUCCESS(Status)) - { - // - // step 2 reset bulk in pipe section 5.3.4 - // - 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); - } - } + USBSTOR_ResetRecovery(Context->FDODeviceExtension); // // get next stack location @@ -243,6 +264,32 @@ USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp); } +NTSTATUS +NTAPI +USBSTOR_HandleResetRecover( + PVOID ErrorContext) +{ + NTSTATUS Status; + PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)ErrorContext; + PIRP_CONTEXT Context = WorkItemData->Context; + + // + // perform Reset Recovery + // + Status = USBSTOR_ResetRecovery(Context->FDODeviceExtension); + DPRINT("Index %x, Count %x, ResetRecovery %x\n", Context->ErrorIndex, Context->RetryCount, Status); + + if (NT_SUCCESS(Status)) + { + // + // now send the CSW + // + USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp); + } + + return Status; +} + VOID NTAPI ErrorHandlerWorkItemRoutine( @@ -250,20 +297,27 @@ { PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; - if (WorkItemData->Context->ErrorIndex == 2) + if (WorkItemData->Context->ErrorIndex == 1) { // - // reset device + // clear STALL // - USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context); + USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData); } - else + else if (WorkItemData->Context->ErrorIndex == 2) { // - // clear stall + // perform Reset Recovery and send the CSW // - USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData); + USBSTOR_HandleResetRecover(WorkItemData); } + else if (WorkItemData->Context->ErrorIndex == 3) + { + // + // perform Reset Recovery and handle error + // + USBSTOR_HandleTransferError(WorkItemData); + } // // Free Work Item Data Index: drivers/usb/usbstor/misc.c =================================================================== --- drivers/usb/usbstor/misc.c (revision 70327) +++ drivers/usb/usbstor/misc.c (working copy) @@ -292,7 +292,6 @@ { PURB Urb; - PUCHAR Buffer; NTSTATUS Status; // @@ -308,19 +307,6 @@ } // - // allocate 1-byte buffer - // - Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR)); - if (!Buffer) - { - // - // no memory - // - FreeItem(Buffer); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // // initialize vendor request // Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); @@ -369,6 +355,8 @@ return STATUS_INSUFFICIENT_RESOURCES; } + *Buffer = 0; + // // execute request // @@ -376,19 +364,34 @@ DPRINT("MaxLUN: %x\n", *Buffer); - if (*Buffer > 0xF) + if ( NT_SUCCESS(Status) ) { - // - // invalid response documented in usb mass storage specification - // - Status = STATUS_DEVICE_DATA_ERROR; + if (*Buffer > 0xF) + { + // + // invalid response documented in usb mass storage specification + // + Status = STATUS_DEVICE_DATA_ERROR; + } + else + { + // + // store maxlun + // + DeviceExtension->MaxLUN = *Buffer; + } } else { // - // store maxlun + // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0" + // 3.2 Get Max LUN (class-specific request) : + // Devices that do not support multiple LUNs may STALL this command. // - DeviceExtension->MaxLUN = *Buffer; + USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension); + + DeviceExtension->MaxLUN = 0; + Status = STATUS_SUCCESS; } // Index: drivers/usb/usbstor/pdo.c =================================================================== --- drivers/usb/usbstor/pdo.c (revision 70327) +++ drivers/usb/usbstor/pdo.c (working copy) @@ -1342,12 +1342,12 @@ // // check if it is a floppy // - Status = USBSTOR_SendFormatCapacityIrp(PDO); + //Status = USBSTOR_SendFormatCapacityIrp(PDO); // // display result // - DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode); + DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x. FIXME: is a floppy\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode); // // failing command is non critical Index: drivers/usb/usbstor/scsi.c =================================================================== --- drivers/usb/usbstor/scsi.c (revision 70327) +++ drivers/usb/usbstor/scsi.c (working copy) @@ -93,6 +93,12 @@ // // sanity checks // + if (sizeof(CSW) != 0x0d) + { + DPRINT1("[USBSTOR] Expected sizeof(CSW) == 0x0d but got %x\n", sizeof(CSW)); + return FALSE; + } + if (Context->csw->Signature != CSW_SIGNATURE) { DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw->Signature); @@ -105,12 +111,6 @@ return FALSE; } - if (Context->csw->Status != 0x00) - { - DPRINT1("[USBSTOR] Expected Status 0x00 but got %x\n", Context->csw->Status); - return FALSE; - } - // // CSW is valid // @@ -164,7 +164,294 @@ return STATUS_MORE_PROCESSING_REQUIRED; } +// +// driver verifier +// +IO_COMPLETION_ROUTINE USBSTOR_SenseCSWCompletionRoutine; +NTSTATUS +NTAPI +USBSTOR_SenseCSWCompletionRoutine( + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Ctx) +{ + PIRP_CONTEXT Context = (PIRP_CONTEXT)Ctx; + PIRP_CONTEXT OriginalContext = Context->OriginalContext; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Srb; + PDEVICE_OBJECT FdoDevice = Context->PDODeviceExtension->LowerDeviceObject; + PFDO_DEVICE_EXTENSION FdoDeviceExtension = Context->PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + + DPRINT("USBSTOR_SenseCSWCompletionRoutine: Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status); + + // is there a MDL + if (Context->TransferBufferMDL) + { + // is there an IRP associated + if (Context->Irp) + { + // did we allocate the MDL + if (Context->TransferBufferMDL != Context->Irp->MdlAddress) + { + // free MDL + IoFreeMdl(Context->TransferBufferMDL); + } + } + else + { + // free MDL + IoFreeMdl(Context->TransferBufferMDL); + } + } + + if (!NT_SUCCESS(Irp->IoStatus.Status)) + { + // if STALL + DPRINT1("USBSTOR_SenseCSWCompletionRoutine Status %x\n", Irp->IoStatus.Status); + } + + if (!USBSTOR_IsCSWValid(Context)) + { + // 6.3.1 Valid CSW + DPRINT1("CSW not Valid. Index %x Status %x\n", Context->ErrorIndex, Irp->IoStatus.Status); + } + + // 6.3.2 Meaningful CSW + if (Context->csw->Status <= 0x02) + { + if (Context->csw->Status == 0x01) + { + DPRINT1("CSWStatus 0x01. Command failed\n"); + } + + if (Context->csw->Status == 0x02) + { + DPRINT1("CSWStatus 0x02. Reset recovery\n"); + } + } + else + { + DPRINT1("FIXME: CSW not Meaningful. CSWStatus %x\n", Irp->IoStatus.Status); + ASSERT(FALSE); + } + + // FIXME: check status + //Context->Irp->IoStatus.Status = Irp->IoStatus.Status; + //Context->Irp->IoStatus.Information = Context->TransferDataLength; + + // free our allocated Sense IRP + IoFreeIrp(Irp); + + // free Sense CBW + FreeItem(Context->cbw); + + // free our allocated CDB + ExFreePool(Context->SenseCDB); + + // free our allocated IRP + IoFreeIrp(Context->Irp); + + // free Sense Context + FreeItem(Context); + + // get SRB pointer + IoStack = IoGetCurrentIrpStackLocation(OriginalContext->Irp); + Srb = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + ASSERT(Srb); + + // Sense data is OK + Srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID; + + // free CBW + FreeItem(OriginalContext->cbw); + + // FIXME: check status -> if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS ) Irp->IoStatus.Status = ConvertSrbStatus(Srb->SrbStatus); + OriginalContext->Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; + OriginalContext->Irp->IoStatus.Information = 0; // OriginalContext->TransferDataLength; + + if (FdoDeviceExtension->IrpListFreeze) + { + // UnFreezing Queue (?spinlock) + FdoDeviceExtension->IrpListFreeze = FALSE; + } + + // terminate current IRP + USBSTOR_QueueTerminateRequest(FdoDevice, OriginalContext->Irp); + + // complete IRP + IoCompleteRequest(OriginalContext->Irp, IO_NO_INCREMENT); + + // start next IRP + USBSTOR_QueueNextRequest(FdoDevice); + + // free context + FreeItem(OriginalContext); + + // done + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +USBSTOR_SendRequestSense( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP OriginalIrp, + IN PIRP_CONTEXT OriginalContext) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension = OriginalContext->PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension = OriginalContext->FDODeviceExtension; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(OriginalContext->Irp); + PSCSI_REQUEST_BLOCK InitialSrb; + PCDB Cdb; + PIRP_CONTEXT Context; + PIRP Irp; + + + // + // allocate CDB for REQUEST SENSE + // + Cdb = ExAllocatePool(NonPagedPool, sizeof(Cdb->CDB6INQUIRY)); + + if ( Cdb == NULL ) + { + DPRINT1("USBSTOR_SendRequestSense Allocate CDB failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(Cdb, sizeof(Cdb->CDB6INQUIRY)); + + // + // get original SRB + // + InitialSrb = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + ASSERT(InitialSrb); + + // + // Build CDB for REQUEST SENSE + // + Cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE; + Cdb->CDB6INQUIRY.LogicalUnitNumber = (PDODeviceExtension->LUN & 15); //USB_MAX_LUN + Cdb->CDB6INQUIRY.Reserved1 = 0; + Cdb->CDB6INQUIRY.PageCode = 0; + Cdb->CDB6INQUIRY.IReserved = 0; + Cdb->CDB6INQUIRY.AllocationLength = (UCHAR)InitialSrb->SenseInfoBufferLength; + Cdb->CDB6INQUIRY.Control = 0; + + // + // allocate IRP-context for REQUEST SENSE + // + Context = USBSTOR_AllocateIrpContext(); + if (!Context) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // save old IRP-context + // + Context->OriginalContext = OriginalContext; + + // + // now build the CBW + // + USBSTOR_BuildCBW((ULONG)Context->cbw, + InitialSrb->SenseInfoBufferLength, + PDODeviceExtension->LUN, + sizeof(Cdb->CDB6INQUIRY), //6 + (PUCHAR)Cdb, + Context->cbw); + + DPRINT("USBSTOR_SendRequestSense: CBW %p\n", Context->cbw); + //DumpCBW((PUCHAR)Context->cbw); + + // + // now initialize the URB + // + UsbBuildInterruptOrBulkTransferRequest(&Context->Urb, + sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), + FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle, + Context->cbw, + NULL, + sizeof(CBW), + USBD_TRANSFER_DIRECTION_OUT, + NULL); + + // + // initialize context + // + Context->Irp = OriginalIrp; + Context->TransferData = InitialSrb->SenseInfoBuffer; + Context->TransferDataLength = InitialSrb->SenseInfoBufferLength; + Context->FDODeviceExtension = OriginalContext->FDODeviceExtension; + Context->PDODeviceExtension = OriginalContext->PDODeviceExtension; + Context->RetryCount = OriginalContext->RetryCount; + Context->ErrorIndex = 0; + + // + // save CDB + // + Context->SenseCDB = Cdb; + + // + // is there transfer data + // + if (Context->TransferDataLength) + { + // + // allocate MDL for buffer, buffer must be allocated from NonPagedPool + // + Context->TransferBufferMDL = IoAllocateMdl(Context->TransferData, Context->TransferDataLength, FALSE, FALSE, NULL); + if (!Context->TransferBufferMDL) + { + // + // failed to allocate MDL + // + FreeItem(Context->cbw); + FreeItem(Context); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // build MDL for nonpaged pool + // + MmBuildMdlForNonPagedPool(Context->TransferBufferMDL); + } + + // + // now allocate the IRP + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + FreeItem(Context->cbw); + FreeItem(Context); + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (OriginalIrp) + { + // + // mark orignal IRP as pending + // + IoMarkIrpPending(OriginalIrp); + } + + // + // send IRP + // + DPRINT("USBSTOR_SendRequestSense: USBSTOR_SendCBW(%p, %p), Irql %x\n", Context, Irp, KeGetCurrentIrql()); + USBSTOR_SendCBW(Context, Irp); + + // + // done + // + return STATUS_PENDING; +} + // // driver verifier // @@ -185,11 +472,15 @@ PREAD_CAPACITY_DATA CapacityData; PUFI_CAPACITY_RESPONSE Response; NTSTATUS Status; + PDEVICE_OBJECT FdoDevice; + PFDO_DEVICE_EXTENSION FdoDeviceExtension; // // access context // Context = (PIRP_CONTEXT)Ctx; + FdoDevice = Context->PDODeviceExtension->LowerDeviceObject; + FdoDeviceExtension = FdoDevice->DeviceExtension; // // is there a mdl @@ -223,7 +514,7 @@ DPRINT("USBSTOR_CSWCompletionRoutine Status %x\n", Irp->IoStatus.Status); - if (!NT_SUCCESS(Irp->IoStatus.Information)) + if (!NT_SUCCESS(Irp->IoStatus.Status)) { if (Context->ErrorIndex == 0) { @@ -233,7 +524,7 @@ Context->ErrorIndex = 1; // - // clear stall and resend cbw + // clear STALL and resend CSW // Status = USBSTOR_QueueWorkItem(Context, Irp); ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED); @@ -241,10 +532,18 @@ } // - // perform reset recovery + // increment error index // - Context->ErrorIndex = 2; + Context->ErrorIndex = 3; + + // + // free our allocated irp + // IoFreeIrp(Irp); + + // + // perform Reset Recovery and handle error + // Status = USBSTOR_QueueWorkItem(Context, NULL); ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED); return STATUS_MORE_PROCESSING_REQUIRED; @@ -253,16 +552,72 @@ if (!USBSTOR_IsCSWValid(Context)) { // - // perform reset recovery + // increment error index // - Context->ErrorIndex = 2; + Context->ErrorIndex = 3; + + // + // free our allocated irp + // IoFreeIrp(Irp); + + // + // perform Reset Recovery and handle error + // Status = USBSTOR_QueueWorkItem(Context, NULL); ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED); return STATUS_MORE_PROCESSING_REQUIRED; } + // + // 6.3.2 Meaningful CSW + // + if (Context->csw->Status <= 0x02) + { + if (Context->csw->Status == 0x01) // 6.6.4 Command Failure + { + DPRINT1("CSWStatus 0x01. Command failed\n"); + // + // Freezing Queue (?spinlock) + // + FdoDeviceExtension->IrpListFreeze = TRUE; + + // + // Send a SCSI REQUEST SENSE command + // + Status = USBSTOR_SendRequestSense(Context->PDODeviceExtension->Self, Irp, Context); + return STATUS_MORE_PROCESSING_REQUIRED; + } + + if (Context->csw->Status == 0x02) //6.6.2 Internal Device Error + { + DPRINT1("CSWStatus 0x02. Reset recovery\n"); + + // + // increment error index + // + Context->ErrorIndex = 3; + + // + // free our allocated irp + // + IoFreeIrp(Irp); + + // + // perform Reset Recovery and handle error + // + Status = USBSTOR_QueueWorkItem(Context, NULL); + ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED); + return STATUS_MORE_PROCESSING_REQUIRED; + } + } + else + { + DPRINT1("FIXME: CSW not Meaningful. CSWStatus %x\n", Irp->IoStatus.Status); + ASSERT(FALSE); + } + // // get current stack location // @@ -274,8 +629,6 @@ Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; ASSERT(Request); - Status = Irp->IoStatus.Status; - // // get SCSI command data block // @@ -347,7 +700,7 @@ // // terminate current request // - USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp); + USBSTOR_QueueTerminateRequest(FdoDevice, Context->Irp); // // complete request @@ -357,7 +710,7 @@ // // start next request // - USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject); + USBSTOR_QueueNextRequest(FdoDevice); // // free our allocated irp @@ -395,7 +748,7 @@ Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle, Context->csw, NULL, - 512, //FIXME + sizeof(CSW), USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, NULL); @@ -410,9 +763,22 @@ // - // setup completion routine + // if error - IRP List (queue) Frozen // - IoSetCompletionRoutine(Irp, USBSTOR_CSWCompletionRoutine, Context, TRUE, TRUE, TRUE); + if (Context->FDODeviceExtension->IrpListFreeze) + { + // + // setup completion routine for Request Sense + // + IoSetCompletionRoutine(Irp, USBSTOR_SenseCSWCompletionRoutine, Context, TRUE, TRUE, TRUE); + } + else + { + // + // setup completion routine + // + IoSetCompletionRoutine(Irp, USBSTOR_CSWCompletionRoutine, Context, TRUE, TRUE, TRUE); + } // // call driver @@ -420,7 +786,6 @@ IoCallDriver(Context->FDODeviceExtension->LowerDeviceObject, Irp); } - // // driver verifier // @@ -447,7 +812,7 @@ if (!NT_SUCCESS(Irp->IoStatus.Status)) { // - // clear stall and resend cbw + // clear STALL and send CSW // Context->ErrorIndex = 1; Status = USBSTOR_QueueWorkItem(Context, Irp); @@ -482,6 +847,7 @@ PIO_STACK_LOCATION IoStack; UCHAR Code; USBD_PIPE_HANDLE PipeHandle; + NTSTATUS Status; DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status); @@ -495,6 +861,17 @@ // IoStack = IoGetNextIrpStackLocation(Irp); + if (!NT_SUCCESS(Irp->IoStatus.Status)) + { + // + // perform Reset Recovery and send the CSW + // + Context->ErrorIndex = 2; + Status = USBSTOR_QueueWorkItem(Context, Irp); + ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED); + return STATUS_MORE_PROCESSING_REQUIRED; + } + // // is there data to be submitted // @@ -548,7 +925,7 @@ Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle, Context->csw, NULL, - 512, //FIXME + sizeof(CSW), USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, NULL); @@ -691,6 +1068,7 @@ Context->FDODeviceExtension = FDODeviceExtension; Context->PDODeviceExtension = PDODeviceExtension; Context->RetryCount = RetryCount; + Context->ErrorIndex = 0; // // is there transfer data Index: drivers/usb/usbstor/usbstor.h =================================================================== --- drivers/usb/usbstor/usbstor.h (revision 70327) +++ drivers/usb/usbstor/usbstor.h (working copy) @@ -312,7 +312,7 @@ UCHAR Bytes[16]; }UFI_UNKNOWN_CMD, *PUFI_UNKNOWN_CMD; -typedef struct +typedef struct _IRP_CONTEXT { union { @@ -328,6 +328,8 @@ PMDL TransferBufferMDL; ULONG ErrorIndex; ULONG RetryCount; + PCDB SenseCDB; + struct _IRP_CONTEXT *OriginalContext; }IRP_CONTEXT, *PIRP_CONTEXT; typedef struct _ERRORHANDLER_WORKITEM_DATA