diff --git a/drivers/usb/usbstor/error.c b/drivers/usb/usbstor/error.c index 2c9f577d734..be91d44a222 100644 --- a/drivers/usb/usbstor/error.c +++ b/drivers/usb/usbstor/error.c @@ -11,6 +11,53 @@ #include "usbstor.h" +NTSTATUS +USBSTOR_GetEndpointStatus( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR bEndpointAddress, + OUT PUSHORT Value) +{ + PURB Urb; + NTSTATUS Status; + + // + // allocate urb + // + DPRINT1("Allocating URB\n"); + Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); + if (!Urb) + { + // + // out of memory + // + DPRINT1("OutofMemory!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // build status + // + UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL); + + // + // send the request + // + DPRINT1("Sending Request DeviceObject %x, Urb %x\n", DeviceObject, Urb); + Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); + + // + // free urb + // + FreeItem(Urb); + + // + // done + // + return Status; +} + + + NTSTATUS USBSTOR_ResetPipeWithHandle( IN PDEVICE_OBJECT DeviceObject, @@ -57,6 +104,7 @@ USBSTOR_ResetPipeWithHandle( return Status; } + NTSTATUS USBSTOR_HandleTransferError( PDEVICE_OBJECT DeviceObject, @@ -95,7 +143,7 @@ USBSTOR_HandleTransferError( // First attempt to reset the pipe // DPRINT1("Resetting Pipe\n"); - Status = USBSTOR_ResetPipeWithHandle(DeviceObject, PipeHandle); + Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, PipeHandle); if (NT_SUCCESS(Status)) { Status = STATUS_SUCCESS; @@ -149,7 +197,7 @@ USBSTOR_HandleTransferError( { DPRINT1("Retrying\n"); - Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Context->Irp); + Status = USBSTOR_HandleExecuteSCSI(*Context->PDODeviceExtension->PDODeviceObject, Context->Irp); /* Cleanup the old IRP context */ if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY) diff --git a/drivers/usb/usbstor/misc.c b/drivers/usb/usbstor/misc.c index 1ce42adcb4a..45e3f82f56a 100644 --- a/drivers/usb/usbstor/misc.c +++ b/drivers/usb/usbstor/misc.c @@ -278,9 +278,15 @@ FreeItem( } NTSTATUS -USBSTOR_GetMaxLUN( +USBSTOR_ClassRequest( IN PDEVICE_OBJECT DeviceObject, - IN PFDO_DEVICE_EXTENSION DeviceExtension) + IN PFDO_DEVICE_EXTENSION DeviceExtension, + IN UCHAR RequestType, + IN USHORT Index, + IN ULONG TransferFlags, + IN ULONG TransferBufferLength, + IN PVOID TransferBuffer) + { PURB Urb; PUCHAR Buffer; @@ -316,10 +322,11 @@ USBSTOR_GetMaxLUN( // Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE; - Urb->UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_IN; - Urb->UrbControlVendorClassRequest.TransferBufferLength = 1; - Urb->UrbControlVendorClassRequest.TransferBuffer = Buffer; - Urb->UrbControlVendorClassRequest.Request = USB_BULK_GET_MAX_LUN; + Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags; + Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength; + Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer; + Urb->UrbControlVendorClassRequest.Request = RequestType; + Urb->UrbControlVendorClassRequest.Index = Index; // // submit request @@ -331,6 +338,39 @@ USBSTOR_GetMaxLUN( // FreeItem(Urb); + // + // done + // + return Status; +} + + +NTSTATUS +USBSTOR_GetMaxLUN( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension) +{ + PUCHAR Buffer; + NTSTATUS Status; + + // + // allocate 1-byte buffer + // + Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR)); + if (!Buffer) + { + // + // no memory + // + FreeItem(Buffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // execute request + // + Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer); + DPRINT1("MaxLUN: %x\n", *Buffer); if (*Buffer > 0xF) @@ -359,3 +399,23 @@ USBSTOR_GetMaxLUN( return Status; } + +NTSTATUS +USBSTOR_ResetDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + + // + // execute request + // + Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL); + DPRINT1("Status %x\n", Status); + + // + // done + // + return Status; + +} diff --git a/drivers/usb/usbstor/scsi.c b/drivers/usb/usbstor/scsi.c index c6fff8e7705..eb7cf119bf6 100644 --- a/drivers/usb/usbstor/scsi.c +++ b/drivers/usb/usbstor/scsi.c @@ -267,6 +267,13 @@ USBSTOR_CSWCompletionRoutine( } } + // + // sanity checks + // + ASSERT(Context->csw->Signature == CSW_SIGNATURE); + ASSERT(Context->csw->Tag == (ULONG)Context->csw); + ASSERT(Context->csw->Status == 0x00); + // // free cbw // @@ -535,13 +542,15 @@ USBSTOR_SendRequest( // // now build the cbw // - USBSTOR_BuildCBW(0xDEADDEAD, // FIXME tag + USBSTOR_BuildCBW((ULONG)Context->cbw, TransferDataLength, PDODeviceExtension->LUN, CommandLength, Command, Context->cbw); + DPRINT1("CBW %p\n", Context->cbw); + // // now initialize the urb // @@ -757,6 +766,21 @@ USBSTOR_SendInquiryCmd( // KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + KeResetEvent(&Event); + DPRINT1("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("DeviceType %x\n", Response->DeviceType); DPRINT1("RMB %x\n", Response->RMB); @@ -791,16 +815,24 @@ 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 // - Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, sizeof(UFI_CAPACITY_RESPONSE)); + Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, PAGE_SIZE); if (!Response) { // diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h index 4ad419facf1..47dabfd5442 100644 --- a/drivers/usb/usbstor/usbstor.h +++ b/drivers/usb/usbstor/usbstor.h @@ -2,7 +2,7 @@ #pragma once #include -#define NDEBUG +#define YDEBUG #include #include #include @@ -86,6 +86,7 @@ typedef struct // max lun command identifier // #define USB_BULK_GET_MAX_LUN 0xFE +#define USB_BULK_RESET_DEVICE 0xFF #include typedef struct @@ -103,6 +104,8 @@ C_ASSERT(sizeof(CBW) == 31); #define CBW_SIGNATURE 0x43425355 +#define CSW_SIGNATURE 0x53425355 + #define MAX_LUN 0xF typedef struct @@ -351,6 +354,10 @@ USBSTOR_SyncForwardIrpCompletionRoutine( PIRP Irp, PVOID Context); +NTSTATUS +USBSTOR_ResetDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension); //--------------------------------------------------------------------- // @@ -443,3 +450,11 @@ VOID USBSTOR_QueueTerminateRequest( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); + +/* error.c */ +NTSTATUS +USBSTOR_GetEndpointStatus( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR bEndpointAddress, + OUT PUSHORT Value); +