[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



svn path=/branches/usb-bringup-trunk/; revision=55548
This commit is contained in:
Johannes Anderwald 2012-02-11 19:26:18 +00:00
parent a070e2aaf2
commit 2a06585e89
4 changed files with 166 additions and 11 deletions

View file

@ -11,6 +11,53 @@
#include "usbstor.h" #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 NTSTATUS
USBSTOR_ResetPipeWithHandle( USBSTOR_ResetPipeWithHandle(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -57,6 +104,7 @@ USBSTOR_ResetPipeWithHandle(
return Status; return Status;
} }
NTSTATUS NTSTATUS
USBSTOR_HandleTransferError( USBSTOR_HandleTransferError(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
@ -95,7 +143,7 @@ USBSTOR_HandleTransferError(
// First attempt to reset the pipe // First attempt to reset the pipe
// //
DPRINT1("Resetting Pipe\n"); DPRINT1("Resetting Pipe\n");
Status = USBSTOR_ResetPipeWithHandle(DeviceObject, PipeHandle); Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, PipeHandle);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
@ -149,7 +197,7 @@ USBSTOR_HandleTransferError(
{ {
DPRINT1("Retrying\n"); DPRINT1("Retrying\n");
Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Context->Irp); Status = USBSTOR_HandleExecuteSCSI(*Context->PDODeviceExtension->PDODeviceObject, Context->Irp);
/* Cleanup the old IRP context */ /* Cleanup the old IRP context */
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY) if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)

View file

@ -278,9 +278,15 @@ FreeItem(
} }
NTSTATUS NTSTATUS
USBSTOR_GetMaxLUN( USBSTOR_ClassRequest(
IN PDEVICE_OBJECT DeviceObject, 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; PURB Urb;
PUCHAR Buffer; PUCHAR Buffer;
@ -316,10 +322,11 @@ USBSTOR_GetMaxLUN(
// //
Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE; Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE;
Urb->UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_IN; Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags;
Urb->UrbControlVendorClassRequest.TransferBufferLength = 1; Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength;
Urb->UrbControlVendorClassRequest.TransferBuffer = Buffer; Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer;
Urb->UrbControlVendorClassRequest.Request = USB_BULK_GET_MAX_LUN; Urb->UrbControlVendorClassRequest.Request = RequestType;
Urb->UrbControlVendorClassRequest.Index = Index;
// //
// submit request // submit request
@ -331,6 +338,39 @@ USBSTOR_GetMaxLUN(
// //
FreeItem(Urb); 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); DPRINT1("MaxLUN: %x\n", *Buffer);
if (*Buffer > 0xF) if (*Buffer > 0xF)
@ -359,3 +399,23 @@ USBSTOR_GetMaxLUN(
return Status; 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;
}

View file

@ -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 // free cbw
// //
@ -535,13 +542,15 @@ USBSTOR_SendRequest(
// //
// now build the cbw // now build the cbw
// //
USBSTOR_BuildCBW(0xDEADDEAD, // FIXME tag USBSTOR_BuildCBW((ULONG)Context->cbw,
TransferDataLength, TransferDataLength,
PDODeviceExtension->LUN, PDODeviceExtension->LUN,
CommandLength, CommandLength,
Command, Command,
Context->cbw); Context->cbw);
DPRINT1("CBW %p\n", Context->cbw);
// //
// now initialize the urb // now initialize the urb
// //
@ -757,6 +766,21 @@ USBSTOR_SendInquiryCmd(
// //
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 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("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);
@ -791,16 +815,24 @@ USBSTOR_SendCapacityCmd(
UFI_CAPACITY_CMD Cmd; UFI_CAPACITY_CMD Cmd;
PUFI_CAPACITY_RESPONSE Response; PUFI_CAPACITY_RESPONSE Response;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
// //
// get PDO device extension // get PDO device extension
// //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
// //
// allocate capacity response // allocate capacity response
// //
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, sizeof(UFI_CAPACITY_RESPONSE)); Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, PAGE_SIZE);
if (!Response) if (!Response)
{ {
// //

View file

@ -2,7 +2,7 @@
#pragma once #pragma once
#include <ntddk.h> #include <ntddk.h>
#define NDEBUG #define YDEBUG
#include <debug.h> #include <debug.h>
#include <usbdi.h> #include <usbdi.h>
#include <hubbusif.h> #include <hubbusif.h>
@ -86,6 +86,7 @@ typedef struct
// max lun command identifier // max lun command identifier
// //
#define USB_BULK_GET_MAX_LUN 0xFE #define USB_BULK_GET_MAX_LUN 0xFE
#define USB_BULK_RESET_DEVICE 0xFF
#include <pshpack1.h> #include <pshpack1.h>
typedef struct typedef struct
@ -103,6 +104,8 @@ C_ASSERT(sizeof(CBW) == 31);
#define CBW_SIGNATURE 0x43425355 #define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#define MAX_LUN 0xF #define MAX_LUN 0xF
typedef struct typedef struct
@ -351,6 +354,10 @@ USBSTOR_SyncForwardIrpCompletionRoutine(
PIRP Irp, PIRP Irp,
PVOID Context); PVOID Context);
NTSTATUS
USBSTOR_ResetDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension);
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// //
@ -443,3 +450,11 @@ VOID
USBSTOR_QueueTerminateRequest( USBSTOR_QueueTerminateRequest(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp); IN PIRP Irp);
/* error.c */
NTSTATUS
USBSTOR_GetEndpointStatus(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR bEndpointAddress,
OUT PUSHORT Value);