Author: janderwald Date: Thu Apr 28 17:45:32 2011 New Revision: 51478
URL: http://svn.reactos.org/svn/reactos?rev=51478&view=rev Log: [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)
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] Thu Apr 28 17:45:32 2011 @@ -1080,6 +1080,8 @@ NTSTATUS Status = STATUS_NOT_IMPLEMENTED; PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; PUCHAR Buffer; + PUSBDEVICE UsbDevice; + ULONG Length;
// // check descriptor type @@ -1092,6 +1094,7 @@ // 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 @@ // 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 @@ 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; + } - - // - // 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; + else + { + DPRINT1("Length %u\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); + + // + // check if this is a valid usb device handle + // + PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + + // + // get device + // + UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); + + 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:
Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] Thu Apr 28 17:45:32 2011 @@ -795,6 +795,13 @@ 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;
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_... ============================================================================== --- branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] Thu Apr 28 17:45:32 2011 @@ -66,7 +66,7 @@ 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 @@ 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){} @@ -753,6 +754,11 @@ ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer;
// + // informal debug print + // + DumpConfigurationDescriptor(ConfigurationDescriptor); + + // // sanity check // PC_ASSERT(ConfigurationDescriptor->bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR)); @@ -867,6 +873,9 @@ IN ULONG BufferLength, OUT PULONG OutBufferLength) { + PVOID Buffer; + ULONG InterfaceIndex, EndpointIndex; + // // sanity check // @@ -875,6 +884,11 @@ PC_ASSERT(OutBufferLength);
// + // reset copied length + // + *OutBufferLength = 0; + + // // FIXME: support multiple configurations // PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); @@ -885,12 +899,87 @@ RtlCopyMemory(ConfigDescriptorBuffer, &m_ConfigurationDescriptors[0].ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
// - // store length - // - *OutBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); -} - - + // subtract length + // + 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) { @@ -912,6 +1001,20 @@ }
//---------------------------------------------------------------------------------------- +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( PUSBDEVICE *OutDevice)