[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;
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:

View file

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

View file

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