mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[USBSTOR]
- Start implementing error handling. - On errors use a worker thread to attempt a recovery. If successful restart the operation that failed. - If STALL_PID is received reset the pipe of the device. - Not entered into code path yet. WIP. svn path=/branches/usb-bringup/; revision=51754
This commit is contained in:
parent
f1ec4fbe16
commit
e5f521c90a
2 changed files with 160 additions and 1 deletions
|
@ -3,7 +3,7 @@ add_definitions(-DDEBUG_MODE)
|
|||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||
|
||||
add_library(usbstor SHARED descriptor.c disk.c fdo.c misc.c pdo.c queue.c scsi.c usbstor.c usbstor.rc)
|
||||
add_library(usbstor SHARED descriptor.c disk.c fdo.c misc.c pdo.c queue.c error.c scsi.c usbstor.c usbstor.rc)
|
||||
|
||||
set_module_type(usbstor kernelmodedriver)
|
||||
add_importlibs(usbstor ntoskrnl hal usbd)
|
||||
|
|
159
drivers/usb/usbstor/error.c
Normal file
159
drivers/usb/usbstor/error.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbstor/error.c
|
||||
* PURPOSE: USB block storage device driver.
|
||||
* PROGRAMMERS:
|
||||
* James Tabor
|
||||
* Michael Martin (michael.martin@reactos.org)
|
||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "usbstor.h"
|
||||
|
||||
NTSTATUS
|
||||
USBSTOR_ResetPipeWithHandle(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN USBD_PIPE_HANDLE PipeHandle)
|
||||
{
|
||||
PURB Urb;
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// allocate urb
|
||||
//
|
||||
DPRINT1("Allocating URB\n");
|
||||
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
|
||||
if (!Urb)
|
||||
{
|
||||
//
|
||||
// out of memory
|
||||
//
|
||||
DPRINT1("OutofMemory!\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize the urb
|
||||
//
|
||||
Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
|
||||
Urb->UrbPipeRequest.Hdr.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL;
|
||||
Urb->UrbPipeRequest.PipeHandle = PipeHandle;
|
||||
|
||||
//
|
||||
// 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_HandleTransferError(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp,
|
||||
PIRP_CONTEXT Context)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PURB Urb;
|
||||
USBD_PIPE_HANDLE PipeHandle;
|
||||
PSCSI_REQUEST_BLOCK Request;
|
||||
|
||||
DPRINT1("Entered Handle Transfer Error\n");
|
||||
//
|
||||
// Determine pipehandle
|
||||
//
|
||||
if (Context->cbw->CommandBlock[0] == SCSIOP_WRITE)
|
||||
{
|
||||
//
|
||||
// write request used bulk out pipe
|
||||
//
|
||||
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// default bulk in pipe
|
||||
//
|
||||
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
|
||||
}
|
||||
|
||||
switch (Context->Urb.UrbHeader.Status)
|
||||
{
|
||||
case USBD_STATUS_STALL_PID:
|
||||
{
|
||||
//
|
||||
// First attempt to reset the pipe
|
||||
//
|
||||
DPRINT1("Resetting Pipe\n");
|
||||
Status = USBSTOR_ResetPipeWithHandle(DeviceObject, PipeHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT1("Failed to reset pipe %x\n");
|
||||
|
||||
//
|
||||
// FIXME: Reset of pipe failed, attempt to reset port
|
||||
//
|
||||
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// FIXME: Handle more errors
|
||||
//
|
||||
default:
|
||||
{
|
||||
DPRINT1("Error not handled\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Stack = IoGetCurrentIrpStackLocation(Context->Irp);
|
||||
//
|
||||
// Retry the operation
|
||||
//
|
||||
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
|
||||
DPRINT1("Retrying\n");
|
||||
Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Context->Irp, Request, Context->PDODeviceExtension);
|
||||
}
|
||||
|
||||
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ErrorHandlerWorkItemRoutine(
|
||||
PVOID Context)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
|
||||
|
||||
Status = USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Irp, WorkItemData->Context);
|
||||
|
||||
//
|
||||
// Free Work Item Data
|
||||
//
|
||||
ExFreePool(WorkItemData);
|
||||
}
|
Loading…
Reference in a new issue