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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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);
+