From 3b6ba2f1d85acf07989d0275cb5ba8ae02f377bd Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 29 Apr 2011 02:46:04 +0000 Subject: [PATCH] [USBEHCI_NEW] - Implement SelectInterface / SelectConfiguration based on mjmartin usbehci driver - Initialization runs untill SelectInterface request - Tested with WinXP SP2 svn path=/branches/usb-bringup/; revision=51489 --- drivers/usb/usbehci_new/hub_controller.cpp | 92 ++++++++-- drivers/usb/usbehci_new/interfaces.h | 22 ++- drivers/usb/usbehci_new/usb_device.cpp | 203 ++++++++++++++++++++- drivers/usb/usbehci_new/usb_request.cpp | 24 ++- 4 files changed, 311 insertions(+), 30 deletions(-) diff --git a/drivers/usb/usbehci_new/hub_controller.cpp b/drivers/usb/usbehci_new/hub_controller.cpp index a3f9c032367..86d89278f1a 100644 --- a/drivers/usb/usbehci_new/hub_controller.cpp +++ b/drivers/usb/usbehci_new/hub_controller.cpp @@ -63,6 +63,7 @@ public: NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleGetStatusFromDevice(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb); + NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb); NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb); @@ -936,29 +937,87 @@ CHubController::HandleSelectConfiguration( IN OUT PIRP Irp, PURB Urb) { - // - // sanity checks - // + PUSBDEVICE UsbDevice; // - // FIXME: support devices + // is the request for the Root Hub // - PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL); + if (Urb->UrbHeader.UsbdDeviceHandle == NULL) + { + // + // FIXME: support setting device to unconfigured state + // + PC_ASSERT(Urb->UrbSelectConfiguration.ConfigurationDescriptor); + + // + // set device handle + // + Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)ROOTHUB2_CONFIGURATION_DESCRIPTOR; + + // + // TODO: copy interface info + // + return STATUS_SUCCESS; + } + else + { + // + // check if this is a valid usb device handle + // + PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + + // + // get device + // + UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); + + // + // select configuration + // + return UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle); + } +} + +//----------------------------------------------------------------------------------------- +NTSTATUS +CHubController::HandleSelectInterface( + IN OUT PIRP Irp, + PURB Urb) +{ + PUSBDEVICE UsbDevice; // - // FIXME: support setting device to unconfigured state + // sanity check // - PC_ASSERT(Urb->UrbSelectConfiguration.ConfigurationDescriptor); + PC_ASSERT(Urb->UrbSelectInterface.ConfigurationHandle); // - // set device handle + // is the request for the Root Hub // - Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)ROOTHUB2_CONFIGURATION_DESCRIPTOR; + if (Urb->UrbHeader.UsbdDeviceHandle == NULL) + { + // + // no op for root hub + // + return STATUS_SUCCESS; + } + else + { + // + // check if this is a valid usb device handle + // + PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); - // - // TODO: copy interface info - // - return STATUS_SUCCESS; + // + // get device + // + UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); + + // + // select interface + // + return UsbDevice->SelectInterface(Urb->UrbSelectInterface.ConfigurationHandle, &Urb->UrbSelectInterface.Interface); + } } //----------------------------------------------------------------------------------------- @@ -1249,7 +1308,7 @@ CHubController::HandleGetDescriptor( CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; - CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; + CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength; CtrlSetup.bmRequestType.B = 0x80; // @@ -1317,6 +1376,9 @@ CHubController::HandleDeviceControl( case URB_FUNCTION_SELECT_CONFIGURATION: Status = HandleSelectConfiguration(Irp, Urb); break; + case URB_FUNCTION_SELECT_INTERFACE: + Status = HandleSelectInterface(Irp, Urb); + break; case URB_FUNCTION_CLASS_OTHER: Status = HandleClassOther(Irp, Urb); break; @@ -1898,7 +1960,7 @@ USBHI_InitializeUsbDevice( // // now set the device address // - Status = UsbDevice->SetDeviceAddress(DeviceAddress); + Status = UsbDevice->SetDeviceAddress((UCHAR)DeviceAddress); if (NT_SUCCESS(Status)) break; diff --git a/drivers/usb/usbehci_new/interfaces.h b/drivers/usb/usbehci_new/interfaces.h index ceb183ca5d3..ddb056f0cbf 100644 --- a/drivers/usb/usbehci_new/interfaces.h +++ b/drivers/usb/usbehci_new/interfaces.h @@ -386,6 +386,7 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown) virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, + IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer) = 0; @@ -796,13 +797,13 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown) IN ULONG BufferLength, OUT PULONG OutBufferLength) = 0; -//---------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- // // Description: returns length of configuration descriptors // virtual ULONG GetConfigurationDescriptorsLength() = 0; -//---------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- // // SubmitSetupPacket // @@ -812,7 +813,24 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown) IN OUT ULONG BufferLength, OUT PVOID Buffer) = 0; +//----------------------------------------------------------------------------------------- +// +// SelectConfiguration +// +// Description: selects a configuration + virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + IN PUSBD_INTERFACE_INFORMATION Interface, + OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle) = 0; + +//----------------------------------------------------------------------------------------- +// +// SelectConfiguration +// +// Description: selects a interface of an configuration + + virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, + IN OUT PUSBD_INTERFACE_INFORMATION Interface) = 0; }; typedef IUSBDevice *PUSBDEVICE; diff --git a/drivers/usb/usbehci_new/usb_device.cpp b/drivers/usb/usbehci_new/usb_device.cpp index 563ac2eb03b..001ffeb6c68 100644 --- a/drivers/usb/usbehci_new/usb_device.cpp +++ b/drivers/usb/usbehci_new/usb_device.cpp @@ -68,11 +68,12 @@ public: virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, IN ULONG BufferLength, OUT PULONG OutBufferLength); virtual ULONG GetConfigurationDescriptorsLength(); virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, OUT ULONG BufferLength, OUT PVOID Buffer); - + virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSBD_INTERFACE_INFORMATION Interface, OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle); + virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION Interface); // local function virtual NTSTATUS CommitIrp(PIRP Irp); - virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN ULONG BufferLength, IN OUT PMDL Mdl); + virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl); virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex); virtual NTSTATUS CreateDeviceDescriptor(); virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor); @@ -90,6 +91,7 @@ protected: ULONG m_Port; UCHAR m_DeviceAddress; PVOID m_Data; + UCHAR m_ConfigurationIndex; KSPIN_LOCK m_Lock; USB_DEVICE_DESCRIPTOR m_DeviceDescriptor; ULONG m_PortStatus; @@ -338,7 +340,7 @@ CUSBDevice::SetDeviceAddress( // // set device address // - Status = CommitSetupPacket(CtrlSetup, 0, 0); + Status = CommitSetupPacket(CtrlSetup, 0, 0, 0); // // free setup packet @@ -440,8 +442,10 @@ CUSBDevice::GetDeviceDescriptor( UCHAR CUSBDevice::GetConfigurationValue() { - UNIMPLEMENTED - return 0x1; + // + // return configuration index + // + return m_ConfigurationIndex; } //---------------------------------------------------------------------------------------- @@ -527,7 +531,8 @@ CUSBDevice::SubmitIrp( //---------------------------------------------------------------------------------------- NTSTATUS CUSBDevice::CommitSetupPacket( - PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, + IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, + IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl) { @@ -559,7 +564,7 @@ CUSBDevice::CommitSetupPacket( // // initialize request // - Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, BufferLength, Mdl); + Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, EndpointDescriptor, BufferLength, Mdl); if (!NT_SUCCESS(Status)) { // @@ -642,7 +647,7 @@ CUSBDevice::CreateDeviceDescriptor() // // commit setup packet // - Status = CommitSetupPacket(&CtrlSetup, sizeof(USB_DEVICE_DESCRIPTOR), Mdl); + Status = CommitSetupPacket(&CtrlSetup, 0, sizeof(USB_DEVICE_DESCRIPTOR), Mdl); // // now free the mdl @@ -734,7 +739,7 @@ CUSBDevice::CreateConfigurationDescriptor( // // commit packet // - Status = CommitSetupPacket(&CtrlSetup, PAGE_SIZE, Mdl); + Status = CommitSetupPacket(&CtrlSetup, 0, PAGE_SIZE, Mdl); if (!NT_SUCCESS(Status)) { // @@ -1039,7 +1044,7 @@ CUSBDevice::SubmitSetupPacket( // // commit setup packet // - Status = CommitSetupPacket(SetupPacket, BufferLength, Mdl); + Status = CommitSetupPacket(SetupPacket, 0, BufferLength, Mdl); // // free mdl @@ -1051,6 +1056,184 @@ CUSBDevice::SubmitSetupPacket( // return Status; } + +//---------------------------------------------------------------------------------------- +NTSTATUS +CUSBDevice::SelectConfiguration( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + IN PUSBD_INTERFACE_INFORMATION InterfaceInfo, + OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle) +{ + ULONG ConfigurationIndex = 0; + ULONG InterfaceIndex, PipeIndex; + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + NTSTATUS Status; + + // + // FIXME: support multiple configurations + // + PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); + PC_ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor.iConfiguration); + + // + // sanity check + // + PC_ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationIndex].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 + // + RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); + CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION; + CtrlSetup.wValue.W = ConfigurationDescriptor->iConfiguration; + + // + // select configuration + // + Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0); + + // + // informal debug print + // + DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status); + + if (NT_SUCCESS(Status)) + { + // + // store configuration device index + // + m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration; + + // + // store configuration handle + // + *ConfigurationHandle = &m_ConfigurationDescriptors[ConfigurationIndex]; + } + + // + // done + // + return Status; +} + +//---------------------------------------------------------------------------------------- +NTSTATUS +CUSBDevice::SelectInterface( + IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, + IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo) +{ + ULONG ConfigurationIndex = 0; + PUSB_CONFIGURATION Configuration; + ULONG PipeIndex; + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + NTSTATUS Status; + + // + // FIXME support multiple configurations + // + PC_ASSERT(&m_ConfigurationDescriptors[ConfigurationIndex] == (PUSB_CONFIGURATION)ConfigurationHandle); + + // + // get configuration struct + // + Configuration = (PUSB_CONFIGURATION)ConfigurationHandle; + + // + // sanity checks + // + PC_ASSERT(Configuration->ConfigurationDescriptor.bNumInterfaces > InterfaceInfo->InterfaceNumber); + PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bNumEndpoints == InterfaceInfo->NumberOfPipes); +#ifdef _MSC_VER + PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); +#endif + + // + // copy pipe handles + // + for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) + { + // + // copy pipe handle + // + InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor; + + if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT)) + { + // + // FIXME: check if enough bandwidth is available + // + } + } + + // + // initialize setup packet + // + RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); + CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE; + CtrlSetup.wValue.W = InterfaceInfo->AlternateSetting; + CtrlSetup.wIndex.W = InterfaceInfo->InterfaceNumber; + 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 + // + return Status; +} + //---------------------------------------------------------------------------------------- NTSTATUS CreateUSBDevice( diff --git a/drivers/usb/usbehci_new/usb_request.cpp b/drivers/usb/usbehci_new/usb_request.cpp index 538f9073148..d002b9b41fa 100644 --- a/drivers/usb/usbehci_new/usb_request.cpp +++ b/drivers/usb/usbehci_new/usb_request.cpp @@ -36,7 +36,7 @@ public: } // IUSBRequest interface functions - virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer); + virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer); virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp); virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode, IN ULONG UrbStatusCode, IN struct _QUEUE_HEAD *QueueHead); virtual VOID CancelCallback(IN NTSTATUS NtStatusCode, IN struct _QUEUE_HEAD *QueueHead); @@ -103,6 +103,11 @@ protected: // UCHAR m_DeviceAddress; + // + // store end point address + // + PUSB_ENDPOINT_DESCRIPTOR m_EndpointDescriptor; + // // DMA queue head // @@ -143,6 +148,7 @@ CUSBRequest::InitializeWithSetupPacket( IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, + IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer) { @@ -160,6 +166,7 @@ CUSBRequest::InitializeWithSetupPacket( m_TransferBufferLength = TransferBufferLength; m_TransferBufferMDL = TransferBuffer; m_DeviceAddress = DeviceAddress; + m_EndpointDescriptor = EndpointDescriptor; // // allocate completion event @@ -242,6 +249,11 @@ CUSBRequest::InitializeWithIrp( // PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL); + // + // get endpoint descriptor + // + m_EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle; + // // get mdl buffer // @@ -590,8 +602,14 @@ CUSBRequest::BuildControlTransferQueueHead( // QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress(); - //if (PipeHandle) - // QueueHead->EndPointCharacteristics.EndPointNumber = ((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->bEndpointAddress & 0x0F; + if (m_EndpointDescriptor) + { + // + // set endpoint address and max packet length + // + QueueHead->EndPointCharacteristics.EndPointNumber = m_EndpointDescriptor->bEndpointAddress & 0x0F; + QueueHead->EndPointCharacteristics.MaximumPacketLength = m_EndpointDescriptor->wMaxPacketSize; + } QueueHead->Token.Bits.DataToggle = TRUE;