[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:
Johannes Anderwald 2011-04-28 17:45:32 +00:00
parent a3f701378c
commit 823176506d
3 changed files with 215 additions and 42 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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(