Author: janderwald
Date: Fri May 6 13:29:27 2011
New Revision: 51607
URL:
http://svn.reactos.org/svn/reactos?rev=51607&view=rev
Log:
[USBSTOR]
- Implement retrieving adapter descriptor (IOCTL_STORAGE_QUERY_PROPERTY)
- Implement retrieving device descriptor (IOCTL_STORAGE_QUERY_PROPERTY)
- Next Function to implement is SRB_FUNCTION_EXECUTE_SCSI
Modified:
branches/usb-bringup/drivers/usb/usbstor/disk.c
Modified: branches/usb-bringup/drivers/usb/usbstor/disk.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] Fri May 6 13:29:27 2011
@@ -143,6 +143,276 @@
return Status;
}
+ULONG
+USBSTOR_GetFieldLength(
+ IN PUCHAR Name,
+ IN ULONG MaxLength)
+{
+ ULONG Index;
+ ULONG LastCharacterPosition = 0;
+
+ //
+ // scan the field and return last positon 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;
+}
+
+NTSTATUS
+USBSTOR_HandleQueryProperty(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ PSTORAGE_PROPERTY_QUERY PropertyQuery;
+ PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
+ PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
+ ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength;
+ PPDO_DEVICE_EXTENSION PDODeviceExtension;
+ PUFI_INQUIRY_RESPONSE InquiryData;
+ PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
+ PUCHAR Buffer;
+
+ DPRINT1("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)
+ {
+ DPRINT1("USBSTOR_HandleQueryProperty StorageDeviceProperty
OutputBufferLength %lu\n",
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+
+ //
+ // get device extension
+ //
+ PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ ASSERT(PDODeviceExtension);
+
+ //
+ // 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);
+
+ //
+ // FIXME handle serial number
+ //
+
+ //
+ // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 3
extra null bytes - 1
+ // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
+ //
+ TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor +
FieldLengthProduct + FieldLengthRevision + 2;
+
+ //
+ // 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;
+
+ Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // get device descriptor
+ //
+ DeviceDescriptor =
(PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer;
+
+ //
+ // initialize device descriptor
+ //
+ DeviceDescriptor->Version = TotalLength;
+ DeviceDescriptor->Size = TotalLength;
+ DeviceDescriptor->DeviceType = InquiryData->DeviceType;
+ DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F);
+ DeviceDescriptor->RemovableMedia = FALSE; //FIXME check if floppy
+ DeviceDescriptor->CommandQueueing = FALSE;
+ DeviceDescriptor->BusType = BusTypeUsb;
+ DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) -
sizeof(UCHAR);
+ DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset +
FieldLengthVendor + 1;
+ DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset
+ FieldLengthProduct + 1;
+ DeviceDescriptor->SerialNumberOffset = 0; //FIXME
+ DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct
+ FieldLengthRevision + 3;
+
+ //
+ // 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;
+
+ //
+ // TODO: copy revision
+ //
+
+ 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));
+
+ //
+ // done
+ //
+ Irp->IoStatus.Information = TotalLength;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ //
+ // adapter property query request
+ //
+ DPRINT1("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);
+
+ Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
+ 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->MaximumPhysicalPages = 25; //FIXME compute some sane value
+ AdapterDescriptor->AlignmentMask = 0;
+ AdapterDescriptor->AdapterUsesPio = FALSE;
+ AdapterDescriptor->AdapterScansDown = FALSE;
+ AdapterDescriptor->CommandQueueing = FALSE;
+ AdapterDescriptor->AcceleratedTransfer = FALSE;
+ AdapterDescriptor->BusType = BusTypeUsb;
+ AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify
+ AdapterDescriptor->BusMinorVersion = 0x00; //FIXME
+
+ //
+ // store returned length
+ //
+ Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
+ }
+}
+
+
+
NTSTATUS
USBSTOR_HandleDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
@@ -154,6 +424,14 @@
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_STORAGE_QUERY_PROPERTY)
+ {
+ //
+ // query property
+ //
+ return USBSTOR_HandleQueryProperty(DeviceObject, Irp);
+ }
DPRINT1("USBSTOR_HandleDeviceControl IoControl %x\n",
IoStack->Parameters.DeviceIoControl.IoControlCode);
DPRINT1("USBSTOR_HandleDeviceControl InputBufferLength %x\n",
IoStack->Parameters.DeviceIoControl.InputBufferLength);
@@ -163,7 +441,6 @@
DPRINT1("USBSTOR_HandleDeviceControl UserBuffer %x\n",
Irp->UserBuffer);
DPRINT1("USBSTOR_HandleDeviceControl MdlAddress %x\n",
Irp->MdlAddress);
- //IOCTL_STORAGE_QUERY_PROPERTY
return STATUS_NOT_SUPPORTED;
}