[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

svn path=/branches/usb-bringup/; revision=51607
This commit is contained in:
Johannes Anderwald 2011-05-06 13:29:27 +00:00
parent c5af801a10
commit 5c9e645604

View file

@ -143,6 +143,276 @@ USBSTOR_HandleInternalDeviceControl(
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,
@ -155,6 +425,14 @@ USBSTOR_HandleDeviceControl(
//
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);
DPRINT1("USBSTOR_HandleDeviceControl OutputBufferLength %x\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
@ -163,7 +441,6 @@ USBSTOR_HandleDeviceControl(
DPRINT1("USBSTOR_HandleDeviceControl UserBuffer %x\n", Irp->UserBuffer);
DPRINT1("USBSTOR_HandleDeviceControl MdlAddress %x\n", Irp->MdlAddress);
//IOCTL_STORAGE_QUERY_PROPERTY
return STATUS_NOT_SUPPORTED;
}