]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg XhciDxe: XHCI multiple interface alternate setting support.
authorStar Zeng <star.zeng@intel.com>
Fri, 4 Jul 2014 03:30:46 +0000 (03:30 +0000)
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 4 Jul 2014 03:30:46 +0000 (03:30 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15617 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h

index bd308613f6eade89246b54be4d292eae93b5380e..dc62c1f6c473203bf5e6b1e94a05570dadb36da8 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The XHCI controller driver.\r
 \r
 /** @file\r
   The XHCI controller driver.\r
 \r
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -968,6 +968,10 @@ XhcControlTransfer (
         ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);\r
         Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength);\r
         CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);\r
         ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);\r
         Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength);\r
         CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);\r
+        //\r
+        // Default to use AlternateSetting 0 for all interfaces.\r
+        //\r
+        Xhc->UsbDevContext[SlotId].ActiveAlternateSetting = AllocateZeroPool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->NumInterfaces * sizeof (UINT8));\r
       }\r
     } else if (((DescriptorType == USB_DESC_TYPE_HUB) ||\r
                (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) {\r
       }\r
     } else if (((DescriptorType == USB_DESC_TYPE_HUB) ||\r
                (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) {\r
@@ -1009,6 +1013,20 @@ XhcControlTransfer (
         break;\r
       }\r
     }\r
         break;\r
       }\r
     }\r
+  } else if ((Request->Request     == USB_REQ_SET_INTERFACE) &&\r
+             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_INTERFACE))) {\r
+    //\r
+    // Hook Set_Interface request from UsbBus as we need configure interface setting.\r
+    // Request->Value indicates AlterlateSetting to set\r
+    // Request->Index indicates Interface to set\r
+    //\r
+    if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] != (UINT8) Request->Value) {\r
+      if (Xhc->HcCParams.Data.Csz == 0) {\r
+        Status = XhcSetInterface (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);\r
+      } else {\r
+        Status = XhcSetInterface64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);\r
+      }\r
+    }\r
   } else if ((Request->Request     == USB_REQ_GET_STATUS) &&\r
              (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) {\r
     ASSERT (Data != NULL);\r
   } else if ((Request->Request     == USB_REQ_GET_STATUS) &&\r
              (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) {\r
     ASSERT (Data != NULL);\r
index 1eb0d0e176bb4970583da0c7fdac8898defe8b00..729a8c0dd562ee445a1d41ffe12a5b3b1a55e794 100644 (file)
@@ -2,7 +2,7 @@
 \r
   Provides some data structure definitions used by the XHCI host controller driver.\r
 \r
 \r
   Provides some data structure definitions used by the XHCI host controller driver.\r
 \r
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -196,6 +196,14 @@ struct _USB_DEV_CONTEXT {
   // These information is used to support XHCI's Config_Endpoint cmd.\r
   //\r
   EFI_USB_CONFIG_DESCRIPTOR **ConfDesc;\r
   // These information is used to support XHCI's Config_Endpoint cmd.\r
   //\r
   EFI_USB_CONFIG_DESCRIPTOR **ConfDesc;\r
+  //\r
+  // A device has an active Configuration.\r
+  //\r
+  UINT8                     ActiveConfiguration;\r
+  //\r
+  // Every interface has an active AlternateSetting.\r
+  //\r
+  UINT8                     *ActiveAlternateSetting;\r
 };\r
 \r
 struct _USB_XHCI_INSTANCE {\r
 };\r
 \r
 struct _USB_XHCI_INSTANCE {\r
index ec13e49a7cb0e5479fba3f4453742f830208d799..e5e1b3d802c0873a1b458db8dea1b2d6fa66544b 100644 (file)
@@ -2,7 +2,7 @@
 \r
   XHCI transfer scheduling routines.\r
 \r
 \r
   XHCI transfer scheduling routines.\r
 \r
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -750,7 +750,7 @@ CreateEventRing (
   //\r
   EventRing->EventRingCCS = 1;\r
 \r
   //\r
   EventRing->EventRingCCS = 1;\r
 \r
-  Size = EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER);\r
+  Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;\r
   Buf = UsbHcAllocateMem (Xhc->MemPool, Size);\r
   ASSERT (Buf != NULL);\r
   ASSERT (((UINTN) Buf & 0x3F) == 0);\r
   Buf = UsbHcAllocateMem (Xhc->MemPool, Size);\r
   ASSERT (Buf != NULL);\r
   ASSERT (((UINTN) Buf & 0x3F) == 0);\r
@@ -2385,6 +2385,10 @@ XhcDisableSlotCmd (
     }\r
   }\r
 \r
     }\r
   }\r
 \r
+  if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting != NULL) {\r
+    FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting);\r
+  }\r
+\r
   if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
     UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT));\r
   }\r
   if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
     UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT));\r
   }\r
@@ -2488,6 +2492,10 @@ XhcDisableSlotCmd64 (
     }\r
   }\r
 \r
     }\r
   }\r
 \r
+  if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting != NULL) {\r
+    FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting);\r
+  }\r
+\r
   if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
     UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64));\r
   }\r
   if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
     UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64));\r
   }\r
@@ -2506,6 +2514,311 @@ XhcDisableSlotCmd64 (
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
+/**\r
+  Initialize endpoint context in input context.\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 InputContext   The pointer to the input context.\r
+  @param IfDesc         The pointer to the usb device interface descriptor.\r
+\r
+  @return The maximum device context index of endpoint.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+XhcInitializeEndpointContext (\r
+  IN USB_XHCI_INSTANCE          *Xhc,\r
+  IN UINT8                      SlotId,\r
+  IN UINT8                      DeviceSpeed,\r
+  IN INPUT_CONTEXT              *InputContext,\r
+  IN USB_INTERFACE_DESCRIPTOR   *IfDesc\r
+  )\r
+{\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
+  UINT8                         Interval;\r
+  TRANSFER_RING                 *EndpointTransferRing;\r
+\r
+  MaxDci = 0;\r
+\r
+  NumEp = IfDesc->NumEndpoints;\r
+\r
+  EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 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
+    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
+    InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);\r
+    InputContext->EP[Dci-1].MaxPacketSize     = EpDesc->MaxPacketSize;\r
+\r
+    if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
+      //\r
+      // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.\r
+      //\r
+      InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+    } else {\r
+      InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+    }\r
+\r
+    switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {\r
+      case USB_ENDPOINT_BULK:\r
+        if (Direction == EfiUsbDataIn) {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_BULK_IN;\r
+        } else {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_BULK_OUT;\r
+        }\r
+\r
+        InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+        if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+          EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+          Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+          CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+        }\r
+\r
+        break;\r
+      case USB_ENDPOINT_ISO:\r
+        if (Direction == EfiUsbDataIn) {\r
+          InputContext->EP[Dci-1].CErr   = 0;\r
+          InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;\r
+        } else {\r
+          InputContext->EP[Dci-1].CErr   = 0;\r
+          InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
+        }\r
+        break;\r
+      case USB_ENDPOINT_INTERRUPT:\r
+        if (Direction == EfiUsbDataIn) {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;\r
+        } else {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;\r
+        }\r
+        InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+        InputContext->EP[Dci-1].MaxESITPayload   = EpDesc->MaxPacketSize;\r
+        //\r
+        // Get the bInterval from descriptor and init the the interval field of endpoint context\r
+        //\r
+        if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
+          Interval = EpDesc->Interval;\r
+          //\r
+          // Calculate through the bInterval field of Endpoint descriptor.\r
+          //\r
+          ASSERT (Interval != 0);\r
+          InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;\r
+        } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
+          Interval = EpDesc->Interval;\r
+          ASSERT (Interval >= 1 && Interval <= 16);\r
+          //\r
+          // Refer to XHCI 1.0 spec section 6.2.3.6, table 61\r
+          //\r
+          InputContext->EP[Dci-1].Interval         = Interval - 1;\r
+          InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+          InputContext->EP[Dci-1].MaxESITPayload   = 0x0002;\r
+          InputContext->EP[Dci-1].MaxBurstSize     = 0x0;\r
+          InputContext->EP[Dci-1].CErr             = 3;\r
+        }\r
+\r
+        if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+          EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+          Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+          CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+        }\r
+        break;\r
+\r
+      case USB_ENDPOINT_CONTROL:\r
+      default:\r
+        ASSERT (0);\r
+        break;\r
+    }\r
+\r
+    PhyAddr = UsbHcGetPciAddrForHostAddr (\r
+                Xhc->MemPool,\r
+                ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,\r
+                sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER\r
+                );\r
+    PhyAddr &= ~(0x0F);\r
+    PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+    InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);\r
+    InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
+\r
+    EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+  }\r
+\r
+  return MaxDci;\r
+}\r
+\r
+/**\r
+  Initialize endpoint context in input context.\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 InputContext   The pointer to the input context.\r
+  @param IfDesc         The pointer to the usb device interface descriptor.\r
+\r
+  @return The maximum device context index of endpoint.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+XhcInitializeEndpointContext64 (\r
+  IN USB_XHCI_INSTANCE          *Xhc,\r
+  IN UINT8                      SlotId,\r
+  IN UINT8                      DeviceSpeed,\r
+  IN INPUT_CONTEXT_64           *InputContext,\r
+  IN USB_INTERFACE_DESCRIPTOR   *IfDesc\r
+  )\r
+{\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
+  UINT8                         Interval;\r
+  TRANSFER_RING                 *EndpointTransferRing;\r
+\r
+  MaxDci = 0;\r
+\r
+  NumEp = IfDesc->NumEndpoints;\r
+\r
+  EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 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
+    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
+    InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);\r
+    InputContext->EP[Dci-1].MaxPacketSize     = EpDesc->MaxPacketSize;\r
+\r
+    if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
+      //\r
+      // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.\r
+      //\r
+      InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+    } else {\r
+      InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
+    }\r
+\r
+    switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {\r
+      case USB_ENDPOINT_BULK:\r
+        if (Direction == EfiUsbDataIn) {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_BULK_IN;\r
+        } else {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_BULK_OUT;\r
+        }\r
+\r
+        InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+        if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+          EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+          Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+          CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+        }\r
+\r
+        break;\r
+      case USB_ENDPOINT_ISO:\r
+        if (Direction == EfiUsbDataIn) {\r
+          InputContext->EP[Dci-1].CErr   = 0;\r
+          InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;\r
+        } else {\r
+          InputContext->EP[Dci-1].CErr   = 0;\r
+          InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
+        }\r
+        break;\r
+      case USB_ENDPOINT_INTERRUPT:\r
+        if (Direction == EfiUsbDataIn) {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;\r
+        } else {\r
+          InputContext->EP[Dci-1].CErr   = 3;\r
+          InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;\r
+        }\r
+        InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+        InputContext->EP[Dci-1].MaxESITPayload   = EpDesc->MaxPacketSize;\r
+        //\r
+        // Get the bInterval from descriptor and init the the interval field of endpoint context\r
+        //\r
+        if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
+          Interval = EpDesc->Interval;\r
+          //\r
+          // Calculate through the bInterval field of Endpoint descriptor.\r
+          //\r
+          ASSERT (Interval != 0);\r
+          InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;\r
+        } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
+          Interval = EpDesc->Interval;\r
+          ASSERT (Interval >= 1 && Interval <= 16);\r
+          //\r
+          // Refer to XHCI 1.0 spec section 6.2.3.6, table 61\r
+          //\r
+          InputContext->EP[Dci-1].Interval         = Interval - 1;\r
+          InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
+          InputContext->EP[Dci-1].MaxESITPayload   = 0x0002;\r
+          InputContext->EP[Dci-1].MaxBurstSize     = 0x0;\r
+          InputContext->EP[Dci-1].CErr             = 3;\r
+        }\r
+\r
+        if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
+          EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
+          Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
+          CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+        }\r
+        break;\r
+\r
+      case USB_ENDPOINT_CONTROL:\r
+      default:\r
+        ASSERT (0);\r
+        break;\r
+    }\r
+\r
+    PhyAddr = UsbHcGetPciAddrForHostAddr (\r
+                Xhc->MemPool,\r
+                ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,\r
+                sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER\r
+                );\r
+    PhyAddr &= ~(0x0F);\r
+    PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+    InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);\r
+    InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
+\r
+    EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+  }\r
+\r
+  return MaxDci;\r
+}\r
 \r
 /**\r
   Configure all the device endpoints through XHCI's Configure_Endpoint cmd.\r
 \r
 /**\r
   Configure all the device endpoints through XHCI's Configure_Endpoint cmd.\r
@@ -2529,18 +2842,11 @@ XhcSetConfigCmd (
 {\r
   EFI_STATUS                  Status;\r
   USB_INTERFACE_DESCRIPTOR    *IfDesc;\r
 {\r
   EFI_STATUS                  Status;\r
   USB_INTERFACE_DESCRIPTOR    *IfDesc;\r
-  USB_ENDPOINT_DESCRIPTOR     *EpDesc;\r
   UINT8                       Index;\r
   UINT8                       Index;\r
-  UINTN                       NumEp;\r
-  UINTN                       EpIndex;\r
-  UINT8                       EpAddr;\r
-  UINT8                       Direction;\r
   UINT8                       Dci;\r
   UINT8                       MaxDci;\r
   EFI_PHYSICAL_ADDRESS        PhyAddr;\r
   UINT8                       Dci;\r
   UINT8                       MaxDci;\r
   EFI_PHYSICAL_ADDRESS        PhyAddr;\r
-  UINT8                       Interval;\r
 \r
 \r
-  TRANSFER_RING               *EndpointTransferRing;\r
   CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
   INPUT_CONTEXT               *InputContext;\r
   DEVICE_CONTEXT              *OutputContext;\r
   CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
   INPUT_CONTEXT               *InputContext;\r
   DEVICE_CONTEXT              *OutputContext;\r
@@ -2559,124 +2865,15 @@ XhcSetConfigCmd (
 \r
   IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
   for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {\r
 \r
   IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
   for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {\r
-    while (IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) {\r
+    while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {\r
       IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
     }\r
 \r
       IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
     }\r
 \r
-    NumEp = IfDesc->NumEndpoints;\r
-\r
-    EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 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
-      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
-      InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);\r
-      InputContext->EP[Dci-1].MaxPacketSize     = EpDesc->MaxPacketSize;\r
-\r
-      if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
-        //\r
-        // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.\r
-        //\r
-        InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
-      } else {\r
-        InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
-      }\r
-\r
-      switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {\r
-        case USB_ENDPOINT_BULK:\r
-          if (Direction == EfiUsbDataIn) {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_BULK_IN;\r
-          } else {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_BULK_OUT;\r
-          }\r
-\r
-          InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-          if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
-            EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
-            Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
-            CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
-          }\r
-\r
-          break;\r
-        case USB_ENDPOINT_ISO:\r
-          if (Direction == EfiUsbDataIn) {\r
-            InputContext->EP[Dci-1].CErr   = 0;\r
-            InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;\r
-          } else {\r
-            InputContext->EP[Dci-1].CErr   = 0;\r
-            InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
-          }\r
-          break;\r
-        case USB_ENDPOINT_INTERRUPT:\r
-          if (Direction == EfiUsbDataIn) {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;\r
-          } else {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;\r
-          }\r
-          InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-          InputContext->EP[Dci-1].MaxESITPayload   = EpDesc->MaxPacketSize;\r
-          //\r
-          // Get the bInterval from descriptor and init the the interval field of endpoint context\r
-          //\r
-          if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
-            Interval = EpDesc->Interval;\r
-            //\r
-            // Calculate through the bInterval field of Endpoint descriptor.\r
-            //\r
-            ASSERT (Interval != 0);\r
-            InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;\r
-          } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
-            Interval = EpDesc->Interval;\r
-            ASSERT (Interval >= 1 && Interval <= 16);\r
-            //\r
-            // Refer to XHCI 1.0 spec section 6.2.3.6, table 61\r
-            //\r
-            InputContext->EP[Dci-1].Interval         = Interval - 1;\r
-            InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-            InputContext->EP[Dci-1].MaxESITPayload   = 0x0002;\r
-            InputContext->EP[Dci-1].MaxBurstSize     = 0x0;\r
-            InputContext->EP[Dci-1].CErr             = 3;\r
-          }\r
-\r
-          if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
-            EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
-            Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
-            CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
-          }\r
-          break;\r
-\r
-        case USB_ENDPOINT_CONTROL:\r
-        default:\r
-          ASSERT (0);\r
-          break;\r
-      }\r
-\r
-      PhyAddr = UsbHcGetPciAddrForHostAddr (\r
-                  Xhc->MemPool,\r
-                  ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,\r
-                  sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER\r
-                  );\r
-      PhyAddr &= ~(0x0F);\r
-      PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
-      InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);\r
-      InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
-\r
-      EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+    Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc);\r
+    if (Dci > MaxDci) {\r
+      MaxDci = Dci;\r
     }\r
     }\r
+\r
     IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
   }\r
 \r
     IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
   }\r
 \r
@@ -2701,7 +2898,10 @@ XhcSetConfigCmd (
              );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));\r
              );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));\r
+  } else {\r
+    Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;\r
   }\r
   }\r
+\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
@@ -2727,18 +2927,11 @@ XhcSetConfigCmd64 (
 {\r
   EFI_STATUS                  Status;\r
   USB_INTERFACE_DESCRIPTOR    *IfDesc;\r
 {\r
   EFI_STATUS                  Status;\r
   USB_INTERFACE_DESCRIPTOR    *IfDesc;\r
-  USB_ENDPOINT_DESCRIPTOR     *EpDesc;\r
   UINT8                       Index;\r
   UINT8                       Index;\r
-  UINTN                       NumEp;\r
-  UINTN                       EpIndex;\r
-  UINT8                       EpAddr;\r
-  UINT8                       Direction;\r
   UINT8                       Dci;\r
   UINT8                       MaxDci;\r
   EFI_PHYSICAL_ADDRESS        PhyAddr;\r
   UINT8                       Dci;\r
   UINT8                       MaxDci;\r
   EFI_PHYSICAL_ADDRESS        PhyAddr;\r
-  UINT8                       Interval;\r
 \r
 \r
-  TRANSFER_RING               *EndpointTransferRing;\r
   CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
   INPUT_CONTEXT_64            *InputContext;\r
   DEVICE_CONTEXT_64           *OutputContext;\r
   CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
   INPUT_CONTEXT_64            *InputContext;\r
   DEVICE_CONTEXT_64           *OutputContext;\r
@@ -2757,126 +2950,15 @@ XhcSetConfigCmd64 (
 \r
   IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
   for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {\r
 \r
   IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
   for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {\r
-    while (IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) {\r
+    while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {\r
       IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
     }\r
 \r
       IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
     }\r
 \r
-    NumEp = IfDesc->NumEndpoints;\r
-\r
-    EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 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
-      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
-      InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);\r
-      InputContext->EP[Dci-1].MaxPacketSize     = EpDesc->MaxPacketSize;\r
-\r
-      if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
-        //\r
-        // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor.\r
-        //\r
-        InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
-      } else {\r
-        InputContext->EP[Dci-1].MaxBurstSize = 0x0;\r
-      }\r
-\r
-      switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {\r
-        case USB_ENDPOINT_BULK:\r
-          if (Direction == EfiUsbDataIn) {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_BULK_IN;\r
-          } else {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_BULK_OUT;\r
-          }\r
-\r
-          InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-          if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
-            EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
-            Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
-            CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
-          }\r
-\r
-          break;\r
-        case USB_ENDPOINT_ISO:\r
-          if (Direction == EfiUsbDataIn) {\r
-            InputContext->EP[Dci-1].CErr   = 0;\r
-            InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;\r
-          } else {\r
-            InputContext->EP[Dci-1].CErr   = 0;\r
-            InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;\r
-          }\r
-          break;\r
-        case USB_ENDPOINT_INTERRUPT:\r
-          if (Direction == EfiUsbDataIn) {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;\r
-          } else {\r
-            InputContext->EP[Dci-1].CErr   = 3;\r
-            InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;\r
-          }\r
-          InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-          InputContext->EP[Dci-1].MaxESITPayload   = EpDesc->MaxPacketSize;\r
-          //\r
-          // Get the bInterval from descriptor and init the the interval field of endpoint context\r
-          //\r
-          if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
-            Interval = EpDesc->Interval;\r
-            //\r
-            // Calculate through the bInterval field of Endpoint descriptor.\r
-            //\r
-            ASSERT (Interval != 0);\r
-            InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;\r
-          } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
-            Interval = EpDesc->Interval;\r
-            ASSERT (Interval >= 1 && Interval <= 16);\r
-            //\r
-            // Refer to XHCI 1.0 spec section 6.2.3.6, table 61\r
-            //\r
-            InputContext->EP[Dci-1].Interval         = Interval - 1;\r
-            InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-            InputContext->EP[Dci-1].MaxESITPayload   = 0x0002;\r
-            InputContext->EP[Dci-1].MaxBurstSize     = 0x0;\r
-            InputContext->EP[Dci-1].CErr             = 3;\r
-          }\r
-\r
-          if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
-            EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
-            Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
-            CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
-          }\r
-          break;\r
-\r
-        case USB_ENDPOINT_CONTROL:\r
-        default:\r
-          ASSERT (0);\r
-          break;\r
-      }\r
-\r
-      PhyAddr = UsbHcGetPciAddrForHostAddr (\r
-                  Xhc->MemPool,\r
-                  ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,\r
-                  sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER\r
-                  );\r
-\r
-      PhyAddr &= ~(0x0F);\r
-      PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
-\r
-      InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);\r
-      InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);\r
-\r
-      EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+    Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc);\r
+    if (Dci > MaxDci) {\r
+      MaxDci = Dci;\r
     }\r
     }\r
\r
     IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
   }\r
 \r
     IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
   }\r
 \r
@@ -2901,11 +2983,452 @@ XhcSetConfigCmd64 (
              );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));\r
              );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));\r
+  } else {\r
+    Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Stop endpoint through XHCI's Stop_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           Stop endpoint successfully.\r
+  @retval Others                Failed to stop endpoint.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcStopEndpoint (\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_STOP_ENDPOINT         CmdTrbStopED;\r
+\r
+  DEBUG ((EFI_D_INFO, "XhcStopEndpoint: 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 (&CmdTrbStopED, sizeof (CmdTrbStopED));\r
+  CmdTrbStopED.CycleBit = 1;\r
+  CmdTrbStopED.Type     = TRB_TYPE_STOP_ENDPOINT;\r
+  CmdTrbStopED.EDID     = Dci;\r
+  CmdTrbStopED.SlotId   = SlotId;\r
+  Status = XhcCmdTransfer (\r
+             Xhc,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbStopED,\r
+             XHC_GENERIC_TIMEOUT,\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+             );\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG ((EFI_D_ERROR, "XhcStopEndpoint: Stop Endpoint 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) {\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
+      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
 \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) {\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
+      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
 \r
 /**\r
   Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
 \r
 /**\r
   Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
index fa8bab43f09bea98ec442680f43239070f8be3c4..023c1089f29c78d93a737885702377fb6ad4aac7 100644 (file)
@@ -2,7 +2,7 @@
 \r
   This file contains the definition for XHCI host controller schedule routines.\r
 \r
 \r
   This file contains the definition for XHCI host controller schedule routines.\r
 \r
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -1041,6 +1041,49 @@ XhcSetConfigCmd64 (
   IN USB_CONFIG_DESCRIPTOR    *ConfigDesc\r
   );\r
 \r
   IN USB_CONFIG_DESCRIPTOR    *ConfigDesc\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
+/**\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
 /**\r
   Find out the actual device address according to the requested device address from UsbBus.\r
 \r
 /**\r
   Find out the actual device address according to the requested device address from UsbBus.\r