[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"
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)

View file

@ -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;
}

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
//
@ -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)
{
//

View file

@ -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 @@ typedef struct
// 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 @@ 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);