/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/fdo.c
+ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: USB block storage device driver.
- * PROGRAMMERS:
- * James Tabor
- * Michael Martin (michael.martin@reactos.org)
- * Johannes Anderwald (johannes.anderwald@reactos.org)
+ * COPYRIGHT: 2005-2006 James Tabor
+ * 2011-2012 Michael Martin (michael.martin@reactos.org)
+ * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbstor.h"
+#define NDEBUG
+#include <debug.h>
+
+
VOID
USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
{
- DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
+ DPRINT1("Dumping Device Descriptor %p\n", DeviceDescriptor);
DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
IN OUT PIRP Irp)
{
ULONG DeviceCount = 0;
- ULONG Index;
+ LONG Index;
PDEVICE_RELATIONS DeviceRelations;
PIO_STACK_LOCATION IoStack;
- //
- // get current irp stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
- //
// check if relation type is BusRelations
- //
if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
{
- //
// FDO always only handles bus relations
- //
return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
}
- //
// 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])
{
- //
- // child pdo
- //
DeviceCount++;
}
}
- //
- // allocate device relations
- //
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
if (!DeviceRelations)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// 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])
{
- //
// store child pdo
- //
DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index];
- //
// add reference
- //
ObReferenceObject(DeviceExtension->ChildPDO[Index]);
- //
- // increment count
- //
DeviceRelations->Count++;
}
}
- //
- // store result
- //
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
- //
- // request completed successfully
- //
return STATUS_SUCCESS;
}
DPRINT("Handling FDO removal %p\n", DeviceObject);
- /* FIXME: wait for devices finished processing */
- for(Index = 0; Index < 16; Index++)
+ // FIXME: wait for devices finished processing
+ for (Index = 0; Index < 16; Index++)
{
if (DeviceExtension->ChildPDO[Index] != NULL)
{
}
}
- /* Send the IRP down the stack */
+ // Freeing everything in DeviceExtension
+ ASSERT(
+ DeviceExtension->DeviceDescriptor &&
+ DeviceExtension->ConfigurationDescriptor &&
+ DeviceExtension->InterfaceInformation &&
+ DeviceExtension->ResetDeviceWorkItem
+ );
+
+ ExFreePoolWithTag(DeviceExtension->DeviceDescriptor, USB_STOR_TAG);
+ ExFreePoolWithTag(DeviceExtension->ConfigurationDescriptor, USB_STOR_TAG);
+ ExFreePoolWithTag(DeviceExtension->InterfaceInformation, USB_STOR_TAG);
+ IoFreeWorkItem(DeviceExtension->ResetDeviceWorkItem);
+
+ if (DeviceExtension->SerialNumber)
+ {
+ ExFreePoolWithTag(DeviceExtension->SerialNumber, USB_STOR_TAG);
+ }
+
+ // Send the IRP down the stack
IoSkipCurrentIrpStackLocation(Irp);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
- /* Detach from the device stack */
+ // Detach from the device stack
IoDetachDevice(DeviceExtension->LowerDeviceObject);
- /* Delete the device object */
IoDeleteDevice(DeviceObject);
return Status;
PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
NTSTATUS Status;
UCHAR Index = 0;
+ PIO_WORKITEM WorkItem;
- //
// forward irp to lower device
- //
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
if (!NT_SUCCESS(Status))
{
- //
- // failed to start
- //
DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status);
return Status;
}
- //
- // intialize irp queue
- //
+ if (!DeviceExtension->ResetDeviceWorkItem)
+ {
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+ DeviceExtension->ResetDeviceWorkItem = WorkItem;
+
+ if (!WorkItem)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ // initialize irp queue
USBSTOR_QueueInitialize(DeviceExtension);
- //
// first get device & configuration & string descriptor
- //
Status = USBSTOR_GetDescriptors(DeviceObject);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get device descriptor
- //
DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status);
return Status;
}
- //
- // dump device descriptor
- //
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));
- //
- // sanity check
- //
+ InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
return STATUS_NOT_SUPPORTED;
}
- if (InterfaceDesc->bInterfaceSubClass != 0x06)
+ if (InterfaceDesc->bInterfaceSubClass == 0x04) // UFI subclass
{
- //
// FIXME: need to pad CDBs to 12 byte
// mode select commands must be translated from 1AH / 15h to 5AH / 55h
- //
DPRINT1("[USBSTOR] Error: need to pad CDBs\n");
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_SUPPORTED;
}
- //
// now select an interface
- //
Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
- //
// failed to get device descriptor
- //
DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status);
return Status;
}
- //
// check if we got a bulk in + bulk out endpoint
- //
Status = USBSTOR_GetPipeHandles(DeviceExtension);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get pipe handles descriptor
- //
DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status);
return Status;
}
- //
- // get num of lun which are supported
- //
Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get max LUN
- //
DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status);
return Status;
}
- //
// now create for each LUN a device object, 1 minimum
- //
do
{
- //
- // create pdo
- //
Status = USBSTOR_CreatePDO(DeviceObject, Index);
- //
- // check for failure
- //
if (!NT_SUCCESS(Status))
{
- //
- // failed to create child pdo
- //
DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status);
return Status;
}
- //
- // increment pdo index
- //
Index++;
DeviceExtension->InstanceCount++;
- }while(Index < DeviceExtension->MaxLUN);
+ } while(Index < DeviceExtension->MaxLUN);
#if 0
//
}
#endif
-
- //
- // start the timer
- //
//IoStartTimer(DeviceObject);
-
- //
- // fdo is now initialized
- //
DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n");
return STATUS_SUCCESS;
}
PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get device extension
- //
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(DeviceExtension->Common.IsFDO);
switch(IoStack->MinorFunction)
{
- case IRP_MN_SURPRISE_REMOVAL:
- {
- DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ 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;
+ }
+ 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:
- {
+ }
+ 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)
+ //
+ // we can if nothing is pending
+ //
+ if (DeviceExtension->IrpPendingCount != 0 ||
+ DeviceExtension->ActiveSrb != NULL)
#else
- if (TRUE)
+ 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:
+ {
+ /* 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);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
}
- //
- // complete request
- //
if (Status != STATUS_PENDING)
{
- //
- // store result
- //
Irp->IoStatus.Status = Status;
-
- //
- // complete request
- //
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
- //
- // done processing
- //
return Status;
}