mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[USBEHCI]
- Store configuration index in the setup packet - Perform retrieving the configuration request before storing the configuration details. Perform the same action for the select interface request - EHCI now supports selecting configuration & interface on devices with more than one configuration (previously only one configuration was supported) - Code has not yet been tested, as no available usb device has such feature svn path=/branches/usb-bringup-trunk/; revision=55536
This commit is contained in:
parent
f61b43a5c1
commit
6ced7570a0
1 changed files with 107 additions and 87 deletions
|
@ -58,7 +58,7 @@ public:
|
||||||
// local function
|
// local function
|
||||||
virtual NTSTATUS CommitIrp(PIRP Irp);
|
virtual NTSTATUS CommitIrp(PIRP Irp);
|
||||||
virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl);
|
virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl);
|
||||||
virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
|
virtual NTSTATUS CreateConfigurationDescriptor(UCHAR 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);
|
virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
|
||||||
|
@ -302,7 +302,7 @@ CUSBDevice::SetDeviceAddress(
|
||||||
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UCHAR OldAddress;
|
UCHAR OldAddress;
|
||||||
ULONG Index;
|
UCHAR Index;
|
||||||
|
|
||||||
DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress);
|
DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress);
|
||||||
|
|
||||||
|
@ -685,7 +685,7 @@ CUSBDevice::CreateDeviceDescriptor()
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBDevice::CreateConfigurationDescriptor(
|
CUSBDevice::CreateConfigurationDescriptor(
|
||||||
ULONG Index)
|
UCHAR Index)
|
||||||
{
|
{
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
|
@ -722,15 +722,11 @@ CUSBDevice::CreateConfigurationDescriptor(
|
||||||
CtrlSetup.bmRequestType._BM.Reserved = 0;
|
CtrlSetup.bmRequestType._BM.Reserved = 0;
|
||||||
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
|
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
|
||||||
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||||
CtrlSetup.wValue.LowByte = 0;
|
CtrlSetup.wValue.LowByte = Index;
|
||||||
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
|
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
|
||||||
CtrlSetup.wIndex.W = 0;
|
CtrlSetup.wIndex.W = 0;
|
||||||
CtrlSetup.wLength = PAGE_SIZE;
|
CtrlSetup.wLength = PAGE_SIZE;
|
||||||
|
|
||||||
//
|
|
||||||
// FIXME: where put configuration index?
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// now build MDL describing the buffer
|
// now build MDL describing the buffer
|
||||||
//
|
//
|
||||||
|
@ -1077,65 +1073,20 @@ CUSBDevice::SelectConfiguration(
|
||||||
IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,
|
IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,
|
||||||
OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle)
|
OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle)
|
||||||
{
|
{
|
||||||
ULONG ConfigurationIndex = 0;
|
|
||||||
ULONG InterfaceIndex, PipeIndex;
|
ULONG InterfaceIndex, PipeIndex;
|
||||||
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: support multiple configurations
|
// sanity checks
|
||||||
//
|
//
|
||||||
PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1);
|
ASSERT(ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations);
|
||||||
PC_ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor.iConfiguration);
|
ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor.iConfiguration);
|
||||||
|
|
||||||
//
|
//
|
||||||
// sanity check
|
// sanity check
|
||||||
//
|
//
|
||||||
PC_ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor.bNumInterfaces);
|
ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor.bNumInterfaces);
|
||||||
|
|
||||||
//
|
|
||||||
// copy interface info and pipe info
|
|
||||||
//
|
|
||||||
for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// sanity check: is the info pre-layed out
|
|
||||||
//
|
|
||||||
PC_ASSERT(InterfaceInfo->NumberOfPipes == m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints);
|
|
||||||
PC_ASSERT(InterfaceInfo->Length != 0);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes]));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// copy interface info
|
|
||||||
//
|
|
||||||
InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex];
|
|
||||||
InterfaceInfo->Class = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceClass;
|
|
||||||
InterfaceInfo->SubClass = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceSubClass;
|
|
||||||
InterfaceInfo->Protocol = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceProtocol;
|
|
||||||
InterfaceInfo->Reserved = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// copy endpoint info
|
|
||||||
//
|
|
||||||
for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// copy pipe info
|
|
||||||
//
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize;
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].EndpointAddress = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress;
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].Interval = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bInterval;
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes;
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// move offset
|
|
||||||
//
|
|
||||||
InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) + InterfaceInfo->Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// now build setup packet
|
// now build setup packet
|
||||||
|
@ -1153,18 +1104,71 @@ CUSBDevice::SelectConfiguration(
|
||||||
// informal debug print
|
// informal debug print
|
||||||
//
|
//
|
||||||
DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status);
|
DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// store configuration device index
|
// failed
|
||||||
//
|
//
|
||||||
m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store configuration device index
|
||||||
|
//
|
||||||
|
m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration;
|
||||||
|
|
||||||
|
//
|
||||||
|
// store configuration handle
|
||||||
|
//
|
||||||
|
*ConfigurationHandle = &m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration];
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy interface info and pipe info
|
||||||
|
//
|
||||||
|
for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// sanity check: is the info pre-layed out
|
||||||
|
//
|
||||||
|
PC_ASSERT(InterfaceInfo->NumberOfPipes == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints);
|
||||||
|
PC_ASSERT(InterfaceInfo->Length != 0);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes]));
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// store configuration handle
|
// copy interface info
|
||||||
//
|
//
|
||||||
*ConfigurationHandle = &m_ConfigurationDescriptors[ConfigurationIndex];
|
InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex];
|
||||||
|
InterfaceInfo->Class = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceClass;
|
||||||
|
InterfaceInfo->SubClass = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceSubClass;
|
||||||
|
InterfaceInfo->Protocol = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceProtocol;
|
||||||
|
InterfaceInfo->Reserved = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy endpoint info
|
||||||
|
//
|
||||||
|
for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// copy pipe info
|
||||||
|
//
|
||||||
|
InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize;
|
||||||
|
InterfaceInfo->Pipes[PipeIndex].EndpointAddress = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress;
|
||||||
|
InterfaceInfo->Pipes[PipeIndex].Interval = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bInterval;
|
||||||
|
InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes;
|
||||||
|
InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// data toggle is reset on configuration requests
|
||||||
|
//
|
||||||
|
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].DataToggle = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move offset
|
||||||
|
//
|
||||||
|
InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) + InterfaceInfo->Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1179,22 +1183,51 @@ CUSBDevice::SelectInterface(
|
||||||
IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
|
IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
|
||||||
IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo)
|
IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo)
|
||||||
{
|
{
|
||||||
ULONG ConfigurationIndex = 0;
|
|
||||||
PUSB_CONFIGURATION Configuration;
|
PUSB_CONFIGURATION Configuration;
|
||||||
ULONG PipeIndex;
|
ULONG PipeIndex;
|
||||||
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
//
|
|
||||||
// FIXME support multiple configurations
|
|
||||||
//
|
|
||||||
PC_ASSERT(&m_ConfigurationDescriptors[ConfigurationIndex] == (PUSB_CONFIGURATION)ConfigurationHandle);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// get configuration struct
|
// get configuration struct
|
||||||
//
|
//
|
||||||
Configuration = (PUSB_CONFIGURATION)ConfigurationHandle;
|
Configuration = (PUSB_CONFIGURATION)ConfigurationHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(Configuration->ConfigurationDescriptor.bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE);
|
||||||
|
ASSERT(Configuration->ConfigurationDescriptor.bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||||
|
ASSERT(Configuration->ConfigurationDescriptor.iConfiguration < m_DeviceDescriptor.bNumConfigurations);
|
||||||
|
ASSERT(&m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor.iConfiguration] == Configuration);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize setup packet
|
||||||
|
//
|
||||||
|
RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
|
||||||
|
CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE;
|
||||||
|
CtrlSetup.wValue.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bAlternateSetting;
|
||||||
|
CtrlSetup.wIndex.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bInterfaceNumber;
|
||||||
|
CtrlSetup.bmRequestType.B = 0x01;
|
||||||
|
|
||||||
|
//
|
||||||
|
// issue request
|
||||||
|
//
|
||||||
|
Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// informal debug print
|
||||||
|
//
|
||||||
|
DPRINT1("CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x Status %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber, Status);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to select interface
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// sanity checks
|
// sanity checks
|
||||||
//
|
//
|
||||||
|
@ -1224,6 +1257,11 @@ CUSBDevice::SelectInterface(
|
||||||
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
|
InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// data toggle is reset on select interface requests
|
||||||
|
//
|
||||||
|
m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor.iConfiguration].Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].DataToggle = FALSE;
|
||||||
|
|
||||||
if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
|
if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -1232,24 +1270,6 @@ CUSBDevice::SelectInterface(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// initialize setup packet
|
|
||||||
//
|
|
||||||
RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
|
|
||||||
CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE;
|
|
||||||
CtrlSetup.wValue.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bAlternateSetting;
|
|
||||||
CtrlSetup.wIndex.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bInterfaceNumber;
|
|
||||||
CtrlSetup.bmRequestType.B = 0x01;
|
|
||||||
|
|
||||||
//
|
|
||||||
// issue request
|
|
||||||
//
|
|
||||||
Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0);
|
|
||||||
|
|
||||||
//
|
|
||||||
// informal debug print
|
|
||||||
//
|
|
||||||
DPRINT1("CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x Status %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber, Status);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// done
|
// done
|
||||||
|
|
Loading…
Reference in a new issue