Now the driver conforms with our current Coding Style.
No functional changes
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/descriptor.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>
+
NTSTATUS
NTAPI
USBSTOR_GetDescriptor(
NTSTATUS Status;
PVOID Descriptor;
- //
- // sanity checks
- //
ASSERT(DeviceObject);
ASSERT(OutDescriptor);
ASSERT(DescriptorLength);
- //
// first allocate descriptor buffer
- //
Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
if (!Descriptor)
{
- //
// no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // allocate urb
- //
Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
if (!Urb)
{
- //
// no memory
- //
FreeItem(Descriptor);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// initialize urb
- //
UsbBuildGetDescriptorRequest(Urb,
sizeof(Urb->UrbControlDescriptorRequest),
DescriptorType,
DescriptorLength,
NULL);
- //
// submit urb
- //
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
- //
- // free urb
- //
FreeItem(Urb);
if (NT_SUCCESS(Status))
{
- //
- // store result
- //
*OutDescriptor = Descriptor;
}
- //
- // done
- //
return Status;
}
-
NTSTATUS
USBSTOR_GetDescriptors(
IN PDEVICE_OBJECT DeviceObject)
PFDO_DEVICE_EXTENSION DeviceExtension;
USHORT DescriptorLength;
- //
- // get device extension
- //
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
// first get device descriptor
- //
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get device descriptor
- //
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
- //
// now get basic configuration descriptor
- //
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get configuration descriptor
- //
FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
- //
// backup length
- //
DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
- //
// release basic descriptor
- //
FreeItem(DeviceExtension->ConfigurationDescriptor);
DeviceExtension->ConfigurationDescriptor = NULL;
- //
// allocate full descriptor
- //
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get configuration descriptor
- //
FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
- //
// check if there is a serial number provided
- //
if (DeviceExtension->DeviceDescriptor->iSerialNumber)
{
- //
// get serial number
- //
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber);
if (!NT_SUCCESS(Status))
{
- //
- // failed to get serial number descriptor, free device descriptor
- //
FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
- //
- // free configuration descriptor
- //
FreeItem(DeviceExtension->ConfigurationDescriptor);
DeviceExtension->ConfigurationDescriptor = NULL;
- //
- // set serial number to zero
- //
DeviceExtension->SerialNumber = NULL;
return Status;
}
NTAPI
USBSTOR_ScanConfigurationDescriptor(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
- OUT PUSB_INTERFACE_DESCRIPTOR * OutInterfaceDescriptor,
- OUT PUSB_ENDPOINT_DESCRIPTOR * InEndpointDescriptor,
- OUT PUSB_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
+ OUT PUSB_INTERFACE_DESCRIPTOR *OutInterfaceDescriptor,
+ OUT PUSB_ENDPOINT_DESCRIPTOR *InEndpointDescriptor,
+ OUT PUSB_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor)
{
PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor;
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
- //
- // sanity checks
- //
ASSERT(ConfigurationDescriptor);
ASSERT(OutInterfaceDescriptor);
ASSERT(InEndpointDescriptor);
ASSERT(OutEndpointDescriptor);
- //
- // nullify pointers
- //
*OutInterfaceDescriptor = NULL;
*InEndpointDescriptor = NULL;
*OutEndpointDescriptor = NULL;
- //
// start scanning
- //
CurrentDescriptor = ConfigurationDescriptor;
do
{
- //
- // check current descriptor type
- //
if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
- //
- // found interface descriptor
- //
if (*OutInterfaceDescriptor)
{
- //
// we only process the first interface descriptor as ms does -> see documentation
- //
break;
}
- //
// store interface descriptor
- //
*OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor;
}
else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{
- //
- // convert to endpoint descriptor
- //
EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor;
- //
- // sanity check
- //
ASSERT(*OutInterfaceDescriptor);
- //
// get endpoint type
- //
if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK)
{
- //
- // bulk endpoint type
- //
- if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress))
- {
- //
- // bulk in
- //
- *InEndpointDescriptor = EndpointDescriptor;
- }
- else
- {
- //
- // bulk out
- //
- *OutEndpointDescriptor = EndpointDescriptor;
- }
+ if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress))
+ {
+ *InEndpointDescriptor = EndpointDescriptor;
+ }
+ else
+ {
+ *OutEndpointDescriptor = EndpointDescriptor;
+ }
}
else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT)
{
- //
- // interrupt endpoint type
- //
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
}
- //
// move to next descriptor
- //
CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength);
- //
// was it the last descriptor
- //
if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
{
- //
- // reached last descriptor
- //
break;
}
- }while(TRUE);
+ } while(TRUE);
- //
// check if everything has been found
- //
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);
return STATUS_UNSUCCESSFUL;
}
- //
- // completed successfully
- //
return STATUS_SUCCESS;
}
PURB Urb;
PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
- //
- // now scan configuration descriptors
- //
Status = USBSTOR_ScanConfigurationDescriptor(DeviceExtension->ConfigurationDescriptor, &InterfaceDescriptor, &InEndpointDescriptor, &OutEndpointDescriptor);
if (!NT_SUCCESS(Status))
{
- //
- // failed to scan
- //
return Status;
}
- //
// now allocate one interface entry and terminating null entry
- //
InterfaceList = (PUSBD_INTERFACE_LIST_ENTRY)AllocateItem(PagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * 2);
if (!InterfaceList)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// initialize interface list entry
- //
InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
- //
// now allocate the urb
- //
Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, InterfaceList);
if (!Urb)
{
- //
- // no memory
- //
FreeItem(InterfaceList);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // sanity check
- //
+
ASSERT(InterfaceList[0].Interface);
- //
// submit urb
- //
Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
if (!NT_SUCCESS(Status))
{
- //
// failed to set configuration
- //
DPRINT1("USBSTOR_SelectConfiguration failed to set interface %x\n", Status);
FreeItem(InterfaceList);
ExFreePoolWithTag(Urb, 0);
return Status;
}
- //
// backup interface information
- //
DeviceExtension->InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)AllocateItem(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length);
if (!DeviceExtension->InterfaceInformation)
{
- //
- // failed to allocate interface information structure
- //
FreeItem(InterfaceList);
ExFreePoolWithTag(Urb, 0);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// copy interface information
- //
RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
- //
// store pipe handle
- //
DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
- //
// now prepare interface urb
- //
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
- //
RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInformation, DeviceExtension->InterfaceInformation->Length);
- //
// now select the interface
- //
Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
-
- //
- // did it succeed
- //
if (NT_SUCCESS(Status))
{
- //
// update configuration info
- //
ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInformation->Length);
RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
}
- //
- // free interface list & urb
- //
FreeItem(InterfaceList);
ExFreePoolWithTag(Urb, 0);
- //
- // done
- //
return Status;
}
ULONG Index;
BOOLEAN BulkInFound = FALSE, BulkOutFound = FALSE;
- //
- // no enumerate all pipes and extract bulk-in / bulk-out pipe handle
- //
- for(Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++)
+ // enumerate all pipes and extract bulk-in / bulk-out pipe handle
+ for (Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++)
{
- //
- // check pipe type
- //
if (DeviceExtension->InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeBulk)
{
- //
- // check direction
- //
if (USB_ENDPOINT_DIRECTION_IN(DeviceExtension->InterfaceInformation->Pipes[Index].EndpointAddress))
{
- //
- // bulk in pipe
- //
DeviceExtension->BulkInPipeIndex = Index;
- //
// there should not be another bulk in pipe
- //
ASSERT(BulkInFound == FALSE);
BulkInFound = TRUE;
}
else
{
- //
- // bulk out pipe
- //
DeviceExtension->BulkOutPipeIndex = Index;
- //
// there should not be another bulk out pipe
- //
ASSERT(BulkOutFound == FALSE);
BulkOutFound = TRUE;
}
}
}
- //
- // check if both bulk pipes have been found
- //
if (!BulkInFound || !BulkOutFound)
{
- //
// WTF? usb port driver does not give us bulk pipe access
- //
DPRINT1("USBSTOR_GetPipeHandles> BulkInFound %c BulkOutFound %c missing!!!\n", BulkInFound, BulkOutFound);
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
- //
- // device is configured
- //
return STATUS_SUCCESS;
}
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/disk.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>
+
NTSTATUS
USBSTOR_HandleInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
PPDO_DEVICE_EXTENSION PDODeviceExtension;
NTSTATUS Status;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
-
- //
- // sanity check
- //
ASSERT(Request);
-
- //
- // get device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
switch(Request->Function)
{
DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");
- //
// check if request is valid
- //
if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
{
- //
// 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) ||
Request->DataTransferLength == 0 ||
Irp->MdlAddress == NULL)
{
- //
- // invalid parameter
- //
Status = STATUS_INVALID_PARAMETER;
break;
}
}
else
{
- //
// sense buffer request
- //
- if (Request->DataTransferLength ||
- Request->DataBuffer ||
- Irp->MdlAddress)
+ if (Request->DataTransferLength || Request->DataBuffer || Irp->MdlAddress)
{
- //
- // invalid parameter
- //
Status = STATUS_INVALID_PARAMETER;
break;
}
}
- //
// add the request
- //
if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp))
{
- //
- // irp was not added to the queue
- //
IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
}
- //
- // irp pending
- //
return STATUS_PENDING;
}
case SRB_FUNCTION_RELEASE_DEVICE:
{
DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n");
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->Claimed == TRUE);
- //
// release claim
- //
PDODeviceExtension->Claimed = FALSE;
Status = STATUS_SUCCESS;
break;
case SRB_FUNCTION_CLAIM_DEVICE:
{
DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n");
- //
+
// check if the device has been claimed
- //
if (PDODeviceExtension->Claimed)
{
- //
// device has already been claimed
- //
Status = STATUS_DEVICE_BUSY;
Request->SrbStatus = SRB_STATUS_BUSY;
break;
}
- //
// claim device
- //
PDODeviceExtension->Claimed = TRUE;
- //
// output device object
- //
Request->DataBuffer = DeviceObject;
- //
- // completed successfully
- //
Status = STATUS_SUCCESS;
break;
}
{
DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n");
- //
- // release queue
- //
USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject);
- //
- // set status success
- //
Request->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS;
break;
//
USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
#endif
- //
- // set status success
- //
+
Request->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS;
break;
}
}
- //
- // complete request
- //
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
ULONG Index;
ULONG LastCharacterPosition = 0;
- //
// scan the field and return last position which contains a valid character
- //
for(Index = 0; Index < MaxLength; Index++)
{
if (Name[Index] != ' ')
{
- //
// trim white spaces from field
- //
LastCharacterPosition = Index;
}
}
- //
// convert from zero based index to length
- //
return LastCharacterPosition + 1;
}
DPRINT("USBSTOR_HandleQueryProperty\n");
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // sanity check
- //
ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY));
ASSERT(Irp->AssociatedIrp.SystemBuffer);
- //
- // get property query
- //
PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
- //
// check property type
- //
if (PropertyQuery->PropertyId != StorageDeviceProperty &&
PropertyQuery->PropertyId != StorageAdapterProperty)
{
- //
// only device property / adapter property are supported
- //
return STATUS_INVALID_PARAMETER_1;
}
- //
// check query type
- //
if (PropertyQuery->QueryType == PropertyExistsQuery)
{
- //
// device property / adapter property is supported
- //
return STATUS_SUCCESS;
}
if (PropertyQuery->QueryType != PropertyStandardQuery)
{
- //
// only standard query and exists query are supported
- //
return STATUS_INVALID_PARAMETER_2;
}
- //
// check if it is a device property
- //
if (PropertyQuery->PropertyId == StorageDeviceProperty)
{
DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
- //
- // get device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension);
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
- //
- // get device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
ASSERT(FDODeviceExtension);
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // get inquiry data
- //
InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
ASSERT(InquiryData);
- //
// compute extra parameters length
- //
FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8);
FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16);
FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
- //
- // is there a serial number
- //
if (FDODeviceExtension->SerialNumber)
{
- //
- // get length
- //
FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
}
else
{
- //
- // no serial number
- //
FieldLengthSerialNumber = 0;
}
- //
// 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
- //
TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
- //
// check if output buffer is long enough
- //
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
{
- //
// buffer too small
- //
DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
- //
// return required size
- //
DescriptorHeader->Version = TotalLength;
DescriptorHeader->Size = TotalLength;
return STATUS_SUCCESS;
}
- //
- // get device descriptor
- //
+ // initialize the device descriptor
DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
- //
- // initialize device descriptor
- //
DeviceDescriptor->Version = TotalLength;
DeviceDescriptor->Size = TotalLength;
DeviceDescriptor->DeviceType = InquiryData->DeviceType;
DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
- //
// copy descriptors
- //
Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR));
- //
- // copy vendor
- //
RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor);
Buffer[FieldLengthVendor] = '\0';
Buffer += FieldLengthVendor + 1;
- //
- // copy product
- //
RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct);
Buffer[FieldLengthProduct] = '\0';
Buffer += FieldLengthProduct + 1;
- //
- // copy revision
- //
RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision);
Buffer[FieldLengthRevision] = '\0';
Buffer += FieldLengthRevision + 1;
- //
- // copy serial number
- //
if (FieldLengthSerialNumber)
{
- //
- // init unicode string
- //
RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
- //
- // init ansi string
- //
AnsiString.Buffer = (PCHAR)Buffer;
AnsiString.Length = 0;
AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
- //
- // convert to ansi code
- //
Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
ASSERT(Status == STATUS_SUCCESS);
}
-
DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
- //
- // done
- //
Irp->IoStatus.Information = TotalLength;
return STATUS_SUCCESS;
}
else
{
- //
// adapter property query request
- //
+
DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR))
{
- //
// buffer too small
- //
DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;
ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER));
- //
// return required size
- //
DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
return STATUS_SUCCESS;
}
- //
// get adapter descriptor, information is returned in the same buffer
- //
AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
- //
// fill out descriptor
- //
AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value
AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
- //
// store returned length
- //
Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
- //
- // done
- //
return STATUS_SUCCESS;
}
}
PINQUIRYDATA ScsiInquiryData;
PUFI_INQUIRY_RESPONSE UFIInquiryResponse;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
- if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY)
+ switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
{
- //
- // query property
- //
- Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
- }
- else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH)
- {
- //
- // query scsi pass through
- //
- DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
- Status = STATUS_NOT_SUPPORTED;
- }
- else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT)
- {
- //
- // query scsi pass through direct
- //
- 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 */
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
- {
- Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(IO_SCSI_CAPABILITIES),
- USB_STOR_TAG);
- Irp->IoStatus.Information = sizeof(PVOID);
- }
- else
+ case IOCTL_STORAGE_QUERY_PROPERTY:
+ Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
+ break;
+ case IOCTL_SCSI_PASS_THROUGH:
+ DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ case IOCTL_SCSI_PASS_THROUGH_DIRECT:
+ DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ case IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER:
+ DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ case IOCTL_SCSI_GET_CAPABILITIES:
{
- Capabilities = Irp->AssociatedIrp.SystemBuffer;
- Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
- }
+ PIO_SCSI_CAPABILITIES Capabilities;
- if (Capabilities)
+ // Legacy port capability query
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
+ {
+ Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(IO_SCSI_CAPABILITIES),
+ USB_STOR_TAG);
+ Irp->IoStatus.Information = sizeof(PVOID);
+ }
+ else
+ {
+ Capabilities = Irp->AssociatedIrp.SystemBuffer;
+ Irp->IoStatus.Information = sizeof(IO_SCSI_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;
- Capabilities->MaximumPhysicalPages = 25;
- Capabilities->SupportedAsynchronousEvents = 0;
- Capabilities->AlignmentMask = 0;
- Capabilities->TaggedQueuing = FALSE;
- Capabilities->AdapterScansDown = FALSE;
- Capabilities->AdapterUsesPio = FALSE;
+ 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;
+
+ 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;
+
+ break;
}
- else
+ case IOCTL_SCSI_GET_ADDRESS:
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- }
- else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_INQUIRY_DATA)
- {
- //
- // get device extension
- //
- PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- ASSERT(PDODeviceExtension);
- ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
+ PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer;
- //
- // 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);
- 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;
- Status = STATUS_SUCCESS;
- }
- else
- {
- //
- // unsupported
- //
- DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
- Status = STATUS_NOT_SUPPORTED;
+ break;
+ }
+ default:
+ DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_NOT_SUPPORTED;
+ break;
}
return Status;
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/error.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>
+
NTSTATUS
USBSTOR_GetEndpointStatus(
IN PDEVICE_OBJECT DeviceObject,
PURB Urb;
NTSTATUS Status;
- //
- // allocate urb
- //
DPRINT("Allocating URB\n");
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if (!Urb)
{
- //
- // out of memory
- //
DPRINT1("OutofMemory!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// build status
- //
- UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL);
+ UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL);
- //
// send the request
- //
DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
- //
- // free urb
- //
FreeItem(Urb);
-
- //
- // done
- //
return Status;
}
-
-
NTSTATUS
USBSTOR_ResetPipeWithHandle(
IN PDEVICE_OBJECT DeviceObject,
PURB Urb;
NTSTATUS Status;
- //
- // allocate urb
- //
DPRINT("Allocating URB\n");
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
if (!Urb)
{
- //
- // out of memory
- //
DPRINT1("OutofMemory!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // initialize the urb
- //
Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
Urb->UrbPipeRequest.Hdr.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL;
Urb->UrbPipeRequest.PipeHandle = PipeHandle;
- //
// send the request
- //
DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
- //
- // free urb
- //
FreeItem(Urb);
-
- //
- // done
- //
return Status;
}
-
NTSTATUS
USBSTOR_HandleTransferError(
PDEVICE_OBJECT DeviceObject,
PSCSI_REQUEST_BLOCK Request;
PCDB pCDB;
- //
- // sanity checks
- //
ASSERT(Context);
ASSERT(Context->PDODeviceExtension);
ASSERT(Context->PDODeviceExtension->Self);
ASSERT(Context->Irp);
- //
// 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);
if (NT_SUCCESS(Status))
{
- //
// step 2 reset bulk in pipe section 5.3.4
- //
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
if (NT_SUCCESS(Status))
{
- //
// finally reset bulk out pipe
- //
Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
}
}
- //
- // get next stack location
- //
Stack = IoGetCurrentIrpStackLocation(Context->Irp);
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
ASSERT(Request);
- //
// obtain request type
- //
pCDB = (PCDB)Request->Cdb;
ASSERT(pCDB);
if (Status != STATUS_SUCCESS || Context->RetryCount >= 1)
{
- //
// Complete the master IRP
- //
Context->Irp->IoStatus.Status = Status;
Context->Irp->IoStatus.Information = 0;
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
- //
// Start the next request
- //
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
- //
// srb handling finished
- //
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
- //
// clear timer srb
- //
Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
}
else
{
DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self);
- //
// re-schedule request
- //
USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1);
- //
// srb error handling finished
- //
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
- //
// srb error handling finished
- //
Context->FDODeviceExtension->TimerWorkQueueEnabled = TRUE;
- //
// clear timer srb
- //
Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
}
- //
- // cleanup irp context
- //
FreeItem(Context->cbw);
FreeItem(Context);
-
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
return Status;
}
NTSTATUS Status;
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
- //
// clear stall on BulkIn pipe
- //
Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
- //
// now resend the csw as the stall got cleared
- //
USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp);
}
if (WorkItemData->Context->ErrorIndex == 2)
{
- //
// reset device
- //
USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
}
else
{
- //
// clear stall
- //
USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData);
}
- //
// Free Work Item Data
- //
ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
}
NTSTATUS Status;
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
- //
- // get device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension;
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
// first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
- //
Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension);
if (NT_SUCCESS(Status))
{
- //
// step 2 reset bulk in pipe section 5.3.4
- //
Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle);
if (NT_SUCCESS(Status))
{
- //
// finally reset bulk out pipe
- //
Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
}
}
DPRINT1("Status %x\n", Status);
- //
// clear timer srb
- //
FDODeviceExtension->LastTimerActiveSrb = NULL;
- //
// re-schedule request
- //
//USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1);
-
-
- //
// do not retry for the same packet again
- //
FDODeviceExtension->TimerWorkQueueEnabled = FALSE;
- //
- // Free Work Item Data
- //
ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
}
-
VOID
NTAPI
USBSTOR_TimerRoutine(
BOOLEAN ResetDevice = FALSE;
PERRORHANDLER_WORKITEM_DATA WorkItemData;
- //
- // get device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
DPRINT1("[USBSTOR] TimerRoutine entered\n");
DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb);
- //
- // acquire spinlock
- //
KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
- //
// is there an active srb and no global reset is in progress
- //
if (FDODeviceExtension->ActiveSrb && FDODeviceExtension->ResetInProgress == FALSE && FDODeviceExtension->TimerWorkQueueEnabled)
{
if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb)
{
- //
// check if empty
- //
DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb);
ResetDevice = TRUE;
}
else
{
- //
// update pointer
- //
FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb;
}
}
else
{
- //
// reset srb
- //
FDODeviceExtension->LastTimerActiveSrb = NULL;
}
- //
- // release lock
- //
KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
USB_STOR_TAG);
if (WorkItemData)
{
- //
// Initialize and queue the work item to handle the error
- //
ExInitializeWorkItem(&WorkItemData->WorkQueueItem,
USBSTOR_TimerWorkerRoutine,
WorkItemData);
/*
* 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)
{
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++)
{
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 */
+ // Send the IRP down the stack
IoSkipCurrentIrpStackLocation(Irp);
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;
NTSTATUS Status;
UCHAR Index = 0;
- //
// 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;
}
- //
// 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));
if (InterfaceDesc->bInterfaceSubClass != 0x06)
{
- //
// 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;
}
- //
// 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;
}
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/misc.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>
-//
-// driver verifier
-//
+
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
NTSTATUS
KEVENT Event;
NTSTATUS Status;
- //
- // initialize event
- //
KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- //
- // copy irp stack location
- //
IoCopyCurrentIrpStackLocationToNext(Irp);
-
- //
- // set completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
-
- //
- // call driver
- //
Status = IoCallDriver(DeviceObject, Irp);
- //
- // check if pending
- //
if (Status == STATUS_PENDING)
{
- //
// wait for the request to finish
- //
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-
- //
- // copy status code
- //
Status = Irp->IoStatus.Status;
}
- //
- // done
- //
return Status;
}
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION Stack;
- //
- // sanity checks
- //
ASSERT(DeviceObject);
ASSERT(BusInterface);
-
- //
- // initialize event
- //
KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- //
- // create irp
- //
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
DeviceObject,
NULL,
NULL,
&Event,
&IoStatus);
-
- //
- // was irp built
- //
if (Irp == NULL)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// initialize request
- //
- Stack=IoGetNextIrpStackLocation(Irp);
+ Stack = IoGetNextIrpStackLocation(Irp);
Stack->MajorFunction = IRP_MJ_PNP;
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- //
- // call driver
- //
- Status= IoCallDriver(DeviceObject, Irp);
+ Status = IoCallDriver(DeviceObject, Irp);
- //
- // did operation complete
- //
if (Status == STATUS_PENDING)
{
- //
- // wait for completion
- //
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-
- //
- // collect status
- //
- Status=IoStatus.Status;
+ Status = IoStatus.Status;
}
return Status;
KEVENT Event;
NTSTATUS Status;
- //
- // allocate irp
- //
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // initialize event
- //
KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- //
- // get next stack location
- //
IoStack = IoGetNextIrpStackLocation(Irp);
- //
// initialize stack location
- //
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length;
Irp->IoStatus.Status = STATUS_SUCCESS;
- //
- // setup completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
- //
- // call driver
- //
Status = IoCallDriver(DeviceObject, Irp);
- //
- // check if request is pending
- //
if (Status == STATUS_PENDING)
{
- //
- // wait for completion
- //
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-
- //
- // update status
- //
Status = Irp->IoStatus.Status;
}
- //
- // free irp
- //
IoFreeIrp(Irp);
-
- //
- // done
- //
return Status;
}
IN POOL_TYPE PoolType,
IN ULONG ItemSize)
{
- //
- // allocate item
- //
PVOID Item = ExAllocatePoolWithTag(PoolType, ItemSize, USB_STOR_TAG);
if (Item)
{
- //
- // zero item
- //
RtlZeroMemory(Item, ItemSize);
}
- //
- // return element
- //
return Item;
}
FreeItem(
IN PVOID Item)
{
- //
- // free item
- //
ExFreePoolWithTag(Item, USB_STOR_TAG);
}
PURB Urb;
NTSTATUS Status;
- //
- // first allocate urb
- //
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if (!Urb)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // initialize vendor request
- //
Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE;
Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags;
Urb->UrbControlVendorClassRequest.Request = RequestType;
Urb->UrbControlVendorClassRequest.Index = Index;
- //
- // submit request
- //
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
- //
- // free urb
- //
FreeItem(Urb);
-
- //
- // done
- //
return Status;
}
-
NTSTATUS
USBSTOR_GetMaxLUN(
IN PDEVICE_OBJECT DeviceObject,
PUCHAR Buffer;
NTSTATUS Status;
- //
- // allocate 1-byte buffer
- //
Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR));
if (!Buffer)
{
- //
- // no memory
- //
FreeItem(Buffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // execute request
- //
Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer);
DPRINT("MaxLUN: %x\n", *Buffer);
{
if (*Buffer > 0xF)
{
- //
// invalid response documented in usb mass storage specification
- //
Status = STATUS_DEVICE_DATA_ERROR;
}
else
{
- //
// store maxlun
- //
DeviceExtension->MaxLUN = *Buffer;
}
}
else
{
- //
// "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0"
// 3.2 Get Max LUN (class-specific request) :
// Devices that do not support multiple LUNs may STALL this command.
- //
USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension);
DeviceExtension->MaxLUN = 0;
Status = STATUS_SUCCESS;
}
- //
- // free buffer
- //
FreeItem(Buffer);
-
- //
- // done
- //
return Status;
-
}
NTSTATUS
{
NTSTATUS Status;
- //
- // execute request
- //
Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL);
-
- //
- // done
- //
return Status;
-
}
BOOLEAN
PUFI_CAPACITY_DESCRIPTOR Descriptor;
ULONG Length, Index, BlockCount, BlockLength;
- //
- // get format header
- //
FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer;
-
- //
- // sanity checks
- //
ASSERT(FormatHeader->Reserved1 == 0x00);
ASSERT(FormatHeader->Reserved2 == 0x00);
ASSERT(FormatHeader->Reserved3 == 0x00);
- //
// is there capacity data
- //
if (!FormatHeader->CapacityLength)
{
- //
- // no data provided
- //
DPRINT1("[USBSTOR] No capacity length\n");
return FALSE;
}
- //
// the format header are always 8 bytes in length
- //
ASSERT((FormatHeader->CapacityLength & 0x7) == 0);
DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength);
- //
// grab length and locate first descriptor
- //
Length = FormatHeader->CapacityLength;
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
- //
BlockCount = NTOHL(Descriptor->BlockCount);
-
- //
- // get block length
- //
BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8));
DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code);
if (BlockLength == 512 && BlockCount == 1440)
{
- //
// 720 KB DD
- //
*MediumTypeCode = 0x1E;
return TRUE;
}
else if (BlockLength == 1024 && BlockCount == 1232)
{
- //
// 1,25 MB
- //
*MediumTypeCode = 0x93;
return TRUE;
}
else if (BlockLength == 512 && BlockCount == 2880)
{
- //
// 1,44MB KB DD
- //
*MediumTypeCode = 0x94;
return TRUE;
}
- //
- // move to next descriptor
- //
- Descriptor = (Descriptor + 1);
+ Descriptor++;
}
- //
- // no floppy detected
- //
return FALSE;
}
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/pdo.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>
+
LPCSTR
USBSTOR_GetDeviceType(
IN PUFI_INQUIRY_RESPONSE InquiryData,
IN UCHAR IsFloppy)
{
- //
- // check if device type is zero
- //
if (InquiryData->DeviceType == 0)
{
if (IsFloppy)
{
- //
// floppy device
- //
return "SFloppy";
}
- //
// direct access device
- //
return "Disk";
}
- //
- // FIXME: use constant - derived from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
- //
switch (InquiryData->DeviceType)
{
case 1:
{
- //
// sequential device, i.e magnetic tape
- //
return "Sequential";
}
case 4:
{
- //
// write once device
- //
return "Worm";
}
case 5:
{
- //
// CDROM device
- //
return "CdRom";
}
case 7:
{
- //
// optical memory device
- //
return "Optical";
}
case 8:
{
- //
// medium change device
- //
return "Changer";
}
default:
{
- //
// other device
- //
return "Other";
}
}
IN PUFI_INQUIRY_RESPONSE InquiryData,
IN UCHAR IsFloppy)
{
- //
- // check if device type is zero
- //
if (InquiryData->DeviceType == 0)
{
if (IsFloppy)
{
- //
// floppy device
- //
return "GenSFloppy";
}
- //
// direct access device
- //
return "GenDisk";
}
- //
- // FIXME: use constant - derived from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
- //
switch (InquiryData->DeviceType)
{
case 1:
{
- //
// sequential device, i.e magnetic tape
- //
return "GenSequential";
}
case 4:
{
- //
// write once device
- //
return "GenWorm";
}
case 5:
{
- //
// CDROM device
- //
return "GenCdRom";
}
case 7:
{
- //
// optical memory device
- //
return "GenOptical";
}
case 8:
{
- //
// medium change device
- //
return "GenChanger";
}
default:
{
- //
// other device
- //
return "UsbstorOther";
}
}
}
-
ULONG
CopyField(
IN PUCHAR Name,
{
ULONG Index;
- for(Index = 0; Index < MaxLength; Index++)
+ for (Index = 0; Index < MaxLength; Index++)
{
if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',')
{
- //
// convert to underscore
- //
Buffer[Index] = '_';
}
else
{
- //
// just copy character
- //
Buffer[Index] = Name[Index];
}
}
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- //PPDO_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IoStack;
LPWSTR Buffer;
static WCHAR DeviceText[] = L"USB Mass Storage Device";
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.QueryDeviceText.DeviceTextType == DeviceTextDescription)
{
DPRINT("USBSTOR_PdoHandleQueryDeviceText DeviceTextDescription\n");
- //
- // allocate item
- //
Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText));
if (!Buffer)
{
- //
- // no memory
- //
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // copy buffer
- //
wcscpy(Buffer, DeviceText);
- //
- // save result
- //
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
return STATUS_SUCCESS;
}
{
DPRINT("USBSTOR_PdoHandleQueryDeviceText DeviceTextLocationInformation\n");
- //
- // allocate item
- //
Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText));
if (!Buffer)
{
- //
- // no memory
- //
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // copy buffer
- //
wcscpy(Buffer, DeviceText);
- //
- // save result
- //
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
return STATUS_SUCCESS;
}
}
-
NTSTATUS
USBSTOR_PdoHandleQueryDeviceId(
IN PDEVICE_OBJECT DeviceObject,
{
PPDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
- CHAR Buffer[100];
+ CHAR Buffer[100] = {0};
LPCSTR DeviceType;
ULONG Offset = 0;
PUFI_INQUIRY_RESPONSE InquiryData;
ANSI_STRING AnsiString;
UNICODE_STRING DeviceId;
- //
- // get device extension
- //
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(DeviceExtension->InquiryData);
-
- //
- // get inquiry data
- //
InquiryData = (PUFI_INQUIRY_RESPONSE)DeviceExtension->InquiryData;
- //
- // get device type
- //
DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy);
- //
- // zero buffer
- //
- RtlZeroMemory(Buffer, sizeof(Buffer));
-
- //
// lets create device string
- //
Offset = sprintf(&Buffer[Offset], "USBSTOR\\");
Offset += sprintf(&Buffer[Offset], DeviceType);
Offset += sprintf(&Buffer[Offset], "&Ven_");
Offset += sprintf(&Buffer[Offset], "&Rev_");
Offset += CopyField(InquiryData->Revision, &Buffer[Offset], 4);
- //
- // now initialize ansi string
- //
RtlInitAnsiString(&AnsiString, (PCSZ)Buffer);
- //
// allocate DeviceId string
- //
DeviceId.Length = 0;
DeviceId.MaximumLength = (strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR);
DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength);
if (!DeviceId.Buffer)
{
- //
- // no memory
- //
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
-
- //
- // convert to unicode
- //
Status = RtlAnsiStringToUnicodeString(&DeviceId, &AnsiString, FALSE);
if (NT_SUCCESS(Status))
{
- //
- // store result
- //
Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer;
}
DPRINT("DeviceId %wZ Status %x\n", &DeviceId, Status);
- //
- // done
- //
return Status;
}
DPRINT("ResultBufferOffset %lu ResultBufferLength %lu Buffer %s Length %lu\n", ResultBufferOffset, ResultBufferLength, Buffer, strlen(Buffer));
- //
// construct destination string
- //
DeviceString.Buffer = &ResultBuffer[ResultBufferOffset];
DeviceString.Length = 0;
DeviceString.MaximumLength = (ResultBufferLength - ResultBufferOffset) * sizeof(WCHAR);
- //
// initialize source string
- //
RtlInitAnsiString(&AnsiString, Buffer);
- //
- // convert to unicode
- //
Status = RtlAnsiStringToUnicodeString(&DeviceString, &AnsiString, FALSE);
ASSERT(Status == STATUS_SUCCESS);
- //
// subtract consumed bytes
- //
ResultBufferLength -= (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
ResultBufferOffset += (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
- //
- // store new offset
- //
*NewResultBufferOffset = ResultBufferOffset;
}
-
-
NTSTATUS
USBSTOR_PdoHandleQueryHardwareId(
IN PDEVICE_OBJECT DeviceObject,
ULONG Offset, TotalLength, Length;
PUFI_INQUIRY_RESPONSE InquiryData;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->DeviceDescriptor);
-
- //
- // get inquiry data
- //
InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
-
- //
- // get device type and generic type
- //
DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy);
GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy);
ASSERT(GenericType);
- //
// generate id 1
// USBSTOR\SCSIType_Vendor(8)_Product(16)_Revision(4)
- //
RtlZeroMemory(Id1, sizeof(Id1));
Offset = 0;
Offset = sprintf(&Id1[Offset], "USBSTOR\\");
Id1Length = strlen(Id1) + 1;
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
- //
// generate id 2
// USBSTOR\SCSIType_VENDOR(8)_Product(16)
- //
RtlZeroMemory(Id2, sizeof(Id2));
Offset = 0;
Offset = sprintf(&Id2[Offset], "USBSTOR\\");
Id2Length = strlen(Id2) + 1;
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
- //
// generate id 3
// USBSTOR\SCSIType_VENDOR(8)
- //
RtlZeroMemory(Id3, sizeof(Id3));
Offset = 0;
Offset = sprintf(&Id3[Offset], "USBSTOR\\");
Id3Length = strlen(Id3) + 1;
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
- //
// generate id 4
// USBSTOR\SCSIType_VENDOR(8)_Product(16)_Revision(1)
- //
RtlZeroMemory(Id4, sizeof(Id4));
Offset = 0;
Offset = sprintf(&Id4[Offset], "USBSTOR\\");
Id4Length = strlen(Id4) + 1;
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
- //
// generate id 5
// USBSTOR\SCSIType
- //
RtlZeroMemory(Id5, sizeof(Id5));
Offset = 0;
Offset = sprintf(&Id5[Offset], "USBSTOR\\");
Id5Length = strlen(Id5) + 1;
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId5 %s\n", Id5);
- //
// generate id 6
// SCSIType
- //
RtlZeroMemory(Id6, sizeof(Id6));
Offset = 0;
Offset = sprintf(&Id6[Offset], GenericType);
Id6Length = strlen(Id6) + 1;
DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId6 %s\n", Id6);
- //
- // compute total length
- //
TotalLength = Id1Length + Id2Length + Id3Length + Id4Length + Id5Length + Id6Length + 1;
- //
- // allocate buffer
- //
Buffer = (LPWSTR)AllocateItem(PagedPool, TotalLength * sizeof(WCHAR));
if (!Buffer)
{
- //
- // no memory
- //
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// reset offset
- //
Offset = 0;
Length = TotalLength;
USBSTOR_ConvertToUnicodeString(Id5, Length, Offset, Buffer, &Offset);
USBSTOR_ConvertToUnicodeString(Id6, Length, Offset, Buffer, &Offset);
- //
- // sanity check
- //
ASSERT(Offset + 1 == Length);
- //
- // store result
- //
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
-
- //
- // done
- //
return STATUS_SUCCESS;
}
{
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- CHAR Buffer[100];
+ CHAR Buffer[100] = {0};
ULONG Length, Offset;
LPWSTR InstanceId;
LPCSTR DeviceType;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->DeviceDescriptor);
-
- //
- // get target device type
- //
DeviceType = USBSTOR_GetDeviceType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy);
- //
- // zero memory
- //
- RtlZeroMemory(Buffer, sizeof(Buffer));
-
- //
// format instance id
- //
Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
Length += sprintf(&Buffer[Length], "USBSTOR\\%s", "RAW") + 2;
- //
- // allocate instance id
- //
InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
if (!InstanceId)
{
- //
- // no memory
- //
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
DPRINT("USBSTOR_PdoHandleQueryCompatibleId %S\n", InstanceId);
- //
- // store result
- //
Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
-
- //
- // completed successfully
- //
return STATUS_SUCCESS;
}
ULONG Length;
LPWSTR InstanceId;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
- //
// format instance id
- //
if (FDODeviceExtension->SerialNumber)
{
- //
// using serial number from device
- //
swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN);
}
else
{
- //
// use instance count and LUN
- //
swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
}
- //
- // calculate length
- //
Length = wcslen(Buffer) + 1;
- //
- // allocate instance id
- //
InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
if (!InstanceId)
{
- //
- // no memory
- //
Irp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // copy instance id
- //
wcscpy(InstanceId, Buffer);
DPRINT("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId);
- //
- // store result
- //
Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
-
- //
- // completed successfully
- //
return STATUS_SUCCESS;
}
DPRINT("USBSTOR_PdoHandleDeviceRelations\n");
- //
- // get current irp stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
- //
// check if relation type is BusRelations
- //
if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
{
- //
// PDO handles only target device relation
- //
return Irp->IoStatus.Status;
}
- //
- // allocate device relations
- //
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
if (!DeviceRelations)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// initialize device relations
- //
DeviceRelations->Count = 1;
DeviceRelations->Objects[0] = DeviceObject;
ObReferenceObject(DeviceObject);
- //
- // store result
- //
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
-
- //
- // completed successfully
- //
return STATUS_SUCCESS;
}
-
NTSTATUS
USBSTOR_PdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
PDEVICE_CAPABILITIES Caps;
ULONG bDelete;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get device extension
- //
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(DeviceExtension->Common.IsFDO == FALSE);
switch(IoStack->MinorFunction)
{
if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
{
- //
- // handle query device id
- //
Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp);
break;
}
else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
{
- //
- // handle instance id
- //
Status = USBSTOR_PdoHandleQueryHardwareId(DeviceObject, Irp);
break;
}
else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
{
- //
- // handle instance id
- //
Status = USBSTOR_PdoHandleQueryInstanceId(DeviceObject, Irp);
break;
}
else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
{
- //
- // handle instance id
- //
Status = USBSTOR_PdoHandleQueryCompatibleId(DeviceObject, Irp);
break;
}
if(*DeviceExtension->PDODeviceObject != NULL)
{
- //
- // clear entry in FDO pdo list
- //
*DeviceExtension->PDODeviceObject = NULL;
bDelete = TRUE;
}
else
{
- //
// device object already marked for deletion
- //
bDelete = FALSE;
}
- /* Complete the IRP */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (bDelete)
{
- /* Delete the device object */
IoDeleteDevice(DeviceObject);
}
return STATUS_SUCCESS;
}
case IRP_MN_QUERY_CAPABILITIES:
{
- //
// just forward irp to lower device
- //
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
ASSERT(Status == STATUS_SUCCESS);
if (NT_SUCCESS(Status))
{
- //
// check if no unique id
- //
Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
Caps->UniqueID = FALSE; // no unique id is supported
Caps->Removable = TRUE; //FIXME
}
case IRP_MN_START_DEVICE:
{
- //
// no-op for PDO
- //
Status = STATUS_SUCCESS;
break;
}
}
default:
{
- //
// do nothing
- //
Status = Irp->IoStatus.Status;
}
}
- //
- // complete request
- //
if (Status != STATUS_PENDING)
{
- //
- // store result
- //
Irp->IoStatus.Status = Status;
-
- //
- // complete request
- //
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
- //
- // done processing
- //
return Status;
}
{
PKEVENT Event = (PKEVENT)Ctx;
- //
- // signal event
- //
KeSetEvent(Event, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
PSCSI_REQUEST_BLOCK Request;
PCDB pCDB;
- //
- // allocate irp
- //
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // get next stack location
- //
IoStack = IoGetNextIrpStackLocation(Irp);
- //
- // create scsi block
- //
Request = ExAllocatePoolWithTag(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK),
USB_STOR_TAG);
if (!Request)
{
- //
- // no memory
- //
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // init request
- //
RtlZeroMemory(Request, sizeof(SCSI_REQUEST_BLOCK));
- //
// allocate data transfer block
- //
Request->DataBuffer = ExAllocatePoolWithTag(NonPagedPool,
DataTransferLength,
USB_STOR_TAG);
if (!Request->DataBuffer)
{
- //
- // no memory
- //
IoFreeIrp(Irp);
ExFreePoolWithTag(Request, USB_STOR_TAG);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // allocate MDL
- //
Irp->MdlAddress = IoAllocateMdl(Request->DataBuffer, DataTransferLength, FALSE, FALSE, NULL);
if (!Irp->MdlAddress)
{
- //
- // no memory
- //
IoFreeIrp(Irp);
ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG);
ExFreePoolWithTag(Request, USB_STOR_TAG);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // non paged pool
- //
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
- //
- // init scsi block
- //
Request->DataTransferLength = DataTransferLength;
Request->Function = SRB_FUNCTION_EXECUTE_SCSI;
Request->SrbFlags = SRB_FLAGS_DATA_IN;
RtlZeroMemory(Request->DataBuffer, DataTransferLength);
-
- //
// get SCSI command data block
- //
pCDB = (PCDB)Request->Cdb;
- //
// set op code
- //
pCDB->AsByte[0] = OpCode;
- //
// store result
- //
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.Others.Argument1 = Request;
IoStack->DeviceObject = DeviceObject;
- //
- // init event
- //
KeInitializeEvent(Event, NotificationEvent, FALSE);
- //
- // lets setup a completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_CompletionRoutine, (PVOID)Event, TRUE, TRUE, TRUE);
- //
- // output result
- //
*OutIrp = Irp;
*OutRequest = Request;
return STATUS_SUCCESS;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PSCSI_REQUEST_BLOCK Request;
- //
- // let's allocate an irp
- //
Status = USBSTOR_AllocateIrp(PDODeviceObject, DataTransferLength, OpCode, &Event, &Request, &Irp);
if (!NT_SUCCESS(Status))
{
- //
- // failed
- //
DPRINT1("[USBSTOR] Failed to build irp\n");
return Status;
}
- //
- // get device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
- //
- // send irp
- //
ASSERT(Irp);
ASSERT(PDODeviceExtension->LowerDeviceObject);
Status = IoCallDriver(PDODeviceExtension->Self, Irp);
if (Status == STATUS_PENDING)
{
- //
- // wait for completion
- //
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = Irp->IoStatus.Status;
}
if (NT_SUCCESS(Status))
{
- //
- // store result
- //
*OutData = Request->DataBuffer;
}
else
{
- //
- // free the data
- //
ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG);
*OutData = NULL;
}
- //
- // free resources
- //
ExFreePoolWithTag(Request, USB_STOR_TAG);
IoFreeMdl(Irp->MdlAddress);
IoFreeIrp(Irp);
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUFI_INQUIRY_RESPONSE Response;
- //
- // get device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
- //
- // send request
- //
Status = USBSTOR_SendIrp(PDODeviceObject, sizeof(UFI_INQUIRY_RESPONSE), SCSIOP_INQUIRY, (PVOID*)&Response);
if (!NT_SUCCESS(Status))
{
- //
- // command failed
- //
DPRINT1("USBSTOR_SendInquiryIrp Failed with %x\n", Status);
return Status;
}
DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], Response->Revision[1], Response->Revision[2], Response->Revision[3]);
- //
- // store result
- //
PDODeviceExtension->InquiryData = (PVOID)Response;
return Status;
}
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUCHAR Response;
- //
- // get device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
- //
- // send request
- //
Status = USBSTOR_SendIrp(PDODeviceObject, 0xFC, SCSIOP_READ_FORMATTED_CAPACITY, (PVOID*)&Response);
if (!NT_SUCCESS(Status))
{
- //
- // command failed
- //
return Status;
}
- //
- // check if its a floppy
- //
PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(Response, 0xFC /*FIXME*/, &PDODeviceExtension->MediumTypeCode);
- //
- // free response
- //
ExFreePoolWithTag(Response, USB_STOR_TAG);
return Status;
}
-
-
NTSTATUS
USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject,
PUFI_INQUIRY_RESPONSE Response;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
// create child device object
- //
Status = IoCreateDevice(DeviceObject->DriverObject, sizeof(PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_MASS_STORAGE, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &PDO);
if (!NT_SUCCESS(Status))
{
- //
- // failed to create device
- //
return Status;
}
- //
// patch the stack size
- //
PDO->StackSize = DeviceObject->StackSize;
- //
- // get device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension;
- //
// initialize device extension
- //
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
PDODeviceExtension->Common.IsFDO = FALSE;
PDODeviceExtension->LowerDeviceObject = DeviceObject;
PDODeviceExtension->Self = PDO;
PDODeviceExtension->LUN = LUN;
- //
- // set device flags
- //
PDO->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER;
- //
// device is initialized
- //
PDO->Flags &= ~DO_DEVICE_INITIALIZING;
- //
// output device object
- //
FDODeviceExtension->ChildPDO[LUN] = PDO;
- //
// send inquiry command by irp
- //
Status = USBSTOR_SendInquiryIrp(PDO);
ASSERT(Status == STATUS_SUCCESS);
- //
- // check response data
- //
Response = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
ASSERT(Response);
if (Response->DeviceType == 0)
{
- //
// check if it is a floppy
- //
Status = USBSTOR_SendFormatCapacityIrp(PDO);
-
- //
- // display result
- //
DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode);
- //
// failing command is non critical
- //
Status = STATUS_SUCCESS;
}
- //
- // done
- //
return Status;
}
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/queue.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_QueueInitialize(
PFDO_DEVICE_EXTENSION FDODeviceExtension)
{
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
-
- //
- // initialize queue lock
- //
KeInitializeSpinLock(&FDODeviceExtension->IrpListLock);
-
- //
- // initialize irp list head
- //
InitializeListHead(&FDODeviceExtension->IrpListHead);
-
- //
- // initialize event
- //
KeInitializeEvent(&FDODeviceExtension->NoPendingRequests, NotificationEvent, TRUE);
}
{
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
// this IRP isn't in our list here
- //
-
- //
// now release the cancel lock
- //
IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- //
- // set cancel status
- //
Irp->IoStatus.Status = STATUS_CANCELLED;
- //
- // now cancel the irp
- //
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- //
- // start the next one
- //
USBSTOR_QueueNextRequest(DeviceObject);
}
{
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire irp list lock
- //
KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
-
- //
- // remove the irp from the list
- //
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
-
- //
- // release irp list lock
- //
KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
- //
- // now release the cancel lock
- //
IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- //
- // set cancel status
- //
Irp->IoStatus.Status = STATUS_CANCELLED;
- //
- // now cancel the irp
- //
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- //
- // start the next one
- //
USBSTOR_QueueNextRequest(DeviceObject);
}
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // mark irp pending
- //
IoMarkIrpPending(Irp);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // check if there are irp pending
- //
SrbProcessing = FDODeviceExtension->IrpPendingCount != 0;
if (SrbProcessing)
{
- //
// add irp to queue
- //
InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry);
}
- //
- // increment pending count
- //
FDODeviceExtension->IrpPendingCount++;
-
-
- //
- // clear the no requests pending event
- //
KeClearEvent(&FDODeviceExtension->NoPendingRequests);
- //
// check if queue is freezed
- //
IrpListFreeze = FDODeviceExtension->IrpListFreeze;
- //
- // release list lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
// synchronize with cancellations by holding the cancel lock
- //
IoAcquireCancelSpinLock(&Irp->CancelIrql);
- //
- // now set the driver cancel routine
- //
if (SrbProcessing)
{
ASSERT(FDODeviceExtension->ActiveSrb != NULL);
OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
}
- //
// check if the irp has already been cancelled
- //
if (Irp->Cancel && OldDriverCancel == NULL)
{
- //
// cancel irp
- //
Irp->CancelRoutine(DeviceObject, Irp);
-
- //
- // irp was cancelled
- //
return FALSE;
}
- //
- // release the cancel lock
- //
IoReleaseCancelSpinLock(Irp->CancelIrql);
- //
// if list is freezed, dont start this packet
- //
DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);
return (IrpListFreeze || SrbProcessing);
PLIST_ENTRY Entry;
PIRP Irp = NULL;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // check if list is empty
- //
if (!IsListEmpty(&FDODeviceExtension->IrpListHead))
{
- //
- // remove entry
- //
Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead);
- //
// get offset to start of irp
- //
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
}
- //
- // release list lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
- // return result
- //
return Irp;
}
{
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
- // perform the wait
- //
KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests,
Executive,
KernelMode,
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FDODeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // decrement pending irp count
- //
FDODeviceExtension->IrpPendingCount--;
- //
// check if this was our current active SRB
- //
if (FDODeviceExtension->ActiveSrb == Request)
{
- //
// indicate processing is completed
- //
FDODeviceExtension->ActiveSrb = NULL;
}
- //
// Set the event if nothing else is pending
- //
if (FDODeviceExtension->IrpPendingCount == 0 &&
FDODeviceExtension->ActiveSrb == NULL)
{
KeSetEvent(&FDODeviceExtension->NoPendingRequests, IO_NO_INCREMENT, FALSE);
}
- //
- // release lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
-
}
VOID
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get pdo device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
// check first if there's already a request pending or the queue is frozen
- //
if (FDODeviceExtension->ActiveSrb != NULL ||
FDODeviceExtension->IrpListFreeze)
{
- //
// no work to do yet
- //
return;
}
- //
// remove first irp from list
- //
Irp = USBSTOR_RemoveIrp(DeviceObject);
- //
// is there an irp pending
- //
if (!Irp)
{
- //
// no work to do
- //
IoStartNextPacket(DeviceObject, TRUE);
return;
}
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get srb
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
-
- //
- // sanity check
- //
ASSERT(Request);
- //
- // set the active SRB
- //
FDODeviceExtension->ActiveSrb = Request;
- //
// start next packet
- //
IoStartPacket(DeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
-
- //
- // start next request
- //
IoStartNextPacket(DeviceObject, TRUE);
}
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
// clear freezed status
- //
FDODeviceExtension->IrpListFreeze = FALSE;
- //
- // release irp list lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
// grab newest irp
- //
Irp = USBSTOR_RemoveIrp(DeviceObject);
- //
- // is there an irp
- //
if (!Irp)
{
- //
- // no irp
- //
return;
}
- //
- // get current irp stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get srb
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // start new packet
- //
IoStartPacket(DeviceObject,
Irp,
&Request->QueueSortKey,
USBSTOR_CancelIo);
}
-
VOID
NTAPI
USBSTOR_StartIo(
DPRINT("USBSTOR_StartIo\n");
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire cancel spinlock
- //
IoAcquireCancelSpinLock(&OldLevel);
- //
- // set cancel routine to zero
- //
IoSetCancelRoutine(Irp, NULL);
- //
// check if the irp has been cancelled
- //
if (Irp->Cancel)
{
- //
- // irp has been cancelled, release cancel spinlock
- //
IoReleaseCancelSpinLock(OldLevel);
- //
- // irp is cancelled
- //
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
- //
- // terminate request
- //
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
-
- //
- // complete request
- //
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- //
- // queue next request
- //
USBSTOR_QueueNextRequest(DeviceObject);
-
- //
- // done
- //
return;
}
- //
- // release cancel spinlock
- //
IoReleaseCancelSpinLock(OldLevel);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // check reset is in progress
- //
ResetInProgress = FDODeviceExtension->ResetInProgress;
ASSERT(ResetInProgress == FALSE);
- //
- // release lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
- // get current irp stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
- //
- // get pdo device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
- //
- // is a reset in progress
- //
+ // TODO: this condition is always false
if (ResetInProgress)
{
- //
// hard reset is in progress
- //
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
return;
}
- //
- // execute scsi
- //
USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp, 0);
- //
// FIXME: handle error
- //
}
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/pdo.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>
+
NTSTATUS
USBSTOR_BuildCBW(
IN ULONG Tag,
IN PUCHAR CommandBlock,
IN OUT PCBW Control)
{
- //
- // sanity check
- //
ASSERT(CommandBlockLength <= 16);
- //
- // now initialize CBW
- //
Control->Signature = CBW_SIGNATURE;
Control->Tag = Tag;
Control->DataTransferLength = DataTransferLength;
Control->LUN = (LUN & MAX_LUN);
Control->CommandBlockLength = CommandBlockLength;
- //
- // copy command block
- //
RtlCopyMemory(Control->CommandBlock, CommandBlock, CommandBlockLength);
- //
- // done
- //
return STATUS_SUCCESS;
}
{
PIRP_CONTEXT Context;
- //
- // allocate irp context
- //
Context = (PIRP_CONTEXT)AllocateItem(NonPagedPool, sizeof(IRP_CONTEXT));
if (!Context)
{
- //
- // no memory
- //
return NULL;
}
- //
- // allocate cbw block
- //
Context->cbw = (PCBW)AllocateItem(NonPagedPool, 512);
if (!Context->cbw)
{
- //
- // no memory
- //
FreeItem(Context);
return NULL;
}
- //
- // done
- //
return Context;
-
}
BOOLEAN
USBSTOR_IsCSWValid(
PIRP_CONTEXT Context)
{
- //
- // sanity checks
- //
if (Context->csw->Signature != CSW_SIGNATURE)
{
DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw->Signature);
return FALSE;
}
- //
- // CSW is valid
- //
return TRUE;
-
}
NTSTATUS
{
PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData;
- //
- // Allocate Work Item Data
- //
ErrorHandlerWorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA), USB_STOR_TAG);
if (!ErrorHandlerWorkItemData)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// error handling started
- //
Context->FDODeviceExtension->SrbErrorHandlingActive = TRUE;
- //
// srb error handling finished
- //
Context->FDODeviceExtension->TimerWorkQueueEnabled = FALSE;
- //
// Initialize and queue the work item to handle the error
- //
ExInitializeWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem,
ErrorHandlerWorkItemRoutine,
ErrorHandlerWorkItemData);
return STATUS_MORE_PROCESSING_REQUIRED;
}
-
-//
-// driver verifier
-//
IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine;
NTSTATUS
PUFI_CAPACITY_RESPONSE Response;
NTSTATUS Status;
- //
- // access context
- //
Context = (PIRP_CONTEXT)Ctx;
- //
- // is there a mdl
- //
if (Context->TransferBufferMDL)
{
- //
// is there an irp associated
- //
if (Context->Irp)
{
- //
// did we allocate the mdl
- //
if (Context->TransferBufferMDL != Context->Irp->MdlAddress)
{
- //
- // free mdl
- //
IoFreeMdl(Context->TransferBufferMDL);
}
}
else
{
- //
- // free mdl
- //
IoFreeMdl(Context->TransferBufferMDL);
}
}
{
if (Context->ErrorIndex == 0)
{
- //
- // increment error index
- //
Context->ErrorIndex = 1;
- //
// clear stall and resend cbw
- //
Status = USBSTOR_QueueWorkItem(Context, Irp);
ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED);
return STATUS_MORE_PROCESSING_REQUIRED;
}
- //
// perform reset recovery
- //
Context->ErrorIndex = 2;
IoFreeIrp(Irp);
Status = USBSTOR_QueueWorkItem(Context, NULL);
if (!USBSTOR_IsCSWValid(Context))
{
- //
// perform reset recovery
- //
Context->ErrorIndex = 2;
IoFreeIrp(Irp);
Status = USBSTOR_QueueWorkItem(Context, NULL);
}
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Context->Irp);
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
ASSERT(Request);
Status = Irp->IoStatus.Status;
- //
- // get SCSI command data block
- //
pCDB = (PCDB)Request->Cdb;
Request->SrbStatus = SRB_STATUS_SUCCESS;
- //
// read capacity needs special work
- //
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
{
- //
// get output buffer
- //
Response = (PUFI_CAPACITY_RESPONSE)Context->TransferData;
- //
// store in pdo
- //
Context->PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
Context->PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
if (Request->DataTransferLength == sizeof(READ_CAPACITY_DATA_EX))
{
- //
// get input buffer
- //
CapacityDataEx = (PREAD_CAPACITY_DATA_EX)Request->DataBuffer;
- //
// set result
- //
CapacityDataEx->BytesPerBlock = Response->BlockLength;
CapacityDataEx->LogicalBlockAddress.QuadPart = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA_EX);
}
else
{
- //
// get input buffer
- //
CapacityData = (PREAD_CAPACITY_DATA)Request->DataBuffer;
- //
// set result
- //
CapacityData->BytesPerBlock = Response->BlockLength;
CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA);
}
- //
- // free response
- //
FreeItem(Context->TransferData);
}
- //
- // free cbw
- //
FreeItem(Context->cbw);
- //
// FIXME: check status
- //
Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
Context->Irp->IoStatus.Information = Context->TransferDataLength;
- //
// terminate current request
- //
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
- //
- // complete request
- //
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
- //
- // start next request
- //
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
- //
- // free our allocated irp
- //
IoFreeIrp(Irp);
-
- //
- // free context
- //
FreeItem(Context);
-
- //
- // done
- //
return STATUS_MORE_PROCESSING_REQUIRED;
}
{
PIO_STACK_LOCATION IoStack;
- //
- // get next irp stack location
- //
IoStack = IoGetNextIrpStackLocation(Irp);
- //
// now initialize the urb for sending the csw
- //
UsbBuildInterruptOrBulkTransferRequest(&Context->Urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL);
- //
// initialize stack location
- //
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)&Context->Urb;
IoStack->Parameters.DeviceIoControl.InputBufferLength = Context->Urb.UrbHeader.Length;
Irp->IoStatus.Status = STATUS_SUCCESS;
-
- //
- // setup completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_CSWCompletionRoutine, Context, TRUE, TRUE, TRUE);
- //
- // call driver
- //
IoCallDriver(Context->FDODeviceExtension->LowerDeviceObject, Irp);
}
-
-//
-// driver verifier
-//
IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine;
NTSTATUS
DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
- //
- // access context
- //
Context = (PIRP_CONTEXT)Ctx;
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
- //
// clear stall and resend cbw
- //
Context->ErrorIndex = 1;
Status = USBSTOR_QueueWorkItem(Context, Irp);
ASSERT(Status == STATUS_MORE_PROCESSING_REQUIRED);
return STATUS_MORE_PROCESSING_REQUIRED;
}
- //
- // send csw
- //
USBSTOR_SendCSW(Context, Irp);
- //
- // cancel completion
- //
return STATUS_MORE_PROCESSING_REQUIRED;
}
-//
-// driver verifier
-//
IO_COMPLETION_ROUTINE USBSTOR_CBWCompletionRoutine;
NTSTATUS
DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
- //
- // access context
- //
Context = (PIRP_CONTEXT)Ctx;
-
- //
- // get next stack location
- //
IoStack = IoGetNextIrpStackLocation(Irp);
- //
// is there data to be submitted
- //
if (Context->TransferDataLength)
{
- //
// get command code
- //
Code = Context->cbw->CommandBlock[0];
if (Code == SCSIOP_WRITE)
{
- //
- // write request use bulk out pipe
- //
+ // write request - use bulk out pipe
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
}
else
{
- //
// default bulk in pipe
- //
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
}
- //
// now initialize the urb for sending data
- //
UsbBuildInterruptOrBulkTransferRequest(&Context->Urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
((Code == SCSIOP_WRITE) ? USBD_TRANSFER_DIRECTION_OUT : (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK)),
NULL);
- //
- // setup completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_DataCompletionRoutine, Context, TRUE, TRUE, TRUE);
}
else
{
- //
// now initialize the urb for sending the csw
- //
-
UsbBuildInterruptOrBulkTransferRequest(&Context->Urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL);
- //
- // setup completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_CSWCompletionRoutine, Context, TRUE, TRUE, TRUE);
}
- //
// initialize stack location
- //
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)&Context->Urb;
IoStack->Parameters.DeviceIoControl.InputBufferLength = Context->Urb.UrbHeader.Length;
Irp->IoStatus.Status = STATUS_SUCCESS;
- //
- // call driver
- //
IoCallDriver(Context->FDODeviceExtension->LowerDeviceObject, Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
{
PIO_STACK_LOCATION IoStack;
- //
- // get next stack location
- //
IoStack = IoGetNextIrpStackLocation(Irp);
- //
// initialize stack location
- //
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)&Context->Urb;
IoStack->Parameters.DeviceIoControl.InputBufferLength = Context->Urb.UrbHeader.Length;
Irp->IoStatus.Status = STATUS_SUCCESS;
- //
- // setup completion routine
- //
IoSetCompletionRoutine(Irp, USBSTOR_CBWCompletionRoutine, Context, TRUE, TRUE, TRUE);
- //
- // call driver
- //
return IoCallDriver(Context->FDODeviceExtension->LowerDeviceObject, Irp);
}
PIRP Irp;
PUCHAR MdlVirtualAddress;
- //
- // first allocate irp context
- //
Context = USBSTOR_AllocateIrpContext();
if (!Context)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
- //
- // now build the cbw
- //
USBSTOR_BuildCBW(PtrToUlong(Context->cbw),
TransferDataLength,
PDODeviceExtension->LUN,
DPRINT("CBW %p\n", Context->cbw);
DumpCBW((PUCHAR)Context->cbw);
- //
// now initialize the urb
- //
UsbBuildInterruptOrBulkTransferRequest(&Context->Urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle,
USBD_TRANSFER_DIRECTION_OUT,
NULL);
- //
// initialize rest of context
- //
Context->Irp = OriginalRequest;
Context->TransferData = TransferData;
Context->TransferDataLength = TransferDataLength;
Context->PDODeviceExtension = PDODeviceExtension;
Context->RetryCount = RetryCount;
- //
// is there transfer data
- //
if (Context->TransferDataLength)
{
- //
// check if the original request already does have an mdl associated
- //
if (OriginalRequest)
{
if ((OriginalRequest->MdlAddress != NULL) &&
(Context->TransferData == NULL || Command[0] == SCSIOP_READ || Command[0] == SCSIOP_WRITE))
{
- //
// Sanity check that the Mdl does describe the TransferData for read/write
- //
if (CommandLength == UFI_READ_WRITE_CMD_LEN)
{
MdlVirtualAddress = MmGetMdlVirtualAddress(OriginalRequest->MdlAddress);
- //
// is there an offset
- //
if (MdlVirtualAddress != Context->TransferData)
{
- //
// lets build an mdl
- //
Context->TransferBufferMDL = IoAllocateMdl(Context->TransferData, MmGetMdlByteCount(OriginalRequest->MdlAddress), FALSE, FALSE, NULL);
if (!Context->TransferBufferMDL)
{
- //
- // failed to allocate MDL
- //
FreeItem(Context->cbw);
FreeItem(Context);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // now build the partial mdl
- //
IoBuildPartialMdl(OriginalRequest->MdlAddress, Context->TransferBufferMDL, Context->TransferData, Context->TransferDataLength);
}
}
if (!Context->TransferBufferMDL)
{
- //
// I/O paging request
- //
Context->TransferBufferMDL = OriginalRequest->MdlAddress;
}
}
else
{
- //
// allocate mdl for buffer, buffer must be allocated from NonPagedPool
- //
Context->TransferBufferMDL = IoAllocateMdl(Context->TransferData, Context->TransferDataLength, FALSE, FALSE, NULL);
if (!Context->TransferBufferMDL)
{
- //
- // failed to allocate MDL
- //
FreeItem(Context->cbw);
FreeItem(Context);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // build mdl for nonpaged pool
- //
MmBuildMdlForNonPagedPool(Context->TransferBufferMDL);
}
}
else
{
- //
// allocate mdl for buffer, buffer must be allocated from NonPagedPool
- //
Context->TransferBufferMDL = IoAllocateMdl(Context->TransferData, Context->TransferDataLength, FALSE, FALSE, NULL);
if (!Context->TransferBufferMDL)
{
- //
- // failed to allocate MDL
- //
FreeItem(Context->cbw);
FreeItem(Context);
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
- // build mdl for nonpaged pool
- //
MmBuildMdlForNonPagedPool(Context->TransferBufferMDL);
}
}
- //
- // now allocate the request
- //
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
{
if (OriginalRequest)
{
- //
- // mark orignal irp as pending
- //
IoMarkIrpPending(OriginalRequest);
}
- //
- // send request
- //
USBSTOR_SendCBW(Context, Irp);
- //
- // done
- //
return STATUS_PENDING;
}
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
// initialize inquiry cmd
- //
RtlZeroMemory(&Cmd, sizeof(UFI_READ_FORMAT_CAPACITY));
Cmd.Code = SCSIOP_READ_FORMATTED_CAPACITY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.AllocationLengthMsb = HTONS(Request->DataTransferLength & 0xFFFF) >> 8;
Cmd.AllocationLengthLsb = HTONS(Request->DataTransferLength & 0xFFFF) & 0xFF;
- //
- // now send the request
- //
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_FORMAT_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
-
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
// initialize inquiry cmd
- //
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_INQUIRY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
- //
- // sanity check
- //
ASSERT(Request->DataTransferLength >= sizeof(UFI_INQUIRY_RESPONSE));
- //
- // now send the request
- //
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
PUFI_CAPACITY_RESPONSE Response;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
- // allocate capacity response
- //
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, PAGE_SIZE);
if (!Response)
{
- //
- // no memory
- //
return STATUS_INSUFFICIENT_RESOURCES;
}
- //
// initialize capacity cmd
- //
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_READ_CAPACITY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
- //
- // send request, response will be freed in completion routine
- //
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), (PUCHAR)Response, RetryCount);
}
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
RtlZeroMemory(Request->DataBuffer, Request->DataTransferLength);
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- //
- // start next request
- //
USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
return STATUS_SUCCESS;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // get SCSI command data block
- //
pCDB = (PCDB)Request->Cdb;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
- // informal debug print
- //
DPRINT("USBSTOR_SendReadWrite DataTransferLength %lu, BlockLength %lu\n", Request->DataTransferLength, PDODeviceExtension->BlockLength);
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->BlockLength);
- //
- // block count
- //
BlockCount = Request->DataTransferLength / PDODeviceExtension->BlockLength;
- //
// initialize read cmd
- //
RtlZeroMemory(&Cmd, sizeof(UFI_READ_WRITE_CMD));
Cmd.Code = pCDB->AsByte[0];
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.LogicalBlockByte2 = pCDB->CDB10.LogicalBlockByte2;
Cmd.LogicalBlockByte3 = pCDB->CDB10.LogicalBlockByte3;
- //
- // sanity check
- //
Temp = (Cmd.ContiguousLogicBlocksByte0 << 8 | Cmd.ContiguousLogicBlocksByte1);
ASSERT(Temp == BlockCount);
DPRINT("USBSTOR_SendReadWrite BlockAddress %x%x%x%x BlockCount %lu BlockLength %lu\n", Cmd.LogicalBlockByte0, Cmd.LogicalBlockByte1, Cmd.LogicalBlockByte2, Cmd.LogicalBlockByte3, BlockCount, PDODeviceExtension->BlockLength);
- //
- // send request
- //
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_WRITE_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // no transfer length
- //
ASSERT(Request->DataTransferLength == 0);
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
// initialize test unit cmd
- //
RtlZeroMemory(&Cmd, sizeof(UFI_TEST_UNIT_CMD));
Cmd.Code = SCSIOP_TEST_UNIT_READY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
- //
- // send the request
- //
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_TEST_UNIT_CMD_LEN, (PUCHAR)&Cmd, 0, NULL, RetryCount);
}
PSCSI_REQUEST_BLOCK Request;
UFI_UNKNOWN_CMD Cmd;
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = IoStack->Parameters.Others.Argument1;
-
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
// check that we're sending to the right LUN
- //
ASSERT(Request->Cdb[1] == (PDODeviceExtension->LUN & MAX_LUN));
-
- //
- // sanity check
- //
ASSERT(Request->CdbLength <= sizeof(UFI_UNKNOWN_CMD));
- //
- // initialize test unit cmd
- //
RtlCopyMemory(&Cmd, Request->Cdb, Request->CdbLength);
- //
- // send the request
- //
return USBSTOR_SendRequest(DeviceObject, Irp, Request->CdbLength, (PUCHAR)&Cmd, Request->DataTransferLength, Request->DataBuffer, RetryCount);
}
PSCSI_REQUEST_BLOCK Request;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
- //
- // get PDO device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get request block
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
-
- //
- // get SCSI command data block
- //
pCDB = (PCDB)Request->Cdb;
DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]);
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
{
- //
- // sanity checks
- //
ASSERT(Request->DataBuffer);
DPRINT("SCSIOP_READ_CAPACITY Length %lu\n", Request->DataTransferLength);
ASSERT(pCDB->MODE_SENSE.AllocationLength == Request->DataTransferLength);
ASSERT(Request->DataBuffer);
- //
- // send mode sense command
- //
Status = USBSTOR_SendModeSense(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_READ_FORMATTED_CAPACITY)
{
DPRINT("SCSIOP_READ_FORMATTED_CAPACITY DataTransferLength %lu\n", Request->DataTransferLength);
- //
- // send read format capacity
- //
Status = USBSTOR_SendFormatCapacity(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_INQUIRY)
{
DPRINT("SCSIOP_INQUIRY DataTransferLength %lu\n", Request->DataTransferLength);
- //
- // send read format capacity
- //
Status = USBSTOR_SendInquiry(DeviceObject, Irp, RetryCount);
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ || pCDB->MODE_SENSE.OperationCode == SCSIOP_WRITE)
{
DPRINT("SCSIOP_READ / SCSIOP_WRITE DataTransferLength %lu\n", Request->DataTransferLength);
- //
- // send read / write command
- //
Status = USBSTOR_SendReadWrite(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_MEDIUM_REMOVAL)
{
DPRINT("SCSIOP_MEDIUM_REMOVAL\n");
- //
// just complete the request
- //
Request->SrbStatus = SRB_STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Request->DataTransferLength;
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- //
- // start next request
- //
USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
return STATUS_SUCCESS;
{
DPRINT("SCSIOP_TEST_UNIT_READY\n");
- //
- // send test unit command
- //
Status = USBSTOR_SendTestUnit(DeviceObject, Irp, RetryCount);
}
else
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/usbstor.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
- Johannes Anderwald
+ * COPYRIGHT: 2005-2006 James Tabor
+ * 2011-2012 Michael Martin (michael.martin@reactos.org)
+ * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
*/
-/* INCLUDES ******************************************************************/
-
#include "usbstor.h"
#define NDEBUG
#include <debug.h>
-/* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
NTSTATUS
NTAPI
PDEVICE_OBJECT DeviceObject;
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);
-
- //
- // check for success
- //
if (!NT_SUCCESS(Status))
{
DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
return Status;
}
- //
- // get device extension
- //
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(DeviceExtension);
-
- //
- // zero device extension
- //
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
- //
// initialize device extension
- //
DeviceExtension->Common.IsFDO = TRUE;
DeviceExtension->FunctionalDeviceObject = DeviceObject;
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
- //
- // init timer
- //
IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
- //
// did attaching fail
- //
if (!DeviceExtension->LowerDeviceObject)
{
- //
- // device removed
- //
IoDeleteDevice(DeviceObject);
return STATUS_DEVICE_REMOVED;
}
- //
- // set device flags
- //
DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
- //
// device is initialized
- //
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
- //
- // done
- //
return STATUS_SUCCESS;
}
USBSTOR_Unload(
PDRIVER_OBJECT DriverObject)
{
- //
// no-op
- //
}
NTSTATUS
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- //
// function always succeeds ;)
- //
DPRINT("USBSTOR_DispatchClose\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
-
NTSTATUS
NTAPI
USBSTOR_DispatchDeviceControl(
{
NTSTATUS Status;
- //
- // handle requests
- //
Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
-
- //
- // complete request
- //
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- //
- // done
- //
return Status;
}
-
NTSTATUS
NTAPI
USBSTOR_DispatchScsi(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- //
- // handle requests
- //
return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
}
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- //
// read write ioctl is not supported
- //
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
{
PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
- //
- // get common device extension
- //
DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
- // is it for the FDO
- //
if (DeviceExtension->IsFDO)
{
- //
- // dispatch pnp request to fdo pnp handler
- //
return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
}
else
{
- //
- // dispatch request to pdo pnp handler
- //
return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
}
}
}
}
-
-
NTSTATUS
NTAPI
DriverEntry(
DPRINT("********* USB Storage *********\n");
- //
- // driver unload routine
- //
DriverObject->DriverUnload = USBSTOR_Unload;
-
- //
- // add device function
- //
DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
-
- //
- // driver start i/o routine
- //
DriverObject->DriverStartIo = USBSTOR_StartIo;
-
- //
- // create / close
- //
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
-
- //
- // scsi pass through requests
- //
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl;
-
- //
- // irp dispatch read / write
- //
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl; // scsi pass through requests
DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
-
- //
- // scsi queue ioctl
- //
DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
-
- //
- // pnp processing
- //
DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
-
- //
- // power processing
- //
DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
return STATUS_SUCCESS;