mirror of
https://github.com/reactos/reactos.git
synced 2025-04-19 12:08:55 +00:00
[USBEHCI_NEW]
- Implement retrieving device / configuration descriptor for usb devices - Based on mjmartin usbehci driver - Mass storage device found wizard now pops up (fails to install - WIP) svn path=/branches/usb-bringup/; revision=51478
This commit is contained in:
parent
a3f701378c
commit
823176506d
3 changed files with 215 additions and 42 deletions
|
@ -1080,6 +1080,8 @@ CHubController::HandleGetDescriptor(
|
|||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
||||
PUCHAR Buffer;
|
||||
PUSBDEVICE UsbDevice;
|
||||
ULONG Length;
|
||||
|
||||
//
|
||||
// check descriptor type
|
||||
|
@ -1092,6 +1094,7 @@ CHubController::HandleGetDescriptor(
|
|||
// sanity check
|
||||
//
|
||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
|
||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
|
||||
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
||||
{
|
||||
|
@ -1100,7 +1103,24 @@ CHubController::HandleGetDescriptor(
|
|||
//
|
||||
RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// check if this is a valid usb device handle
|
||||
//
|
||||
PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
|
||||
|
||||
//
|
||||
// get device
|
||||
//
|
||||
UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
|
||||
|
||||
//
|
||||
// retrieve device descriptor from device
|
||||
//
|
||||
UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1112,52 +1132,95 @@ CHubController::HandleGetDescriptor(
|
|||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// FIXME: support devices
|
||||
//
|
||||
PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL);
|
||||
|
||||
//
|
||||
// copy configuration descriptor template
|
||||
//
|
||||
C_ASSERT(sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR) == sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// get configuration descriptor, very retarded!
|
||||
//
|
||||
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer;
|
||||
|
||||
//
|
||||
// check if buffer can hold interface and endpoint descriptor
|
||||
//
|
||||
if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength)
|
||||
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
||||
{
|
||||
//
|
||||
// buffer too small
|
||||
// request is for the root bus controller
|
||||
//
|
||||
C_ASSERT(sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR) == sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// get configuration descriptor, very retarded!
|
||||
//
|
||||
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer;
|
||||
|
||||
//
|
||||
// check if buffer can hold interface and endpoint descriptor
|
||||
//
|
||||
if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength)
|
||||
{
|
||||
//
|
||||
// buffer too small
|
||||
//
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// copy interface descriptor template
|
||||
//
|
||||
Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
|
||||
C_ASSERT(sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR) == sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||
RtlCopyMemory(Buffer, ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// copy end point descriptor template
|
||||
//
|
||||
Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
|
||||
C_ASSERT(sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR) == sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||
RtlCopyMemory(Buffer, ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Length %u\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||
|
||||
//
|
||||
// copy interface descriptor template
|
||||
//
|
||||
Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
|
||||
C_ASSERT(sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR) == sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||
RtlCopyMemory(Buffer, ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||
//
|
||||
// check if this is a valid usb device handle
|
||||
//
|
||||
PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
|
||||
|
||||
//
|
||||
// copy end point descriptor template
|
||||
//
|
||||
Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
|
||||
C_ASSERT(sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR) == sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||
RtlCopyMemory(Buffer, ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||
//
|
||||
// get device
|
||||
//
|
||||
UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
Status = STATUS_SUCCESS;
|
||||
if (UsbDevice->GetConfigurationDescriptorsLength() > Urb->UrbControlDescriptorRequest.TransferBufferLength)
|
||||
{
|
||||
//
|
||||
// buffer too small
|
||||
//
|
||||
Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->GetConfigurationDescriptorsLength();
|
||||
|
||||
//
|
||||
// bail out
|
||||
//
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// perform work in IUSBDevice
|
||||
//
|
||||
UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength, &Length);
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
PC_ASSERT(UsbDevice->GetConfigurationDescriptorsLength() == Length);
|
||||
|
||||
//
|
||||
// store result size
|
||||
//
|
||||
Urb->UrbControlDescriptorRequest.TransferBufferLength = Length;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -795,6 +795,13 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
|||
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer,
|
||||
IN ULONG BufferLength,
|
||||
OUT PULONG OutBufferLength) = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// Description: returns length of configuration descriptors
|
||||
//
|
||||
virtual ULONG GetConfigurationDescriptorsLength() = 0;
|
||||
|
||||
};
|
||||
|
||||
typedef IUSBDevice *PUSBDEVICE;
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
virtual UCHAR GetConfigurationValue();
|
||||
virtual NTSTATUS SubmitIrp(PIRP Irp);
|
||||
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, IN ULONG BufferLength, OUT PULONG OutBufferLength);
|
||||
|
||||
virtual ULONG GetConfigurationDescriptorsLength();
|
||||
|
||||
// local function
|
||||
virtual NTSTATUS CommitIrp(PIRP Irp);
|
||||
|
@ -74,6 +74,7 @@ public:
|
|||
virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
|
||||
virtual NTSTATUS CreateDeviceDescriptor();
|
||||
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
|
||||
virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
|
||||
|
||||
// constructor / destructor
|
||||
CUSBDevice(IUnknown *OuterUnknown){}
|
||||
|
@ -752,6 +753,11 @@ CUSBDevice::CreateConfigurationDescriptor(
|
|||
//
|
||||
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer;
|
||||
|
||||
//
|
||||
// informal debug print
|
||||
//
|
||||
DumpConfigurationDescriptor(ConfigurationDescriptor);
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
|
@ -867,6 +873,9 @@ CUSBDevice::GetConfigurationDescriptors(
|
|||
IN ULONG BufferLength,
|
||||
OUT PULONG OutBufferLength)
|
||||
{
|
||||
PVOID Buffer;
|
||||
ULONG InterfaceIndex, EndpointIndex;
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
|
@ -874,6 +883,11 @@ CUSBDevice::GetConfigurationDescriptors(
|
|||
PC_ASSERT(ConfigDescriptorBuffer);
|
||||
PC_ASSERT(OutBufferLength);
|
||||
|
||||
//
|
||||
// reset copied length
|
||||
//
|
||||
*OutBufferLength = 0;
|
||||
|
||||
//
|
||||
// FIXME: support multiple configurations
|
||||
//
|
||||
|
@ -885,12 +899,87 @@ CUSBDevice::GetConfigurationDescriptors(
|
|||
RtlCopyMemory(ConfigDescriptorBuffer, &m_ConfigurationDescriptors[0].ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// store length
|
||||
// subtract length
|
||||
//
|
||||
*OutBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
|
||||
BufferLength -= sizeof(USB_CONFIGURATION_DESCRIPTOR);
|
||||
*OutBufferLength += sizeof(USB_CONFIGURATION_DESCRIPTOR);
|
||||
|
||||
//
|
||||
// increment offset
|
||||
//
|
||||
Buffer = (PVOID)(ConfigDescriptorBuffer + 1);
|
||||
|
||||
for(InterfaceIndex = 0; InterfaceIndex < m_ConfigurationDescriptors[0].ConfigurationDescriptor.bNumInterfaces; InterfaceIndex++)
|
||||
{
|
||||
if (BufferLength < sizeof(USB_INTERFACE_DESCRIPTOR))
|
||||
{
|
||||
//
|
||||
// no more room in buffer
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// copy interface descriptor
|
||||
//
|
||||
RtlCopyMemory(Buffer, &m_ConfigurationDescriptors[0].Interfaces[InterfaceIndex].InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// increment offset
|
||||
//
|
||||
Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||
BufferLength -= sizeof(USB_INTERFACE_DESCRIPTOR);
|
||||
*OutBufferLength += sizeof(USB_INTERFACE_DESCRIPTOR);
|
||||
|
||||
//
|
||||
// does the interface have endpoints
|
||||
//
|
||||
if (m_ConfigurationDescriptors[0].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints)
|
||||
{
|
||||
//
|
||||
// is enough space available
|
||||
//
|
||||
if (BufferLength < sizeof(USB_ENDPOINT_DESCRIPTOR) * m_ConfigurationDescriptors[0].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints)
|
||||
{
|
||||
//
|
||||
// no buffer
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// copy end points
|
||||
//
|
||||
for(EndpointIndex = 0; EndpointIndex < m_ConfigurationDescriptors[0].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints; EndpointIndex++)
|
||||
{
|
||||
//
|
||||
// copy endpoint
|
||||
//
|
||||
RtlCopyMemory(Buffer, &m_ConfigurationDescriptors[0].Interfaces[InterfaceIndex].EndPoints[EndpointIndex].EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// increment buffer offset
|
||||
//
|
||||
Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||
BufferLength -= sizeof(USB_ENDPOINT_DESCRIPTOR);
|
||||
*OutBufferLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
ULONG
|
||||
CUSBDevice::GetConfigurationDescriptorsLength()
|
||||
{
|
||||
//
|
||||
// FIXME: support multiple configurations
|
||||
//
|
||||
PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1);
|
||||
|
||||
return m_ConfigurationDescriptors[0].ConfigurationDescriptor.wTotalLength;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
VOID
|
||||
CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
||||
{
|
||||
|
@ -911,6 +1000,20 @@ CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
|||
DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
VOID
|
||||
CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||
{
|
||||
DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
|
||||
DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
|
||||
DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
|
||||
DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
|
||||
DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
|
||||
DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
|
||||
DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
|
||||
DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
|
||||
DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
NTSTATUS
|
||||
CreateUSBDevice(
|
||||
|
|
Loading…
Reference in a new issue