mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 15:19:09 +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"
|
#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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue