[FORMATTING][USBSTOR] Remove Captain Obvious and line-wasting comments.

Now the driver conforms with our current Coding Style.
No functional changes
This commit is contained in:
Victor Perevertkin 2019-03-24 23:01:43 +03:00
parent 33604e0147
commit d17d15ab6c
9 changed files with 271 additions and 2439 deletions

View file

@ -1,12 +1,10 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/descriptor.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
#include "usbstor.h" #include "usbstor.h"
@ -14,6 +12,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
NTSTATUS NTSTATUS
NTAPI NTAPI
USBSTOR_GetDescriptor( USBSTOR_GetDescriptor(
@ -28,41 +27,27 @@ USBSTOR_GetDescriptor(
NTSTATUS Status; NTSTATUS Status;
PVOID Descriptor; PVOID Descriptor;
//
// sanity checks
//
ASSERT(DeviceObject); ASSERT(DeviceObject);
ASSERT(OutDescriptor); ASSERT(OutDescriptor);
ASSERT(DescriptorLength); ASSERT(DescriptorLength);
//
// first allocate descriptor buffer // first allocate descriptor buffer
//
Descriptor = AllocateItem(NonPagedPool, DescriptorLength); Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
if (!Descriptor) if (!Descriptor)
{ {
//
// no memory // no memory
//
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// allocate urb
//
Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB)); Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
if (!Urb) if (!Urb)
{ {
//
// no memory // no memory
//
FreeItem(Descriptor); FreeItem(Descriptor);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// initialize urb // initialize urb
//
UsbBuildGetDescriptorRequest(Urb, UsbBuildGetDescriptorRequest(Urb,
sizeof(Urb->UrbControlDescriptorRequest), sizeof(Urb->UrbControlDescriptorRequest),
DescriptorType, DescriptorType,
@ -73,31 +58,19 @@ USBSTOR_GetDescriptor(
DescriptorLength, DescriptorLength,
NULL); NULL);
//
// submit urb // submit urb
//
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
//
// free urb
//
FreeItem(Urb); FreeItem(Urb);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
//
// store result
//
*OutDescriptor = Descriptor; *OutDescriptor = Descriptor;
} }
//
// done
//
return Status; return Status;
} }
NTSTATUS NTSTATUS
USBSTOR_GetDescriptors( USBSTOR_GetDescriptors(
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
@ -106,89 +79,54 @@ USBSTOR_GetDescriptors(
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
USHORT DescriptorLength; USHORT DescriptorLength;
//
// get device extension
//
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// first get device descriptor // first get device descriptor
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor); Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get device descriptor
//
DeviceExtension->DeviceDescriptor = NULL; DeviceExtension->DeviceDescriptor = NULL;
return Status; return Status;
} }
//
// now get basic configuration descriptor // now get basic configuration descriptor
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor); Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get configuration descriptor
//
FreeItem(DeviceExtension->DeviceDescriptor); FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL; DeviceExtension->DeviceDescriptor = NULL;
return Status; return Status;
} }
//
// backup length // backup length
//
DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength; DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
//
// release basic descriptor // release basic descriptor
//
FreeItem(DeviceExtension->ConfigurationDescriptor); FreeItem(DeviceExtension->ConfigurationDescriptor);
DeviceExtension->ConfigurationDescriptor = NULL; DeviceExtension->ConfigurationDescriptor = NULL;
//
// allocate full descriptor // allocate full descriptor
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor); Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get configuration descriptor
//
FreeItem(DeviceExtension->DeviceDescriptor); FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL; DeviceExtension->DeviceDescriptor = NULL;
return Status; return Status;
} }
//
// check if there is a serial number provided // check if there is a serial number provided
//
if (DeviceExtension->DeviceDescriptor->iSerialNumber) if (DeviceExtension->DeviceDescriptor->iSerialNumber)
{ {
//
// get serial number // get serial number
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber); Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get serial number descriptor, free device descriptor
//
FreeItem(DeviceExtension->DeviceDescriptor); FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL; DeviceExtension->DeviceDescriptor = NULL;
//
// free configuration descriptor
//
FreeItem(DeviceExtension->ConfigurationDescriptor); FreeItem(DeviceExtension->ConfigurationDescriptor);
DeviceExtension->ConfigurationDescriptor = NULL; DeviceExtension->ConfigurationDescriptor = NULL;
//
// set serial number to zero
//
DeviceExtension->SerialNumber = NULL; DeviceExtension->SerialNumber = NULL;
return Status; return Status;
} }
@ -201,133 +139,80 @@ NTSTATUS
NTAPI NTAPI
USBSTOR_ScanConfigurationDescriptor( USBSTOR_ScanConfigurationDescriptor(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
OUT PUSB_INTERFACE_DESCRIPTOR * OutInterfaceDescriptor, OUT PUSB_INTERFACE_DESCRIPTOR *OutInterfaceDescriptor,
OUT PUSB_ENDPOINT_DESCRIPTOR * InEndpointDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR *InEndpointDescriptor,
OUT PUSB_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor) OUT PUSB_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor)
{ {
PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor; PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor;
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor; PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
//
// sanity checks
//
ASSERT(ConfigurationDescriptor); ASSERT(ConfigurationDescriptor);
ASSERT(OutInterfaceDescriptor); ASSERT(OutInterfaceDescriptor);
ASSERT(InEndpointDescriptor); ASSERT(InEndpointDescriptor);
ASSERT(OutEndpointDescriptor); ASSERT(OutEndpointDescriptor);
//
// nullify pointers
//
*OutInterfaceDescriptor = NULL; *OutInterfaceDescriptor = NULL;
*InEndpointDescriptor = NULL; *InEndpointDescriptor = NULL;
*OutEndpointDescriptor = NULL; *OutEndpointDescriptor = NULL;
//
// start scanning // start scanning
//
CurrentDescriptor = ConfigurationDescriptor; CurrentDescriptor = ConfigurationDescriptor;
do do
{ {
//
// check current descriptor type
//
if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{ {
//
// found interface descriptor
//
if (*OutInterfaceDescriptor) if (*OutInterfaceDescriptor)
{ {
//
// we only process the first interface descriptor as ms does -> see documentation // we only process the first interface descriptor as ms does -> see documentation
//
break; break;
} }
//
// store interface descriptor // store interface descriptor
//
*OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor; *OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor;
} }
else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{ {
//
// convert to endpoint descriptor
//
EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor; EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor;
//
// sanity check
//
ASSERT(*OutInterfaceDescriptor); ASSERT(*OutInterfaceDescriptor);
//
// get endpoint type // get endpoint type
//
if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK)
{ {
// if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress))
// bulk endpoint type {
// *InEndpointDescriptor = EndpointDescriptor;
if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress)) }
{ else
// {
// bulk in *OutEndpointDescriptor = EndpointDescriptor;
// }
*InEndpointDescriptor = EndpointDescriptor;
}
else
{
//
// bulk out
//
*OutEndpointDescriptor = EndpointDescriptor;
}
} }
else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT) else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT)
{ {
// UNIMPLEMENTED;
// interrupt endpoint type
//
UNIMPLEMENTED;
} }
} }
//
// move to next descriptor // move to next descriptor
//
CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength); CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength);
//
// was it the last descriptor // was it the last descriptor
//
if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
{ {
//
// reached last descriptor
//
break; break;
} }
}while(TRUE); } while(TRUE);
//
// check if everything has been found // check if everything has been found
//
if (*OutInterfaceDescriptor == NULL || *InEndpointDescriptor == NULL || *OutEndpointDescriptor == NULL) if (*OutInterfaceDescriptor == NULL || *InEndpointDescriptor == NULL || *OutEndpointDescriptor == NULL)
{ {
//
// failed to find interface / endpoint descriptor
//
DPRINT1("USBSTOR_ScanConfigurationDescriptor: Failed to find InterfaceDescriptor %p InEndpointDescriptor %p OutEndpointDescriptor %p\n", *OutInterfaceDescriptor, *InEndpointDescriptor, *OutEndpointDescriptor); DPRINT1("USBSTOR_ScanConfigurationDescriptor: Failed to find InterfaceDescriptor %p InEndpointDescriptor %p OutEndpointDescriptor %p\n", *OutInterfaceDescriptor, *InEndpointDescriptor, *OutEndpointDescriptor);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
//
// completed successfully
//
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -356,128 +241,77 @@ USBSTOR_SelectConfigurationAndInterface(
PURB Urb; PURB Urb;
PUSBD_INTERFACE_LIST_ENTRY InterfaceList; PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
//
// now scan configuration descriptors
//
Status = USBSTOR_ScanConfigurationDescriptor(DeviceExtension->ConfigurationDescriptor, &InterfaceDescriptor, &InEndpointDescriptor, &OutEndpointDescriptor); Status = USBSTOR_ScanConfigurationDescriptor(DeviceExtension->ConfigurationDescriptor, &InterfaceDescriptor, &InEndpointDescriptor, &OutEndpointDescriptor);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to scan
//
return Status; return Status;
} }
//
// now allocate one interface entry and terminating null entry // now allocate one interface entry and terminating null entry
//
InterfaceList = (PUSBD_INTERFACE_LIST_ENTRY)AllocateItem(PagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * 2); InterfaceList = (PUSBD_INTERFACE_LIST_ENTRY)AllocateItem(PagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * 2);
if (!InterfaceList) if (!InterfaceList)
{ {
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// initialize interface list entry // initialize interface list entry
//
InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor; InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
//
// now allocate the urb // now allocate the urb
//
Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, InterfaceList); Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, InterfaceList);
if (!Urb) if (!Urb)
{ {
//
// no memory
//
FreeItem(InterfaceList); FreeItem(InterfaceList);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// sanity check
//
ASSERT(InterfaceList[0].Interface); ASSERT(InterfaceList[0].Interface);
//
// submit urb // submit urb
//
Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to set configuration // failed to set configuration
//
DPRINT1("USBSTOR_SelectConfiguration failed to set interface %x\n", Status); DPRINT1("USBSTOR_SelectConfiguration failed to set interface %x\n", Status);
FreeItem(InterfaceList); FreeItem(InterfaceList);
ExFreePoolWithTag(Urb, 0); ExFreePoolWithTag(Urb, 0);
return Status; return Status;
} }
//
// backup interface information // backup interface information
//
DeviceExtension->InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)AllocateItem(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length); DeviceExtension->InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)AllocateItem(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length);
if (!DeviceExtension->InterfaceInformation) if (!DeviceExtension->InterfaceInformation)
{ {
//
// failed to allocate interface information structure
//
FreeItem(InterfaceList); FreeItem(InterfaceList);
ExFreePoolWithTag(Urb, 0); ExFreePoolWithTag(Urb, 0);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// copy interface information // copy interface information
//
RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length); RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
//
// store pipe handle // store pipe handle
//
DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle; DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
//
// now prepare interface urb // now prepare interface urb
//
UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting); UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
//
// copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ // copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
//
RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInformation, DeviceExtension->InterfaceInformation->Length); RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInformation, DeviceExtension->InterfaceInformation->Length);
//
// now select the interface // now select the interface
//
Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
//
// did it succeed
//
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
//
// update configuration info // update configuration info
//
ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInformation->Length); ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInformation->Length);
RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length); RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
} }
//
// free interface list & urb
//
FreeItem(InterfaceList); FreeItem(InterfaceList);
ExFreePoolWithTag(Urb, 0); ExFreePoolWithTag(Urb, 0);
//
// done
//
return Status; return Status;
} }
@ -488,62 +322,36 @@ USBSTOR_GetPipeHandles(
ULONG Index; ULONG Index;
BOOLEAN BulkInFound = FALSE, BulkOutFound = FALSE; BOOLEAN BulkInFound = FALSE, BulkOutFound = FALSE;
// // enumerate all pipes and extract bulk-in / bulk-out pipe handle
// no enumerate all pipes and extract bulk-in / bulk-out pipe handle for (Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++)
//
for(Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++)
{ {
//
// check pipe type
//
if (DeviceExtension->InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeBulk) if (DeviceExtension->InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeBulk)
{ {
//
// check direction
//
if (USB_ENDPOINT_DIRECTION_IN(DeviceExtension->InterfaceInformation->Pipes[Index].EndpointAddress)) if (USB_ENDPOINT_DIRECTION_IN(DeviceExtension->InterfaceInformation->Pipes[Index].EndpointAddress))
{ {
//
// bulk in pipe
//
DeviceExtension->BulkInPipeIndex = Index; DeviceExtension->BulkInPipeIndex = Index;
//
// there should not be another bulk in pipe // there should not be another bulk in pipe
//
ASSERT(BulkInFound == FALSE); ASSERT(BulkInFound == FALSE);
BulkInFound = TRUE; BulkInFound = TRUE;
} }
else else
{ {
//
// bulk out pipe
//
DeviceExtension->BulkOutPipeIndex = Index; DeviceExtension->BulkOutPipeIndex = Index;
//
// there should not be another bulk out pipe // there should not be another bulk out pipe
//
ASSERT(BulkOutFound == FALSE); ASSERT(BulkOutFound == FALSE);
BulkOutFound = TRUE; BulkOutFound = TRUE;
} }
} }
} }
//
// check if both bulk pipes have been found
//
if (!BulkInFound || !BulkOutFound) if (!BulkInFound || !BulkOutFound)
{ {
//
// WTF? usb port driver does not give us bulk pipe access // WTF? usb port driver does not give us bulk pipe access
//
DPRINT1("USBSTOR_GetPipeHandles> BulkInFound %c BulkOutFound %c missing!!!\n", BulkInFound, BulkOutFound); DPRINT1("USBSTOR_GetPipeHandles> BulkInFound %c BulkOutFound %c missing!!!\n", BulkInFound, BulkOutFound);
return STATUS_DEVICE_CONFIGURATION_ERROR; return STATUS_DEVICE_CONFIGURATION_ERROR;
} }
//
// device is configured
//
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -1,12 +1,10 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/disk.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
#include "usbstor.h" #include "usbstor.h"
@ -14,6 +12,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
NTSTATUS NTSTATUS
USBSTOR_HandleInternalDeviceControl( USBSTOR_HandleInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -24,29 +23,10 @@ USBSTOR_HandleInternalDeviceControl(
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
NTSTATUS Status; NTSTATUS Status;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get request block
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// sanity check
//
ASSERT(Request); ASSERT(Request);
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
switch(Request->Function) switch(Request->Function)
@ -55,69 +35,42 @@ USBSTOR_HandleInternalDeviceControl(
{ {
DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n"); DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");
//
// check if request is valid // check if request is valid
//
if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
{ {
//
// data is transferred with this irp // data is transferred with this irp
//
if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) || if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) ||
Request->DataTransferLength == 0 || Request->DataTransferLength == 0 ||
Irp->MdlAddress == NULL) Irp->MdlAddress == NULL)
{ {
//
// invalid parameter
//
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
break; break;
} }
} }
else else
{ {
//
// sense buffer request // sense buffer request
// if (Request->DataTransferLength || Request->DataBuffer || Irp->MdlAddress)
if (Request->DataTransferLength ||
Request->DataBuffer ||
Irp->MdlAddress)
{ {
//
// invalid parameter
//
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
break; break;
} }
} }
//
// add the request // add the request
//
if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp)) if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp))
{ {
//
// irp was not added to the queue
//
IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo); IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
} }
//
// irp pending
//
return STATUS_PENDING; return STATUS_PENDING;
} }
case SRB_FUNCTION_RELEASE_DEVICE: case SRB_FUNCTION_RELEASE_DEVICE:
{ {
DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n"); DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n");
//
// sanity check
//
ASSERT(PDODeviceExtension->Claimed == TRUE); ASSERT(PDODeviceExtension->Claimed == TRUE);
//
// release claim // release claim
//
PDODeviceExtension->Claimed = FALSE; PDODeviceExtension->Claimed = FALSE;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
@ -125,32 +78,22 @@ USBSTOR_HandleInternalDeviceControl(
case SRB_FUNCTION_CLAIM_DEVICE: case SRB_FUNCTION_CLAIM_DEVICE:
{ {
DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n"); DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n");
//
// check if the device has been claimed // check if the device has been claimed
//
if (PDODeviceExtension->Claimed) if (PDODeviceExtension->Claimed)
{ {
//
// device has already been claimed // device has already been claimed
//
Status = STATUS_DEVICE_BUSY; Status = STATUS_DEVICE_BUSY;
Request->SrbStatus = SRB_STATUS_BUSY; Request->SrbStatus = SRB_STATUS_BUSY;
break; break;
} }
//
// claim device // claim device
//
PDODeviceExtension->Claimed = TRUE; PDODeviceExtension->Claimed = TRUE;
//
// output device object // output device object
//
Request->DataBuffer = DeviceObject; Request->DataBuffer = DeviceObject;
//
// completed successfully
//
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
} }
@ -158,14 +101,8 @@ USBSTOR_HandleInternalDeviceControl(
{ {
DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n"); DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n");
//
// release queue
//
USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject); USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject);
//
// set status success
//
Request->SrbStatus = SRB_STATUS_SUCCESS; Request->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
@ -184,9 +121,7 @@ USBSTOR_HandleInternalDeviceControl(
// //
USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject); USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
#endif #endif
//
// set status success
//
Request->SrbStatus = SRB_STATUS_SUCCESS; Request->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
@ -201,9 +136,6 @@ USBSTOR_HandleInternalDeviceControl(
} }
} }
//
// complete request
//
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
@ -217,23 +149,17 @@ USBSTOR_GetFieldLength(
ULONG Index; ULONG Index;
ULONG LastCharacterPosition = 0; ULONG LastCharacterPosition = 0;
//
// scan the field and return last position which contains a valid character // scan the field and return last position which contains a valid character
//
for(Index = 0; Index < MaxLength; Index++) for(Index = 0; Index < MaxLength; Index++)
{ {
if (Name[Index] != ' ') if (Name[Index] != ' ')
{ {
//
// trim white spaces from field // trim white spaces from field
//
LastCharacterPosition = Index; LastCharacterPosition = Index;
} }
} }
//
// convert from zero based index to length // convert from zero based index to length
//
return LastCharacterPosition + 1; return LastCharacterPosition + 1;
} }
@ -258,125 +184,75 @@ USBSTOR_HandleQueryProperty(
DPRINT("USBSTOR_HandleQueryProperty\n"); DPRINT("USBSTOR_HandleQueryProperty\n");
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// sanity check
//
ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY)); ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
ASSERT(Irp->AssociatedIrp.SystemBuffer); ASSERT(Irp->AssociatedIrp.SystemBuffer);
//
// get property query
//
PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer; PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
//
// check property type // check property type
//
if (PropertyQuery->PropertyId != StorageDeviceProperty && if (PropertyQuery->PropertyId != StorageDeviceProperty &&
PropertyQuery->PropertyId != StorageAdapterProperty) PropertyQuery->PropertyId != StorageAdapterProperty)
{ {
//
// only device property / adapter property are supported // only device property / adapter property are supported
//
return STATUS_INVALID_PARAMETER_1; return STATUS_INVALID_PARAMETER_1;
} }
//
// check query type // check query type
//
if (PropertyQuery->QueryType == PropertyExistsQuery) if (PropertyQuery->QueryType == PropertyExistsQuery)
{ {
//
// device property / adapter property is supported // device property / adapter property is supported
//
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
if (PropertyQuery->QueryType != PropertyStandardQuery) if (PropertyQuery->QueryType != PropertyStandardQuery)
{ {
//
// only standard query and exists query are supported // only standard query and exists query are supported
//
return STATUS_INVALID_PARAMETER_2; return STATUS_INVALID_PARAMETER_2;
} }
//
// check if it is a device property // check if it is a device property
//
if (PropertyQuery->PropertyId == StorageDeviceProperty) if (PropertyQuery->PropertyId == StorageDeviceProperty)
{ {
DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength); DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension); ASSERT(PDODeviceExtension);
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
//
// get device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
ASSERT(FDODeviceExtension); ASSERT(FDODeviceExtension);
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// get inquiry data
//
InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
ASSERT(InquiryData); ASSERT(InquiryData);
//
// compute extra parameters length // compute extra parameters length
//
FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8); FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8);
FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16); FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16);
FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4); FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
//
// is there a serial number
//
if (FDODeviceExtension->SerialNumber) if (FDODeviceExtension->SerialNumber)
{ {
//
// get length
//
FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString); FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
} }
else else
{ {
//
// no serial number
//
FieldLengthSerialNumber = 0; FieldLengthSerialNumber = 0;
} }
//
// total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1 // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
// -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
//
TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3; TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
//
// check if output buffer is long enough // check if output buffer is long enough
//
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
{ {
//
// buffer too small // buffer too small
//
DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer; DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER)); ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
//
// return required size // return required size
//
DescriptorHeader->Version = TotalLength; DescriptorHeader->Version = TotalLength;
DescriptorHeader->Size = TotalLength; DescriptorHeader->Size = TotalLength;
@ -384,14 +260,9 @@ USBSTOR_HandleQueryProperty(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
// // initialize the device descriptor
// get device descriptor
//
DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer; DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
//
// initialize device descriptor
//
DeviceDescriptor->Version = TotalLength; DeviceDescriptor->Version = TotalLength;
DeviceDescriptor->Size = TotalLength; DeviceDescriptor->Size = TotalLength;
DeviceDescriptor->DeviceType = InquiryData->DeviceType; DeviceDescriptor->DeviceType = InquiryData->DeviceType;
@ -405,86 +276,54 @@ USBSTOR_HandleQueryProperty(
DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0); DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0); DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
//
// copy descriptors // copy descriptors
//
Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR)); Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
//
// copy vendor
//
RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor); RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor);
Buffer[FieldLengthVendor] = '\0'; Buffer[FieldLengthVendor] = '\0';
Buffer += FieldLengthVendor + 1; Buffer += FieldLengthVendor + 1;
//
// copy product
//
RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct); RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct);
Buffer[FieldLengthProduct] = '\0'; Buffer[FieldLengthProduct] = '\0';
Buffer += FieldLengthProduct + 1; Buffer += FieldLengthProduct + 1;
//
// copy revision
//
RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision); RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision);
Buffer[FieldLengthRevision] = '\0'; Buffer[FieldLengthRevision] = '\0';
Buffer += FieldLengthRevision + 1; Buffer += FieldLengthRevision + 1;
//
// copy serial number
//
if (FieldLengthSerialNumber) if (FieldLengthSerialNumber)
{ {
//
// init unicode string
//
RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString); RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
//
// init ansi string
//
AnsiString.Buffer = (PCHAR)Buffer; AnsiString.Buffer = (PCHAR)Buffer;
AnsiString.Length = 0; AnsiString.Length = 0;
AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR); AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
//
// convert to ansi code
//
Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE); Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
ASSERT(Status == STATUS_SUCCESS); ASSERT(Status == STATUS_SUCCESS);
} }
DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset)); DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset)); DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset)); DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset)); DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
//
// done
//
Irp->IoStatus.Information = TotalLength; Irp->IoStatus.Information = TotalLength;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else else
{ {
//
// adapter property query request // adapter property query request
//
DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength); DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR)) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
{ {
//
// buffer too small // buffer too small
//
DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer; DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER)); ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
//
// return required size // return required size
//
DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
@ -492,14 +331,10 @@ USBSTOR_HandleQueryProperty(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
//
// get adapter descriptor, information is returned in the same buffer // get adapter descriptor, information is returned in the same buffer
//
AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer; AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
//
// fill out descriptor // fill out descriptor
//
AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value
@ -513,14 +348,9 @@ USBSTOR_HandleQueryProperty(
AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
AdapterDescriptor->BusMinorVersion = 0x00; //FIXME AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
//
// store returned length // store returned length
//
Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR); Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
//
// done
//
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -538,153 +368,130 @@ USBSTOR_HandleDeviceControl(
PINQUIRYDATA ScsiInquiryData; PINQUIRYDATA ScsiInquiryData;
PUFI_INQUIRY_RESPONSE UFIInquiryResponse; PUFI_INQUIRY_RESPONSE UFIInquiryResponse;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY) switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
{ {
// case IOCTL_STORAGE_QUERY_PROPERTY:
// query property Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
// break;
Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp); case IOCTL_SCSI_PASS_THROUGH:
} DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH) Status = STATUS_NOT_SUPPORTED;
{ break;
// case IOCTL_SCSI_PASS_THROUGH_DIRECT:
// query scsi pass through DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
// Status = STATUS_NOT_SUPPORTED;
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n"); break;
Status = STATUS_NOT_SUPPORTED; case IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER:
} DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) Status = STATUS_NOT_SUPPORTED;
{ break;
// case IOCTL_SCSI_GET_CAPABILITIES:
// query scsi pass through direct {
// PIO_SCSI_CAPABILITIES Capabilities;
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
Status = STATUS_NOT_SUPPORTED;
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
{
//
// query serial number
//
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
Status = STATUS_NOT_SUPPORTED;
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_CAPABILITIES)
{
PIO_SCSI_CAPABILITIES Capabilities;
/* Legacy port capability query */ // Legacy port capability query
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID)) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
{ {
Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool, Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
sizeof(IO_SCSI_CAPABILITIES), sizeof(IO_SCSI_CAPABILITIES),
USB_STOR_TAG); USB_STOR_TAG);
Irp->IoStatus.Information = sizeof(PVOID); Irp->IoStatus.Information = sizeof(PVOID);
} }
else else
{ {
Capabilities = Irp->AssociatedIrp.SystemBuffer; Capabilities = Irp->AssociatedIrp.SystemBuffer;
Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES); Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
} }
if (Capabilities) if (Capabilities)
{
Capabilities->MaximumTransferLength = MAXULONG;
Capabilities->MaximumPhysicalPages = 25;
Capabilities->SupportedAsynchronousEvents = 0;
Capabilities->AlignmentMask = 0;
Capabilities->TaggedQueuing = FALSE;
Capabilities->AdapterScansDown = FALSE;
Capabilities->AdapterUsesPio = FALSE;
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
break;
}
case IOCTL_SCSI_GET_INQUIRY_DATA:
{ {
Capabilities->MaximumTransferLength = MAXULONG; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
Capabilities->MaximumPhysicalPages = 25; ASSERT(PDODeviceExtension);
Capabilities->SupportedAsynchronousEvents = 0; ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
Capabilities->AlignmentMask = 0;
Capabilities->TaggedQueuing = FALSE; // get parameters
Capabilities->AdapterScansDown = FALSE; BusInfo = Irp->AssociatedIrp.SystemBuffer;
Capabilities->AdapterUsesPio = FALSE; InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData;
UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
ASSERT(UFIInquiryResponse);
BusInfo->NumberOfBuses = 1;
BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
BusInfo->BusData[0].InitiatorBusId = 0;
BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
InquiryData->PathId = 0;
InquiryData->TargetId = 0;
InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
InquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
InquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
InquiryData->NextInquiryDataOffset = 0;
RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA));
ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType;
ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F);
// Hack for IoReadPartitionTable call in disk.sys
ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0);
ScsiInquiryData->Versions = 0x04;
ScsiInquiryData->ResponseDataFormat = 0x02;
ScsiInquiryData->AdditionalLength = 31;
ScsiInquiryData->SoftReset = 0;
ScsiInquiryData->CommandQueue = 0;
ScsiInquiryData->LinkedCommands = 0;
ScsiInquiryData->RelativeAddressing = 0;
RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8));
RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16));
Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break;
} }
else case IOCTL_SCSI_GET_ADDRESS:
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
Address->Length = sizeof(SCSI_ADDRESS);
Address->PortNumber = 0;
Address->PathId = 0;
Address->TargetId = 0;
Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
Status = STATUS_SUCCESS;
break;
} }
} default:
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_INQUIRY_DATA) DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
{ Status = STATUS_NOT_SUPPORTED;
// break;
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension);
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
//
// get parameters
//
BusInfo = Irp->AssociatedIrp.SystemBuffer;
InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1);
ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData;
//
// get inquiry data
//
UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
ASSERT(UFIInquiryResponse);
BusInfo->NumberOfBuses = 1;
BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME
BusInfo->BusData[0].InitiatorBusId = 0;
BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
InquiryData->PathId = 0;
InquiryData->TargetId = 0;
InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN;
InquiryData->DeviceClaimed = PDODeviceExtension->Claimed;
InquiryData->InquiryDataLength = sizeof(INQUIRYDATA);
InquiryData->NextInquiryDataOffset = 0;
RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA));
ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType;
ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F);
/* Hack for IoReadPartitionTable call in disk.sys */
ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0);
ScsiInquiryData->Versions = 0x04;
ScsiInquiryData->ResponseDataFormat = 0x02;
ScsiInquiryData->AdditionalLength = 31;
ScsiInquiryData->SoftReset = 0;
ScsiInquiryData->CommandQueue = 0;
ScsiInquiryData->LinkedCommands = 0;
ScsiInquiryData->RelativeAddressing = 0;
RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8));
RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16));
Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1;
Status = STATUS_SUCCESS;
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS)
{
PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
Address->Length = sizeof(SCSI_ADDRESS);
Address->PortNumber = 0;
Address->PathId = 0;
Address->TargetId = 0;
Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN);
Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
Status = STATUS_SUCCESS;
}
else
{
//
// unsupported
//
DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
Status = STATUS_NOT_SUPPORTED;
} }
return Status; return Status;

View file

@ -1,12 +1,10 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/error.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
#include "usbstor.h" #include "usbstor.h"
@ -14,6 +12,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
NTSTATUS NTSTATUS
USBSTOR_GetEndpointStatus( USBSTOR_GetEndpointStatus(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -23,44 +22,25 @@ USBSTOR_GetEndpointStatus(
PURB Urb; PURB Urb;
NTSTATUS Status; NTSTATUS Status;
//
// allocate urb
//
DPRINT("Allocating URB\n"); DPRINT("Allocating URB\n");
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if (!Urb) if (!Urb)
{ {
//
// out of memory
//
DPRINT1("OutofMemory!\n"); DPRINT1("OutofMemory!\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// build status // build status
// UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL);
UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL);
//
// send the request // send the request
//
DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb); DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
//
// free urb
//
FreeItem(Urb); FreeItem(Urb);
//
// done
//
return Status; return Status;
} }
NTSTATUS NTSTATUS
USBSTOR_ResetPipeWithHandle( USBSTOR_ResetPipeWithHandle(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -69,45 +49,26 @@ USBSTOR_ResetPipeWithHandle(
PURB Urb; PURB Urb;
NTSTATUS Status; NTSTATUS Status;
//
// allocate urb
//
DPRINT("Allocating URB\n"); DPRINT("Allocating URB\n");
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
if (!Urb) if (!Urb)
{ {
//
// out of memory
//
DPRINT1("OutofMemory!\n"); DPRINT1("OutofMemory!\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// initialize the urb
//
Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST); Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
Urb->UrbPipeRequest.Hdr.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL; Urb->UrbPipeRequest.Hdr.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL;
Urb->UrbPipeRequest.PipeHandle = PipeHandle; Urb->UrbPipeRequest.PipeHandle = PipeHandle;
//
// send the request // send the request
//
DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb); DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
//
// free urb
//
FreeItem(Urb); FreeItem(Urb);
//
// done
//
return Status; return Status;
} }
NTSTATUS NTSTATUS
USBSTOR_HandleTransferError( USBSTOR_HandleTransferError(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
@ -118,107 +79,70 @@ USBSTOR_HandleTransferError(
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PCDB pCDB; PCDB pCDB;
//
// sanity checks
//
ASSERT(Context); ASSERT(Context);
ASSERT(Context->PDODeviceExtension); ASSERT(Context->PDODeviceExtension);
ASSERT(Context->PDODeviceExtension->Self); ASSERT(Context->PDODeviceExtension->Self);
ASSERT(Context->Irp); ASSERT(Context->Irp);
//
// first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
//
Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension); Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
//
// step 2 reset bulk in pipe section 5.3.4 // step 2 reset bulk in pipe section 5.3.4
//
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle); Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
//
// finally reset bulk out pipe // finally reset bulk out pipe
//
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle); Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
} }
} }
//
// get next stack location
//
Stack = IoGetCurrentIrpStackLocation(Context->Irp); Stack = IoGetCurrentIrpStackLocation(Context->Irp);
//
// get request block
//
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1; Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
ASSERT(Request); ASSERT(Request);
//
// obtain request type // obtain request type
//
pCDB = (PCDB)Request->Cdb; pCDB = (PCDB)Request->Cdb;
ASSERT(pCDB); ASSERT(pCDB);
if (Status != STATUS_SUCCESS || Context->RetryCount >= 1) if (Status != STATUS_SUCCESS || Context->RetryCount >= 1)
{ {
//
// Complete the master IRP // Complete the master IRP
//
Context->Irp->IoStatus.Status = Status; Context->Irp->IoStatus.Status = Status;
Context->Irp->IoStatus.Information = 0; Context->Irp->IoStatus.Information = 0;
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp); USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT); IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
//
// Start the next request // Start the next request
//
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject); USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
//
// srb handling finished // srb handling finished
//
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE; Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
//
// clear timer srb // clear timer srb
//
Context->FDODeviceExtension->LastTimerActiveSrb = NULL; Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
} }
else else
{ {
DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self); DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self);
//
// re-schedule request // re-schedule request
//
USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1); USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1);
//
// srb error handling finished // srb error handling finished
//
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE; Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
//
// srb error handling finished // srb error handling finished
//
Context->FDODeviceExtension->TimerWorkQueueEnabled = TRUE; Context->FDODeviceExtension->TimerWorkQueueEnabled = TRUE;
//
// clear timer srb // clear timer srb
//
Context->FDODeviceExtension->LastTimerActiveSrb = NULL; Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
} }
//
// cleanup irp context
//
FreeItem(Context->cbw); FreeItem(Context->cbw);
FreeItem(Context); FreeItem(Context);
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status); DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
return Status; return Status;
} }
@ -231,15 +155,11 @@ USBSTOR_ResetHandlerWorkItemRoutine(
NTSTATUS Status; NTSTATUS Status;
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
//
// clear stall on BulkIn pipe // clear stall on BulkIn pipe
//
Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle); Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status); DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
//
// now resend the csw as the stall got cleared // now resend the csw as the stall got cleared
//
USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp); USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp);
} }
@ -252,22 +172,16 @@ ErrorHandlerWorkItemRoutine(
if (WorkItemData->Context->ErrorIndex == 2) if (WorkItemData->Context->ErrorIndex == 2)
{ {
//
// reset device // reset device
//
USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context); USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
} }
else else
{ {
//
// clear stall // clear stall
//
USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData); USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData);
} }
//
// Free Work Item Data // Free Work Item Data
//
ExFreePoolWithTag(WorkItemData, USB_STOR_TAG); ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
} }
@ -280,56 +194,35 @@ USBSTOR_TimerWorkerRoutine(
NTSTATUS Status; NTSTATUS Status;
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
//
// get device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension;
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
//
Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension); Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
//
// step 2 reset bulk in pipe section 5.3.4 // step 2 reset bulk in pipe section 5.3.4
//
Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle); Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
//
// finally reset bulk out pipe // finally reset bulk out pipe
//
Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle); Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
} }
} }
DPRINT1("Status %x\n", Status); DPRINT1("Status %x\n", Status);
//
// clear timer srb // clear timer srb
//
FDODeviceExtension->LastTimerActiveSrb = NULL; FDODeviceExtension->LastTimerActiveSrb = NULL;
//
// re-schedule request // re-schedule request
//
//USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1); //USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1);
//
// do not retry for the same packet again // do not retry for the same packet again
//
FDODeviceExtension->TimerWorkQueueEnabled = FALSE; FDODeviceExtension->TimerWorkQueueEnabled = FALSE;
//
// Free Work Item Data
//
ExFreePoolWithTag(WorkItemData, USB_STOR_TAG); ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
} }
VOID VOID
NTAPI NTAPI
USBSTOR_TimerRoutine( USBSTOR_TimerRoutine(
@ -340,50 +233,33 @@ USBSTOR_TimerRoutine(
BOOLEAN ResetDevice = FALSE; BOOLEAN ResetDevice = FALSE;
PERRORHANDLER_WORKITEM_DATA WorkItemData; PERRORHANDLER_WORKITEM_DATA WorkItemData;
//
// get device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
DPRINT1("[USBSTOR] TimerRoutine entered\n"); DPRINT1("[USBSTOR] TimerRoutine entered\n");
DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb); DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb);
//
// acquire spinlock
//
KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock); KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
//
// is there an active srb and no global reset is in progress // is there an active srb and no global reset is in progress
//
if (FDODeviceExtension->ActiveSrb && FDODeviceExtension->ResetInProgress == FALSE && FDODeviceExtension->TimerWorkQueueEnabled) if (FDODeviceExtension->ActiveSrb && FDODeviceExtension->ResetInProgress == FALSE && FDODeviceExtension->TimerWorkQueueEnabled)
{ {
if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb) if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb)
{ {
//
// check if empty // check if empty
//
DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb); DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb);
ResetDevice = TRUE; ResetDevice = TRUE;
} }
else else
{ {
//
// update pointer // update pointer
//
FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb; FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb;
} }
} }
else else
{ {
//
// reset srb // reset srb
//
FDODeviceExtension->LastTimerActiveSrb = NULL; FDODeviceExtension->LastTimerActiveSrb = NULL;
} }
//
// release lock
//
KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock); KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
@ -394,9 +270,7 @@ USBSTOR_TimerRoutine(
USB_STOR_TAG); USB_STOR_TAG);
if (WorkItemData) if (WorkItemData)
{ {
//
// Initialize and queue the work item to handle the error // Initialize and queue the work item to handle the error
//
ExInitializeWorkItem(&WorkItemData->WorkQueueItem, ExInitializeWorkItem(&WorkItemData->WorkQueueItem,
USBSTOR_TimerWorkerRoutine, USBSTOR_TimerWorkerRoutine,
WorkItemData); WorkItemData);

View file

@ -1,12 +1,10 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/fdo.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
#include "usbstor.h" #include "usbstor.h"
@ -14,6 +12,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
VOID VOID
USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
{ {
@ -44,80 +43,47 @@ USBSTOR_FdoHandleDeviceRelations(
PDEVICE_RELATIONS DeviceRelations; PDEVICE_RELATIONS DeviceRelations;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// check if relation type is BusRelations // check if relation type is BusRelations
//
if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations) if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
{ {
//
// FDO always only handles bus relations // FDO always only handles bus relations
//
return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
} }
//
// go through array and count device objects // go through array and count device objects
//
for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
{ {
if (DeviceExtension->ChildPDO[Index]) if (DeviceExtension->ChildPDO[Index])
{ {
//
// child pdo
//
DeviceCount++; DeviceCount++;
} }
} }
//
// allocate device relations
//
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0)); DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
if (!DeviceRelations) if (!DeviceRelations)
{ {
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// add device objects // add device objects
// for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
{ {
if (DeviceExtension->ChildPDO[Index]) if (DeviceExtension->ChildPDO[Index])
{ {
//
// store child pdo // store child pdo
//
DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index]; DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index];
//
// add reference // add reference
//
ObReferenceObject(DeviceExtension->ChildPDO[Index]); ObReferenceObject(DeviceExtension->ChildPDO[Index]);
//
// increment count
//
DeviceRelations->Count++; DeviceRelations->Count++;
} }
} }
//
// store result
//
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
//
// request completed successfully
//
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -132,8 +98,8 @@ USBSTOR_FdoHandleRemoveDevice(
DPRINT("Handling FDO removal %p\n", DeviceObject); DPRINT("Handling FDO removal %p\n", DeviceObject);
/* FIXME: wait for devices finished processing */ // FIXME: wait for devices finished processing
for(Index = 0; Index < 16; Index++) for (Index = 0; Index < 16; Index++)
{ {
if (DeviceExtension->ChildPDO[Index] != NULL) if (DeviceExtension->ChildPDO[Index] != NULL)
{ {
@ -142,14 +108,13 @@ USBSTOR_FdoHandleRemoveDevice(
} }
} }
/* Send the IRP down the stack */ // Send the IRP down the stack
IoSkipCurrentIrpStackLocation(Irp); IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
/* Detach from the device stack */ // Detach from the device stack
IoDetachDevice(DeviceExtension->LowerDeviceObject); IoDetachDevice(DeviceExtension->LowerDeviceObject);
/* Delete the device object */
IoDeleteDevice(DeviceObject); IoDeleteDevice(DeviceObject);
return Status; return Status;
@ -165,50 +130,31 @@ USBSTOR_FdoHandleStartDevice(
NTSTATUS Status; NTSTATUS Status;
UCHAR Index = 0; UCHAR Index = 0;
//
// forward irp to lower device // forward irp to lower device
//
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to start
//
DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status); DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status);
return Status; return Status;
} }
//
// initialize irp queue // initialize irp queue
//
USBSTOR_QueueInitialize(DeviceExtension); USBSTOR_QueueInitialize(DeviceExtension);
//
// first get device & configuration & string descriptor // first get device & configuration & string descriptor
//
Status = USBSTOR_GetDescriptors(DeviceObject); Status = USBSTOR_GetDescriptors(DeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get device descriptor
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status); DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status);
return Status; return Status;
} }
//
// dump device descriptor
//
USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor); USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor);
//
// Check that this device uses bulk transfers and is SCSI
//
InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
// // Check that this device uses bulk transfers and is SCSI
// sanity check
// InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
@ -221,82 +167,51 @@ USBSTOR_FdoHandleStartDevice(
if (InterfaceDesc->bInterfaceSubClass != 0x06) if (InterfaceDesc->bInterfaceSubClass != 0x06)
{ {
//
// FIXME: need to pad CDBs to 12 byte // FIXME: need to pad CDBs to 12 byte
// mode select commands must be translated from 1AH / 15h to 5AH / 55h // mode select commands must be translated from 1AH / 15h to 5AH / 55h
//
DPRINT1("[USBSTOR] Error: need to pad CDBs\n"); DPRINT1("[USBSTOR] Error: need to pad CDBs\n");
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
//
// now select an interface // now select an interface
//
Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension); Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get device descriptor // failed to get device descriptor
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status); DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status);
return Status; return Status;
} }
//
// check if we got a bulk in + bulk out endpoint // check if we got a bulk in + bulk out endpoint
//
Status = USBSTOR_GetPipeHandles(DeviceExtension); Status = USBSTOR_GetPipeHandles(DeviceExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get pipe handles descriptor
//
DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status); DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status);
return Status; return Status;
} }
//
// get num of lun which are supported
//
Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension); Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to get max LUN
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status); DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status);
return Status; return Status;
} }
//
// now create for each LUN a device object, 1 minimum // now create for each LUN a device object, 1 minimum
//
do do
{ {
//
// create pdo
//
Status = USBSTOR_CreatePDO(DeviceObject, Index); Status = USBSTOR_CreatePDO(DeviceObject, Index);
//
// check for failure
//
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
//
// failed to create child pdo
//
DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status); DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status);
return Status; return Status;
} }
//
// increment pdo index
//
Index++; Index++;
DeviceExtension->InstanceCount++; DeviceExtension->InstanceCount++;
}while(Index < DeviceExtension->MaxLUN); } while(Index < DeviceExtension->MaxLUN);
#if 0 #if 0
// //
@ -313,16 +228,8 @@ USBSTOR_FdoHandleStartDevice(
} }
#endif #endif
//
// start the timer
//
//IoStartTimer(DeviceObject); //IoStartTimer(DeviceObject);
//
// fdo is now initialized
//
DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n"); DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -336,126 +243,94 @@ USBSTOR_FdoHandlePnp(
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get device extension
//
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(DeviceExtension->Common.IsFDO); ASSERT(DeviceExtension->Common.IsFDO);
switch(IoStack->MinorFunction) switch(IoStack->MinorFunction)
{ {
case IRP_MN_SURPRISE_REMOVAL: case IRP_MN_SURPRISE_REMOVAL:
{
DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
//
// forward irp to next device object
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
break;
}
case IRP_MN_STOP_DEVICE:
{
DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
IoStopTimer(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
//
// forward irp to next device object
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
case IRP_MN_REMOVE_DEVICE:
{
DPRINT("IRP_MN_REMOVE_DEVICE\n");
return USBSTOR_FdoHandleRemoveDevice(DeviceObject, DeviceExtension, Irp);
}
case IRP_MN_QUERY_CAPABILITIES:
{
//
// FIXME: set custom capabilities
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
{
#if 0
//
// we can if nothing is pending
//
if (DeviceExtension->IrpPendingCount != 0 ||
DeviceExtension->ActiveSrb != NULL)
#else
if (TRUE)
#endif
{
/* We have pending requests */
DPRINT1("Failing removal/stop request due to pending requests present\n");
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* We're all clear */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
break;
}
case IRP_MN_START_DEVICE:
{
Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
break;
}
default:
{ {
// DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
// forward irp to next device object // forward irp to next device object
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
break;
}
case IRP_MN_STOP_DEVICE:
{
DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
IoStopTimer(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
// forward irp to next device object
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
case IRP_MN_REMOVE_DEVICE:
{
DPRINT("IRP_MN_REMOVE_DEVICE\n");
return USBSTOR_FdoHandleRemoveDevice(DeviceObject, DeviceExtension, Irp);
}
case IRP_MN_QUERY_CAPABILITIES:
{
// FIXME: set custom capabilities
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
{
#if 0
// //
// we can if nothing is pending
//
if (DeviceExtension->IrpPendingCount != 0 ||
DeviceExtension->ActiveSrb != NULL)
#else
if (TRUE)
#endif
{
/* We have pending requests */
DPRINT1("Failing removal/stop request due to pending requests present\n");
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* We're all clear */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
break;
}
case IRP_MN_START_DEVICE:
{
Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
break;
}
default:
{
// forward irp to next device object
IoSkipCurrentIrpStackLocation(Irp); IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
} }
} }
//
// complete request
//
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
//
// store result
//
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
//
// complete request
//
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
} }
//
// done processing
//
return Status; return Status;
} }

View file

@ -1,12 +1,10 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/misc.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
#include "usbstor.h" #include "usbstor.h"
@ -14,9 +12,7 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
//
// driver verifier
//
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine; IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
NTSTATUS NTSTATUS
@ -40,46 +36,19 @@ USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
KEVENT Event; KEVENT Event;
NTSTATUS Status; NTSTATUS Status;
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
// copy irp stack location
//
IoCopyCurrentIrpStackLocationToNext(Irp); IoCopyCurrentIrpStackLocationToNext(Irp);
//
// set completion routine
//
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
//
// call driver
//
Status = IoCallDriver(DeviceObject, Irp); Status = IoCallDriver(DeviceObject, Irp);
//
// check if pending
//
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
//
// wait for the request to finish // wait for the request to finish
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
//
// copy status code
//
Status = Irp->IoStatus.Status; Status = Irp->IoStatus.Status;
} }
//
// done
//
return Status; return Status;
} }
@ -95,22 +64,11 @@ USBSTOR_GetBusInterface(
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
//
// sanity checks
//
ASSERT(DeviceObject); ASSERT(DeviceObject);
ASSERT(BusInterface); ASSERT(BusInterface);
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
// create irp
//
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
DeviceObject, DeviceObject,
NULL, NULL,
@ -118,22 +76,13 @@ USBSTOR_GetBusInterface(
NULL, NULL,
&Event, &Event,
&IoStatus); &IoStatus);
//
// was irp built
//
if (Irp == NULL) if (Irp == NULL)
{ {
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// initialize request // initialize request
// Stack = IoGetNextIrpStackLocation(Irp);
Stack=IoGetNextIrpStackLocation(Irp);
Stack->MajorFunction = IRP_MJ_PNP; Stack->MajorFunction = IRP_MJ_PNP;
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE; Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
@ -143,25 +92,12 @@ USBSTOR_GetBusInterface(
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL; Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
// Status = IoCallDriver(DeviceObject, Irp);
// call driver
//
Status= IoCallDriver(DeviceObject, Irp);
//
// did operation complete
//
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
//
// wait for completion
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
//
// collect status
//
Status=IoStatus.Status;
} }
return Status; return Status;
@ -177,72 +113,34 @@ USBSTOR_SyncUrbRequest(
KEVENT Event; KEVENT Event;
NTSTATUS Status; NTSTATUS Status;
//
// allocate irp
//
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp) if (!Irp)
{ {
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
// get next stack location
//
IoStack = IoGetNextIrpStackLocation(Irp); IoStack = IoGetNextIrpStackLocation(Irp);
//
// initialize stack location // initialize stack location
//
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest; IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length; IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
//
// setup completion routine
//
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
//
// call driver
//
Status = IoCallDriver(DeviceObject, Irp); Status = IoCallDriver(DeviceObject, Irp);
//
// check if request is pending
//
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
//
// wait for completion
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
//
// update status
//
Status = Irp->IoStatus.Status; Status = Irp->IoStatus.Status;
} }
//
// free irp
//
IoFreeIrp(Irp); IoFreeIrp(Irp);
//
// done
//
return Status; return Status;
} }
@ -251,22 +149,13 @@ AllocateItem(
IN POOL_TYPE PoolType, IN POOL_TYPE PoolType,
IN ULONG ItemSize) IN ULONG ItemSize)
{ {
//
// allocate item
//
PVOID Item = ExAllocatePoolWithTag(PoolType, ItemSize, USB_STOR_TAG); PVOID Item = ExAllocatePoolWithTag(PoolType, ItemSize, USB_STOR_TAG);
if (Item) if (Item)
{ {
//
// zero item
//
RtlZeroMemory(Item, ItemSize); RtlZeroMemory(Item, ItemSize);
} }
//
// return element
//
return Item; return Item;
} }
@ -274,9 +163,6 @@ VOID
FreeItem( FreeItem(
IN PVOID Item) IN PVOID Item)
{ {
//
// free item
//
ExFreePoolWithTag(Item, USB_STOR_TAG); ExFreePoolWithTag(Item, USB_STOR_TAG);
} }
@ -294,21 +180,12 @@ USBSTOR_ClassRequest(
PURB Urb; PURB Urb;
NTSTATUS Status; NTSTATUS Status;
//
// first allocate urb
//
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if (!Urb) if (!Urb)
{ {
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//
// initialize vendor request
//
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 = TransferFlags; Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags;
@ -317,23 +194,12 @@ USBSTOR_ClassRequest(
Urb->UrbControlVendorClassRequest.Request = RequestType; Urb->UrbControlVendorClassRequest.Request = RequestType;
Urb->UrbControlVendorClassRequest.Index = Index; Urb->UrbControlVendorClassRequest.Index = Index;
//
// submit request
//
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
//
// free urb
//
FreeItem(Urb); FreeItem(Urb);
//
// done
//
return Status; return Status;
} }
NTSTATUS NTSTATUS
USBSTOR_GetMaxLUN( USBSTOR_GetMaxLUN(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -342,22 +208,13 @@ USBSTOR_GetMaxLUN(
PUCHAR Buffer; PUCHAR Buffer;
NTSTATUS Status; NTSTATUS Status;
//
// allocate 1-byte buffer
//
Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR)); Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR));
if (!Buffer) if (!Buffer)
{ {
//
// no memory
//
FreeItem(Buffer); FreeItem(Buffer);
return STATUS_INSUFFICIENT_RESOURCES; 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); Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer);
DPRINT("MaxLUN: %x\n", *Buffer); DPRINT("MaxLUN: %x\n", *Buffer);
@ -366,42 +223,28 @@ USBSTOR_GetMaxLUN(
{ {
if (*Buffer > 0xF) if (*Buffer > 0xF)
{ {
//
// invalid response documented in usb mass storage specification // invalid response documented in usb mass storage specification
//
Status = STATUS_DEVICE_DATA_ERROR; Status = STATUS_DEVICE_DATA_ERROR;
} }
else else
{ {
//
// store maxlun // store maxlun
//
DeviceExtension->MaxLUN = *Buffer; DeviceExtension->MaxLUN = *Buffer;
} }
} }
else else
{ {
//
// "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0" // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0"
// 3.2 Get Max LUN (class-specific request) : // 3.2 Get Max LUN (class-specific request) :
// Devices that do not support multiple LUNs may STALL this command. // Devices that do not support multiple LUNs may STALL this command.
//
USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension); USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension);
DeviceExtension->MaxLUN = 0; DeviceExtension->MaxLUN = 0;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
//
// free buffer
//
FreeItem(Buffer); FreeItem(Buffer);
//
// done
//
return Status; return Status;
} }
NTSTATUS NTSTATUS
@ -411,16 +254,8 @@ USBSTOR_ResetDevice(
{ {
NTSTATUS Status; NTSTATUS Status;
//
// execute request
//
Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL); Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
//
// done
//
return Status; return Status;
} }
BOOLEAN BOOLEAN
@ -433,88 +268,54 @@ USBSTOR_IsFloppy(
PUFI_CAPACITY_DESCRIPTOR Descriptor; PUFI_CAPACITY_DESCRIPTOR Descriptor;
ULONG Length, Index, BlockCount, BlockLength; ULONG Length, Index, BlockCount, BlockLength;
//
// get format header
//
FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer; FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer;
//
// sanity checks
//
ASSERT(FormatHeader->Reserved1 == 0x00); ASSERT(FormatHeader->Reserved1 == 0x00);
ASSERT(FormatHeader->Reserved2 == 0x00); ASSERT(FormatHeader->Reserved2 == 0x00);
ASSERT(FormatHeader->Reserved3 == 0x00); ASSERT(FormatHeader->Reserved3 == 0x00);
//
// is there capacity data // is there capacity data
//
if (!FormatHeader->CapacityLength) if (!FormatHeader->CapacityLength)
{ {
//
// no data provided
//
DPRINT1("[USBSTOR] No capacity length\n"); DPRINT1("[USBSTOR] No capacity length\n");
return FALSE; return FALSE;
} }
//
// the format header are always 8 bytes in length // the format header are always 8 bytes in length
//
ASSERT((FormatHeader->CapacityLength & 0x7) == 0); ASSERT((FormatHeader->CapacityLength & 0x7) == 0);
DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength); DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength);
//
// grab length and locate first descriptor // grab length and locate first descriptor
//
Length = FormatHeader->CapacityLength; Length = FormatHeader->CapacityLength;
Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1); Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1);
for(Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++) for (Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++)
{ {
//
// blocks are little endian format // blocks are little endian format
//
BlockCount = NTOHL(Descriptor->BlockCount); BlockCount = NTOHL(Descriptor->BlockCount);
//
// get block length
//
BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8)); BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8));
DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code); DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code);
if (BlockLength == 512 && BlockCount == 1440) if (BlockLength == 512 && BlockCount == 1440)
{ {
//
// 720 KB DD // 720 KB DD
//
*MediumTypeCode = 0x1E; *MediumTypeCode = 0x1E;
return TRUE; return TRUE;
} }
else if (BlockLength == 1024 && BlockCount == 1232) else if (BlockLength == 1024 && BlockCount == 1232)
{ {
//
// 1,25 MB // 1,25 MB
//
*MediumTypeCode = 0x93; *MediumTypeCode = 0x93;
return TRUE; return TRUE;
} }
else if (BlockLength == 512 && BlockCount == 2880) else if (BlockLength == 512 && BlockCount == 2880)
{ {
//
// 1,44MB KB DD // 1,44MB KB DD
//
*MediumTypeCode = 0x94; *MediumTypeCode = 0x94;
return TRUE; return TRUE;
} }
// Descriptor++;
// move to next descriptor
//
Descriptor = (Descriptor + 1);
} }
//
// no floppy detected
//
return FALSE; return FALSE;
} }

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,10 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/queue.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
* Michael Martin (michael.martin@reactos.org) * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
#include "usbstor.h" #include "usbstor.h"
@ -14,28 +12,14 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
VOID VOID
USBSTOR_QueueInitialize( USBSTOR_QueueInitialize(
PFDO_DEVICE_EXTENSION FDODeviceExtension) PFDO_DEVICE_EXTENSION FDODeviceExtension)
{ {
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// initialize queue lock
//
KeInitializeSpinLock(&FDODeviceExtension->IrpListLock); KeInitializeSpinLock(&FDODeviceExtension->IrpListLock);
//
// initialize irp list head
//
InitializeListHead(&FDODeviceExtension->IrpListHead); InitializeListHead(&FDODeviceExtension->IrpListHead);
//
// initialize event
//
KeInitializeEvent(&FDODeviceExtension->NoPendingRequests, NotificationEvent, TRUE); KeInitializeEvent(&FDODeviceExtension->NoPendingRequests, NotificationEvent, TRUE);
} }
@ -47,40 +31,18 @@ USBSTOR_CancelIo(
{ {
PFDO_DEVICE_EXTENSION FDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
//
// sanity check
//
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// this IRP isn't in our list here // this IRP isn't in our list here
//
//
// now release the cancel lock // now release the cancel lock
//
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
//
// set cancel status
//
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
//
// now cancel the irp
//
USBSTOR_QueueTerminateRequest(DeviceObject, Irp); USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// start the next one
//
USBSTOR_QueueNextRequest(DeviceObject); USBSTOR_QueueNextRequest(DeviceObject);
} }
@ -92,51 +54,20 @@ USBSTOR_Cancel(
{ {
PFDO_DEVICE_EXTENSION FDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
//
// sanity check
//
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// acquire irp list lock
//
KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock); KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
//
// remove the irp from the list
//
RemoveEntryList(&Irp->Tail.Overlay.ListEntry); RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
//
// release irp list lock
//
KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock); KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
//
// now release the cancel lock
//
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
//
// set cancel status
//
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
//
// now cancel the irp
//
USBSTOR_QueueTerminateRequest(DeviceObject, Irp); USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// start the next one
//
USBSTOR_QueueNextRequest(DeviceObject); USBSTOR_QueueNextRequest(DeviceObject);
} }
@ -153,68 +84,32 @@ USBSTOR_QueueAddIrp(
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// mark irp pending
//
IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
//
// acquire lock
//
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
//
// check if there are irp pending
//
SrbProcessing = FDODeviceExtension->IrpPendingCount != 0; SrbProcessing = FDODeviceExtension->IrpPendingCount != 0;
if (SrbProcessing) if (SrbProcessing)
{ {
//
// add irp to queue // add irp to queue
//
InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry); InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry);
} }
//
// increment pending count
//
FDODeviceExtension->IrpPendingCount++; FDODeviceExtension->IrpPendingCount++;
//
// clear the no requests pending event
//
KeClearEvent(&FDODeviceExtension->NoPendingRequests); KeClearEvent(&FDODeviceExtension->NoPendingRequests);
//
// check if queue is freezed // check if queue is freezed
//
IrpListFreeze = FDODeviceExtension->IrpListFreeze; IrpListFreeze = FDODeviceExtension->IrpListFreeze;
//
// release list lock
//
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
//
// synchronize with cancellations by holding the cancel lock // synchronize with cancellations by holding the cancel lock
//
IoAcquireCancelSpinLock(&Irp->CancelIrql); IoAcquireCancelSpinLock(&Irp->CancelIrql);
//
// now set the driver cancel routine
//
if (SrbProcessing) if (SrbProcessing)
{ {
ASSERT(FDODeviceExtension->ActiveSrb != NULL); ASSERT(FDODeviceExtension->ActiveSrb != NULL);
@ -229,30 +124,17 @@ USBSTOR_QueueAddIrp(
OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo); OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
} }
//
// check if the irp has already been cancelled // check if the irp has already been cancelled
//
if (Irp->Cancel && OldDriverCancel == NULL) if (Irp->Cancel && OldDriverCancel == NULL)
{ {
//
// cancel irp // cancel irp
//
Irp->CancelRoutine(DeviceObject, Irp); Irp->CancelRoutine(DeviceObject, Irp);
//
// irp was cancelled
//
return FALSE; return FALSE;
} }
//
// release the cancel lock
//
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
//
// if list is freezed, dont start this packet // if list is freezed, dont start this packet
//
DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount); DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);
return (IrpListFreeze || SrbProcessing); return (IrpListFreeze || SrbProcessing);
@ -267,45 +149,21 @@ USBSTOR_RemoveIrp(
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PIRP Irp = NULL; PIRP Irp = NULL;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// acquire lock
//
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
//
// check if list is empty
//
if (!IsListEmpty(&FDODeviceExtension->IrpListHead)) if (!IsListEmpty(&FDODeviceExtension->IrpListHead))
{ {
//
// remove entry
//
Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead); Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead);
//
// get offset to start of irp // get offset to start of irp
//
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
} }
//
// release list lock
//
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
//
// return result
//
return Irp; return Irp;
} }
@ -315,14 +173,8 @@ USBSTOR_QueueWaitForPendingRequests(
{ {
PFDO_DEVICE_EXTENSION FDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// perform the wait
//
KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests, KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests,
Executive, Executive,
KernelMode, KernelMode,
@ -340,51 +192,28 @@ USBSTOR_QueueTerminateRequest(
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FDODeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FDODeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// acquire lock
//
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
//
// decrement pending irp count
//
FDODeviceExtension->IrpPendingCount--; FDODeviceExtension->IrpPendingCount--;
//
// check if this was our current active SRB // check if this was our current active SRB
//
if (FDODeviceExtension->ActiveSrb == Request) if (FDODeviceExtension->ActiveSrb == Request)
{ {
//
// indicate processing is completed // indicate processing is completed
//
FDODeviceExtension->ActiveSrb = NULL; FDODeviceExtension->ActiveSrb = NULL;
} }
//
// Set the event if nothing else is pending // Set the event if nothing else is pending
//
if (FDODeviceExtension->IrpPendingCount == 0 && if (FDODeviceExtension->IrpPendingCount == 0 &&
FDODeviceExtension->ActiveSrb == NULL) FDODeviceExtension->ActiveSrb == NULL)
{ {
KeSetEvent(&FDODeviceExtension->NoPendingRequests, IO_NO_INCREMENT, FALSE); KeSetEvent(&FDODeviceExtension->NoPendingRequests, IO_NO_INCREMENT, FALSE);
} }
//
// release lock
//
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
} }
VOID VOID
@ -396,73 +225,36 @@ USBSTOR_QueueNextRequest(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
//
// get pdo device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// check first if there's already a request pending or the queue is frozen // check first if there's already a request pending or the queue is frozen
//
if (FDODeviceExtension->ActiveSrb != NULL || if (FDODeviceExtension->ActiveSrb != NULL ||
FDODeviceExtension->IrpListFreeze) FDODeviceExtension->IrpListFreeze)
{ {
//
// no work to do yet // no work to do yet
//
return; return;
} }
//
// remove first irp from list // remove first irp from list
//
Irp = USBSTOR_RemoveIrp(DeviceObject); Irp = USBSTOR_RemoveIrp(DeviceObject);
//
// is there an irp pending // is there an irp pending
//
if (!Irp) if (!Irp)
{ {
//
// no work to do // no work to do
//
IoStartNextPacket(DeviceObject, TRUE); IoStartNextPacket(DeviceObject, TRUE);
return; return;
} }
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get srb
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// sanity check
//
ASSERT(Request); ASSERT(Request);
//
// set the active SRB
//
FDODeviceExtension->ActiveSrb = Request; FDODeviceExtension->ActiveSrb = Request;
//
// start next packet // start next packet
//
IoStartPacket(DeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo); IoStartPacket(DeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
//
// start next request
//
IoStartNextPacket(DeviceObject, TRUE); IoStartNextPacket(DeviceObject, TRUE);
} }
@ -476,67 +268,33 @@ USBSTOR_QueueRelease(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// acquire lock
//
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
//
// clear freezed status // clear freezed status
//
FDODeviceExtension->IrpListFreeze = FALSE; FDODeviceExtension->IrpListFreeze = FALSE;
//
// release irp list lock
//
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
//
// grab newest irp // grab newest irp
//
Irp = USBSTOR_RemoveIrp(DeviceObject); Irp = USBSTOR_RemoveIrp(DeviceObject);
//
// is there an irp
//
if (!Irp) if (!Irp)
{ {
//
// no irp
//
return; return;
} }
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get srb
//
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
//
// start new packet
//
IoStartPacket(DeviceObject, IoStartPacket(DeviceObject,
Irp, Irp,
&Request->QueueSortKey, &Request->QueueSortKey,
USBSTOR_CancelIo); USBSTOR_CancelIo);
} }
VOID VOID
NTAPI NTAPI
USBSTOR_StartIo( USBSTOR_StartIo(
@ -551,107 +309,45 @@ USBSTOR_StartIo(
DPRINT("USBSTOR_StartIo\n"); DPRINT("USBSTOR_StartIo\n");
//
// get FDO device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
//
// acquire cancel spinlock
//
IoAcquireCancelSpinLock(&OldLevel); IoAcquireCancelSpinLock(&OldLevel);
//
// set cancel routine to zero
//
IoSetCancelRoutine(Irp, NULL); IoSetCancelRoutine(Irp, NULL);
//
// check if the irp has been cancelled // check if the irp has been cancelled
//
if (Irp->Cancel) if (Irp->Cancel)
{ {
//
// irp has been cancelled, release cancel spinlock
//
IoReleaseCancelSpinLock(OldLevel); IoReleaseCancelSpinLock(OldLevel);
//
// irp is cancelled
//
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
//
// terminate request
//
USBSTOR_QueueTerminateRequest(DeviceObject, Irp); USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
//
// complete request
//
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// queue next request
//
USBSTOR_QueueNextRequest(DeviceObject); USBSTOR_QueueNextRequest(DeviceObject);
//
// done
//
return; return;
} }
//
// release cancel spinlock
//
IoReleaseCancelSpinLock(OldLevel); IoReleaseCancelSpinLock(OldLevel);
//
// acquire lock
//
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
//
// check reset is in progress
//
ResetInProgress = FDODeviceExtension->ResetInProgress; ResetInProgress = FDODeviceExtension->ResetInProgress;
ASSERT(ResetInProgress == FALSE); ASSERT(ResetInProgress == FALSE);
//
// release lock
//
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get pdo device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
// // TODO: this condition is always false
// is a reset in progress
//
if (ResetInProgress) if (ResetInProgress)
{ {
//
// hard reset is in progress // hard reset is in progress
//
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
USBSTOR_QueueTerminateRequest(DeviceObject, Irp); USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
@ -659,12 +355,7 @@ USBSTOR_StartIo(
return; return;
} }
//
// execute scsi
//
USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp, 0); USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp, 0);
//
// FIXME: handle error // FIXME: handle error
//
} }

File diff suppressed because it is too large Load diff

View file

@ -1,21 +1,17 @@
/* /*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: drivers/usb/usbstor/usbstor.c
* PURPOSE: USB block storage device driver. * PURPOSE: USB block storage device driver.
* PROGRAMMERS: * COPYRIGHT: 2005-2006 James Tabor
* James Tabor * 2011-2012 Michael Martin (michael.martin@reactos.org)
Johannes Anderwald * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
*/ */
/* INCLUDES ******************************************************************/
#include "usbstor.h" #include "usbstor.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -27,71 +23,38 @@ USBSTOR_AddDevice(
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
//
// lets create the device
//
Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject); Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
//
// check for success
//
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status); DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
return Status; return Status;
} }
//
// get device extension
//
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(DeviceExtension); ASSERT(DeviceExtension);
//
// zero device extension
//
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION)); RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
//
// initialize device extension // initialize device extension
//
DeviceExtension->Common.IsFDO = TRUE; DeviceExtension->Common.IsFDO = TRUE;
DeviceExtension->FunctionalDeviceObject = DeviceObject; DeviceExtension->FunctionalDeviceObject = DeviceObject;
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
//
// init timer
//
IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension); IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
//
// did attaching fail // did attaching fail
//
if (!DeviceExtension->LowerDeviceObject) if (!DeviceExtension->LowerDeviceObject)
{ {
//
// device removed
//
IoDeleteDevice(DeviceObject); IoDeleteDevice(DeviceObject);
return STATUS_DEVICE_REMOVED; return STATUS_DEVICE_REMOVED;
} }
//
// set device flags
//
DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
//
// device is initialized // device is initialized
//
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//
// done
//
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -100,9 +63,7 @@ NTAPI
USBSTOR_Unload( USBSTOR_Unload(
PDRIVER_OBJECT DriverObject) PDRIVER_OBJECT DriverObject)
{ {
//
// no-op // no-op
//
} }
NTSTATUS NTSTATUS
@ -111,9 +72,7 @@ USBSTOR_DispatchClose(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
//
// function always succeeds ;) // function always succeeds ;)
//
DPRINT("USBSTOR_DispatchClose\n"); DPRINT("USBSTOR_DispatchClose\n");
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
@ -121,7 +80,6 @@ USBSTOR_DispatchClose(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
USBSTOR_DispatchDeviceControl( USBSTOR_DispatchDeviceControl(
@ -130,33 +88,18 @@ USBSTOR_DispatchDeviceControl(
{ {
NTSTATUS Status; NTSTATUS Status;
//
// handle requests
//
Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp); Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
//
// complete request
//
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// done
//
return Status; return Status;
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
USBSTOR_DispatchScsi( USBSTOR_DispatchScsi(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
//
// handle requests
//
return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp); return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
} }
@ -166,9 +109,7 @@ USBSTOR_DispatchReadWrite(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PIRP Irp) PIRP Irp)
{ {
//
// read write ioctl is not supported // read write ioctl is not supported
//
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -183,26 +124,14 @@ USBSTOR_DispatchPnp(
{ {
PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension; PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
//
// get common device extension
//
DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// is it for the FDO
//
if (DeviceExtension->IsFDO) if (DeviceExtension->IsFDO)
{ {
//
// dispatch pnp request to fdo pnp handler
//
return USBSTOR_FdoHandlePnp(DeviceObject, Irp); return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
} }
else else
{ {
//
// dispatch request to pdo pnp handler
//
return USBSTOR_PdoHandlePnp(DeviceObject, Irp); return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
} }
} }
@ -233,8 +162,6 @@ USBSTOR_DispatchPower(
} }
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
DriverEntry( DriverEntry(
@ -244,51 +171,16 @@ DriverEntry(
DPRINT("********* USB Storage *********\n"); DPRINT("********* USB Storage *********\n");
//
// driver unload routine
//
DriverObject->DriverUnload = USBSTOR_Unload; DriverObject->DriverUnload = USBSTOR_Unload;
//
// add device function
//
DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice; DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
//
// driver start i/o routine
//
DriverObject->DriverStartIo = USBSTOR_StartIo; DriverObject->DriverStartIo = USBSTOR_StartIo;
//
// create / close
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose; DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl; // scsi pass through requests
//
// scsi pass through requests
//
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl;
//
// irp dispatch read / write
//
DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite; DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
//
// scsi queue ioctl
//
DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi; DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
//
// pnp processing
//
DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp; DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
//
// power processing
//
DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower; DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
return STATUS_SUCCESS; return STATUS_SUCCESS;