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/disk.c?rev=51607&r1=51606&r2=51607&view=diff
==============================================================================
--- 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;
 }


Reply via email to