mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +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;
|
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||||
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
||||||
PUCHAR Buffer;
|
PUCHAR Buffer;
|
||||||
|
PUSBDEVICE UsbDevice;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
//
|
//
|
||||||
// check descriptor type
|
// check descriptor type
|
||||||
|
@ -1092,6 +1094,7 @@ CHubController::HandleGetDescriptor(
|
||||||
// sanity check
|
// sanity check
|
||||||
//
|
//
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||||
|
|
||||||
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1100,7 +1103,24 @@ CHubController::HandleGetDescriptor(
|
||||||
//
|
//
|
||||||
RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
Status = STATUS_SUCCESS;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1112,52 +1132,95 @@ CHubController::HandleGetDescriptor(
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||||
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||||
|
|
||||||
//
|
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// 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;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Length %u\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||||
|
|
||||||
//
|
//
|
||||||
// copy interface descriptor template
|
// check if this is a valid usb device handle
|
||||||
//
|
//
|
||||||
Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
|
PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
|
||||||
C_ASSERT(sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR) == sizeof(USB_INTERFACE_DESCRIPTOR));
|
|
||||||
RtlCopyMemory(Buffer, ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// copy end point descriptor template
|
// get device
|
||||||
//
|
//
|
||||||
Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
|
UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
|
||||||
C_ASSERT(sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR) == sizeof(USB_ENDPOINT_DESCRIPTOR));
|
|
||||||
RtlCopyMemory(Buffer, ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
|
|
||||||
|
|
||||||
//
|
if (UsbDevice->GetConfigurationDescriptorsLength() > Urb->UrbControlDescriptorRequest.TransferBufferLength)
|
||||||
// done
|
{
|
||||||
//
|
//
|
||||||
Status = STATUS_SUCCESS;
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -795,6 +795,13 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
||||||
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer,
|
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer,
|
||||||
IN ULONG BufferLength,
|
IN ULONG BufferLength,
|
||||||
OUT PULONG OutBufferLength) = 0;
|
OUT PULONG OutBufferLength) = 0;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Description: returns length of configuration descriptors
|
||||||
|
//
|
||||||
|
virtual ULONG GetConfigurationDescriptorsLength() = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IUSBDevice *PUSBDEVICE;
|
typedef IUSBDevice *PUSBDEVICE;
|
||||||
|
|
|
@ -66,7 +66,7 @@ public:
|
||||||
virtual UCHAR GetConfigurationValue();
|
virtual UCHAR GetConfigurationValue();
|
||||||
virtual NTSTATUS SubmitIrp(PIRP Irp);
|
virtual NTSTATUS SubmitIrp(PIRP Irp);
|
||||||
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, IN ULONG BufferLength, OUT PULONG OutBufferLength);
|
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, IN ULONG BufferLength, OUT PULONG OutBufferLength);
|
||||||
|
virtual ULONG GetConfigurationDescriptorsLength();
|
||||||
|
|
||||||
// local function
|
// local function
|
||||||
virtual NTSTATUS CommitIrp(PIRP Irp);
|
virtual NTSTATUS CommitIrp(PIRP Irp);
|
||||||
|
@ -74,6 +74,7 @@ public:
|
||||||
virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
|
virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
|
||||||
virtual NTSTATUS CreateDeviceDescriptor();
|
virtual NTSTATUS CreateDeviceDescriptor();
|
||||||
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
|
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
|
||||||
|
virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
CUSBDevice(IUnknown *OuterUnknown){}
|
CUSBDevice(IUnknown *OuterUnknown){}
|
||||||
|
@ -752,6 +753,11 @@ CUSBDevice::CreateConfigurationDescriptor(
|
||||||
//
|
//
|
||||||
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer;
|
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// informal debug print
|
||||||
|
//
|
||||||
|
DumpConfigurationDescriptor(ConfigurationDescriptor);
|
||||||
|
|
||||||
//
|
//
|
||||||
// sanity check
|
// sanity check
|
||||||
//
|
//
|
||||||
|
@ -867,6 +873,9 @@ CUSBDevice::GetConfigurationDescriptors(
|
||||||
IN ULONG BufferLength,
|
IN ULONG BufferLength,
|
||||||
OUT PULONG OutBufferLength)
|
OUT PULONG OutBufferLength)
|
||||||
{
|
{
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG InterfaceIndex, EndpointIndex;
|
||||||
|
|
||||||
//
|
//
|
||||||
// sanity check
|
// sanity check
|
||||||
//
|
//
|
||||||
|
@ -874,6 +883,11 @@ CUSBDevice::GetConfigurationDescriptors(
|
||||||
PC_ASSERT(ConfigDescriptorBuffer);
|
PC_ASSERT(ConfigDescriptorBuffer);
|
||||||
PC_ASSERT(OutBufferLength);
|
PC_ASSERT(OutBufferLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
// reset copied length
|
||||||
|
//
|
||||||
|
*OutBufferLength = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: support multiple configurations
|
// FIXME: support multiple configurations
|
||||||
//
|
//
|
||||||
|
@ -885,12 +899,87 @@ CUSBDevice::GetConfigurationDescriptors(
|
||||||
RtlCopyMemory(ConfigDescriptorBuffer, &m_ConfigurationDescriptors[0].ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
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
|
VOID
|
||||||
CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
||||||
{
|
{
|
||||||
|
@ -911,6 +1000,20 @@ CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
||||||
DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
|
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
|
NTSTATUS
|
||||||
CreateUSBDevice(
|
CreateUSBDevice(
|
||||||
|
|
Loading…
Reference in a new issue