+/**\r
+ Reset endpoint through XHCI's Reset_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param Dci The device context index of endpoint.\r
+\r
+ @retval EFI_SUCCESS Reset endpoint successfully.\r
+ @retval Others Failed to reset endpoint.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcResetEndpoint (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 Dci\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ CMD_TRB_RESET_ENDPOINT CmdTrbResetED;\r
+\r
+ DEBUG ((EFI_D_INFO, "XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));\r
+\r
+ //\r
+ // Send stop endpoint command to transit Endpoint from running to stop state\r
+ //\r
+ ZeroMem (&CmdTrbResetED, sizeof (CmdTrbResetED));\r
+ CmdTrbResetED.CycleBit = 1;\r
+ CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT;\r
+ CmdTrbResetED.EDID = Dci;\r
+ CmdTrbResetED.SlotId = SlotId;\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Set transfer ring dequeue pointer through XHCI's Set_Tr_Dequeue_Pointer cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param Dci The device context index of endpoint.\r
+ @param Urb The dequeue pointer of the transfer ring specified\r
+ by the urb to be updated.\r
+\r
+ @retval EFI_SUCCESS Set transfer ring dequeue pointer succeeds.\r
+ @retval Others Failed to set transfer ring dequeue pointer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcSetTrDequeuePointer (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 Dci,\r
+ IN URB *Urb\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+ CMD_SET_TR_DEQ_POINTER CmdSetTRDeq;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+\r
+ DEBUG ((EFI_D_INFO, "XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));\r
+\r
+ //\r
+ // Send stop endpoint command to transit Endpoint from running to stop state\r
+ //\r
+ ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq));\r
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER));\r
+ CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS;\r
+ CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
+ CmdSetTRDeq.CycleBit = 1;\r
+ CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE;\r
+ CmdSetTRDeq.Endpoint = Dci;\r
+ CmdSetTRDeq.SlotId = SlotId;\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Set interface through XHCI's Configure_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param DeviceSpeed The device's speed.\r
+ @param ConfigDesc The pointer to the usb device configuration descriptor.\r
+ @param Request USB device request to send.\r
+\r
+ @retval EFI_SUCCESS Successfully set interface.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcSetInterface (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 DeviceSpeed,\r
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc,\r
+ IN EFI_USB_DEVICE_REQUEST *Request\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ USB_INTERFACE_DESCRIPTOR *IfDescActive;\r
+ USB_INTERFACE_DESCRIPTOR *IfDescSet;\r
+ USB_INTERFACE_DESCRIPTOR *IfDesc;\r
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;\r
+ UINTN NumEp;\r
+ UINTN EpIndex;\r
+ UINT8 EpAddr;\r
+ UINT8 Direction;\r
+ UINT8 Dci;\r
+ UINT8 MaxDci;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+ VOID *RingSeg;\r
+\r
+ CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;\r
+ INPUT_CONTEXT *InputContext;\r
+ DEVICE_CONTEXT *OutputContext;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
+ //\r
+ // XHCI 4.6.6 Configure Endpoint\r
+ // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop\r
+ // Context and Add Context flags as follows:\r
+ // 1) If an endpoint is not modified by the Alternate Interface setting, then software shall set the Drop\r
+ // Context and Add Context flags to '0'.\r
+ //\r
+ // Except the interface indicated by Reqeust->Index, no impact to other interfaces.\r
+ // So the default Drop Context and Add Context flags can be '0' to cover 1).\r
+ //\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
+ CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));\r
+\r
+ ASSERT (ConfigDesc != NULL);\r
+\r
+ MaxDci = 0;\r
+\r
+ IfDescActive = NULL;\r
+ IfDescSet = NULL;\r
+\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
+ while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {\r
+ if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >= sizeof (USB_INTERFACE_DESCRIPTOR))) {\r
+ if (IfDesc->InterfaceNumber == (UINT8) Request->Index) {\r
+ if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {\r
+ //\r
+ // Find out the active interface descriptor.\r
+ //\r
+ IfDescActive = IfDesc;\r
+ } else if (IfDesc->AlternateSetting == (UINT8) Request->Value) {\r
+ //\r
+ // Find out the interface descriptor to set.\r
+ //\r
+ IfDescSet = IfDesc;\r
+ }\r
+ }\r
+ }\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+ }\r
+\r
+ //\r
+ // XHCI 4.6.6 Configure Endpoint\r
+ // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop\r
+ // Context and Add Context flags as follows:\r
+ // 2) If an endpoint previously disabled, is enabled by the Alternate Interface setting, then software shall set\r
+ // the Drop Context flag to '0' and Add Context flag to '1', and initialize the Input Endpoint Context.\r
+ // 3) If an endpoint previously enabled, is disabled by the Alternate Interface setting, then software shall set\r
+ // the Drop Context flag to '1' and Add Context flag to '0'.\r
+ // 4) If a parameter of an enabled endpoint is modified by an Alternate Interface setting, the Drop Context\r
+ // and Add Context flags shall be set to '1'.\r
+ //\r
+ // Below codes are to cover 2), 3) and 4).\r
+ //\r
+\r
+ if ((IfDescActive != NULL) && (IfDescSet != NULL)) {\r
+ NumEp = IfDescActive->NumEndpoints;\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDescActive + 1);\r
+ for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {\r
+ while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ }\r
+\r
+ if (EpDesc->Length < sizeof (USB_ENDPOINT_DESCRIPTOR)) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
+ }\r
+\r
+ EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F);\r
+ Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
+\r
+ Dci = XhcEndpointToDci (EpAddr, Direction);\r
+ ASSERT (Dci < 32);\r
+ if (Dci > MaxDci) {\r
+ MaxDci = Dci;\r
+ }\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 1) Stop any Running Transfer Rings affected by the Alternate Interface setting.\r
+ //\r
+ Status = XhcStopEndpoint (Xhc, SlotId, Dci);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 2) Free Transfer Rings of all endpoints that will be affected by the Alternate Interface setting.\r
+ //\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] != NULL) {\r
+ RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;\r
+ if (RingSeg != NULL) {\r
+ UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);\r
+ }\r
+ FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]);\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] = NULL;\r
+ }\r
+\r
+ //\r
+ // Set the Drop Context flag to '1'.\r
+ //\r
+ InputContext->InputControlContext.Dword1 |= (BIT0 << Dci);\r
+\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ }\r
+\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 3) Clear all the Endpoint Context fields of each endpoint that will be disabled by the Alternate\r
+ // Interface setting, to '0'.\r
+ //\r
+ // The step 3) has been covered by the ZeroMem () to InputContext at the start of the function.\r
+ //\r
+\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 4) For each endpoint enabled by the Configure Endpoint Command:\r
+ // a. Allocate a Transfer Ring.\r
+ // b. Initialize the Transfer Ring Segment(s) by clearing all fields of all TRBs to '0'.\r
+ // c. Initialize the Endpoint Context data structure.\r
+ //\r
+ Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDescSet);\r
+ if (Dci > MaxDci) {\r
+ MaxDci = Dci;\r
+ }\r
+\r
+ InputContext->InputControlContext.Dword2 |= BIT0;\r
+ InputContext->Slot.ContextEntries = MaxDci;\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 5) Issue and successfully complete a Configure Endpoint Command.\r
+ //\r
+ ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));\r
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT));\r
+ CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);\r
+ CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
+ CmdTrbCfgEP.CycleBit = 1;\r
+ CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;\r
+ CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
+ DEBUG ((EFI_D_INFO, "SetInterface: Configure Endpoint\n"));\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status));\r
+ } else {\r
+ //\r
+ // Update the active AlternateSetting.\r
+ //\r
+ Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Set interface through XHCI's Configure_Endpoint cmd.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param SlotId The slot id to be configured.\r
+ @param DeviceSpeed The device's speed.\r
+ @param ConfigDesc The pointer to the usb device configuration descriptor.\r
+ @param Request USB device request to send.\r
+\r
+ @retval EFI_SUCCESS Successfully set interface.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcSetInterface64 (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 SlotId,\r
+ IN UINT8 DeviceSpeed,\r
+ IN USB_CONFIG_DESCRIPTOR *ConfigDesc,\r
+ IN EFI_USB_DEVICE_REQUEST *Request\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ USB_INTERFACE_DESCRIPTOR *IfDescActive;\r
+ USB_INTERFACE_DESCRIPTOR *IfDescSet;\r
+ USB_INTERFACE_DESCRIPTOR *IfDesc;\r
+ USB_ENDPOINT_DESCRIPTOR *EpDesc;\r
+ UINTN NumEp;\r
+ UINTN EpIndex;\r
+ UINT8 EpAddr;\r
+ UINT8 Direction;\r
+ UINT8 Dci;\r
+ UINT8 MaxDci;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+ VOID *RingSeg;\r
+\r
+ CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP;\r
+ INPUT_CONTEXT_64 *InputContext;\r
+ DEVICE_CONTEXT_64 *OutputContext;\r
+ EVT_TRB_COMMAND_COMPLETION *EvtTrb;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+ OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
+ //\r
+ // XHCI 4.6.6 Configure Endpoint\r
+ // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop\r
+ // Context and Add Context flags as follows:\r
+ // 1) If an endpoint is not modified by the Alternate Interface setting, then software shall set the Drop\r
+ // Context and Add Context flags to '0'.\r
+ //\r
+ // Except the interface indicated by Reqeust->Index, no impact to other interfaces.\r
+ // So the default Drop Context and Add Context flags can be '0' to cover 1).\r
+ //\r
+ ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+ CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64));\r
+\r
+ ASSERT (ConfigDesc != NULL);\r
+\r
+ MaxDci = 0;\r
+\r
+ IfDescActive = NULL;\r
+ IfDescSet = NULL;\r
+\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
+ while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) {\r
+ if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >= sizeof (USB_INTERFACE_DESCRIPTOR))) {\r
+ if (IfDesc->InterfaceNumber == (UINT8) Request->Index) {\r
+ if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {\r
+ //\r
+ // Find out the active interface descriptor.\r
+ //\r
+ IfDescActive = IfDesc;\r
+ } else if (IfDesc->AlternateSetting == (UINT8) Request->Value) {\r
+ //\r
+ // Find out the interface descriptor to set.\r
+ //\r
+ IfDescSet = IfDesc;\r
+ }\r
+ }\r
+ }\r
+ IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+ }\r
+\r
+ //\r
+ // XHCI 4.6.6 Configure Endpoint\r
+ // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop\r
+ // Context and Add Context flags as follows:\r
+ // 2) If an endpoint previously disabled, is enabled by the Alternate Interface setting, then software shall set\r
+ // the Drop Context flag to '0' and Add Context flag to '1', and initialize the Input Endpoint Context.\r
+ // 3) If an endpoint previously enabled, is disabled by the Alternate Interface setting, then software shall set\r
+ // the Drop Context flag to '1' and Add Context flag to '0'.\r
+ // 4) If a parameter of an enabled endpoint is modified by an Alternate Interface setting, the Drop Context\r
+ // and Add Context flags shall be set to '1'.\r
+ //\r
+ // Below codes are to cover 2), 3) and 4).\r
+ //\r
+\r
+ if ((IfDescActive != NULL) && (IfDescSet != NULL)) {\r
+ NumEp = IfDescActive->NumEndpoints;\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDescActive + 1);\r
+ for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {\r
+ while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ }\r
+\r
+ if (EpDesc->Length < sizeof (USB_ENDPOINT_DESCRIPTOR)) {\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ continue;\r
+ }\r
+\r
+ EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F);\r
+ Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);\r
+\r
+ Dci = XhcEndpointToDci (EpAddr, Direction);\r
+ ASSERT (Dci < 32);\r
+ if (Dci > MaxDci) {\r
+ MaxDci = Dci;\r
+ }\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 1) Stop any Running Transfer Rings affected by the Alternate Interface setting.\r
+ //\r
+ Status = XhcStopEndpoint (Xhc, SlotId, Dci);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 2) Free Transfer Rings of all endpoints that will be affected by the Alternate Interface setting.\r
+ //\r
+ if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] != NULL) {\r
+ RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;\r
+ if (RingSeg != NULL) {\r
+ UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);\r
+ }\r
+ FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]);\r
+ Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] = NULL;\r
+ }\r
+\r
+ //\r
+ // Set the Drop Context flag to '1'.\r
+ //\r
+ InputContext->InputControlContext.Dword1 |= (BIT0 << Dci);\r
+\r
+ EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+ }\r
+\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 3) Clear all the Endpoint Context fields of each endpoint that will be disabled by the Alternate\r
+ // Interface setting, to '0'.\r
+ //\r
+ // The step 3) has been covered by the ZeroMem () to InputContext at the start of the function.\r
+ //\r
+\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 4) For each endpoint enabled by the Configure Endpoint Command:\r
+ // a. Allocate a Transfer Ring.\r
+ // b. Initialize the Transfer Ring Segment(s) by clearing all fields of all TRBs to '0'.\r
+ // c. Initialize the Endpoint Context data structure.\r
+ //\r
+ Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDescSet);\r
+ if (Dci > MaxDci) {\r
+ MaxDci = Dci;\r
+ }\r
+\r
+ InputContext->InputControlContext.Dword2 |= BIT0;\r
+ InputContext->Slot.ContextEntries = MaxDci;\r
+ //\r
+ // XHCI 4.3.6 - Setting Alternate Interfaces\r
+ // 5) Issue and successfully complete a Configure Endpoint Command.\r
+ //\r
+ ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));\r
+ PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64));\r
+ CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);\r
+ CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
+ CmdTrbCfgEP.CycleBit = 1;\r
+ CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;\r
+ CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;\r
+ DEBUG ((EFI_D_INFO, "SetInterface64: Configure Endpoint\n"));\r
+ Status = XhcCmdTransfer (\r
+ Xhc,\r
+ (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
+ XHC_GENERIC_TIMEOUT,\r
+ (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status));\r
+ } else {\r
+ //\r
+ // Update the active AlternateSetting.\r
+ //\r
+ Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r