mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 14:45:06 +00:00
[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:
parent
a070e2aaf2
commit
2a06585e89
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue