Author: janderwald Date: Sat Feb 11 19:26:18 2012 New Revision: 55548
URL: http://svn.reactos.org/svn/reactos?rev=55548&view=rev Log: [USBSTOR] - Implement retrieving endpoint halted status - Fix multiple bugs which leaded to crashes (wrong device object passed). Usbstor now successfully restarts requests after handling the errors - Implement mass storage reset, not yet used - Add checks in CSW completion
Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/error.c branches/usb-bringup-trunk/drivers/usb/usbstor/misc.c branches/usb-bringup-trunk/drivers/usb/usbstor/scsi.c branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h
Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/error.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbstor/error.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbstor/error.c [iso-8859-1] Sat Feb 11 19:26:18 2012 @@ -12,6 +12,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, IN USBD_PIPE_HANDLE PipeHandle) @@ -56,6 +103,7 @@ // return Status; } +
NTSTATUS USBSTOR_HandleTransferError( @@ -95,7 +143,7 @@ // 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 @@ {
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)
Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/misc.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbstor/misc.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbstor/misc.c [iso-8859-1] Sat Feb 11 19:26:18 2012 @@ -278,25 +278,80 @@ }
NTSTATUS +USBSTOR_ClassRequest( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension, + IN UCHAR RequestType, + IN USHORT Index, + IN ULONG TransferFlags, + IN ULONG TransferBufferLength, + IN PVOID TransferBuffer) + +{ + PURB Urb; + PUCHAR Buffer; + NTSTATUS Status; + + // + // first allocate urb + // + Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); + if (!Urb) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // 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); + Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE; + Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags; + Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength; + Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer; + Urb->UrbControlVendorClassRequest.Request = RequestType; + Urb->UrbControlVendorClassRequest.Index = Index; + + // + // submit request + // + Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); + + // + // free urb + // + FreeItem(Urb); + + // + // done + // + return Status; +} + + +NTSTATUS USBSTOR_GetMaxLUN( IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension) { - PURB Urb; PUCHAR Buffer; NTSTATUS Status; - - // - // first allocate urb - // - Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); - if (!Urb) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - }
// // allocate 1-byte buffer @@ -312,24 +367,9 @@ }
// - // initialize vendor request - // - 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; - - // - // submit request - // - Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); - - // - // free urb - // - FreeItem(Urb); + // 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);
@@ -359,3 +399,23 @@ 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; + +}
Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/scsi.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbstor/scsi.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbstor/scsi.c [iso-8859-1] Sat Feb 11 19:26:18 2012 @@ -268,6 +268,13 @@ }
// + // sanity checks + // + ASSERT(Context->csw->Signature == CSW_SIGNATURE); + ASSERT(Context->csw->Tag == (ULONG)Context->csw); + ASSERT(Context->csw->Status == 0x00); + + // // free cbw // FreeItem(Context->cbw); @@ -535,12 +542,14 @@ // // 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 @@ // 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 @@ 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) { //
Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h [iso-8859-1] Sat Feb 11 19:26:18 2012 @@ -2,7 +2,7 @@ #pragma once
#include <ntddk.h> -#define NDEBUG +#define YDEBUG #include <debug.h> #include <usbdi.h> #include <hubbusif.h> @@ -86,6 +86,7 @@ // max lun command identifier // #define USB_BULK_GET_MAX_LUN 0xFE +#define USB_BULK_RESET_DEVICE 0xFF
#include <pshpack1.h> typedef struct @@ -103,6 +104,8 @@
#define CBW_SIGNATURE 0x43425355 +#define CSW_SIGNATURE 0x53425355 + #define MAX_LUN 0xF
typedef struct @@ -351,6 +354,10 @@ PIRP Irp, PVOID Context);
+NTSTATUS +USBSTOR_ResetDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension);
//--------------------------------------------------------------------- // @@ -443,3 +450,11 @@ USBSTOR_QueueTerminateRequest( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); + +/* error.c */ +NTSTATUS +USBSTOR_GetEndpointStatus( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR bEndpointAddress, + OUT PUSHORT Value); +