]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
MdeModulePkg: The patch eliminates two assumptions
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciSched.c
index 49cc2619eb4dbd9f986d853080009281fa1e5219..d0b616582ece11067fec3804fd6b5e624c4a52ed 100644 (file)
@@ -47,7 +47,7 @@ XhcCreateCmdTrb (
   Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0;\r
   Urb->TrbEnd             = Urb->TrbStart;\r
 \r
-  Urb->EvtRing     = &Xhc->CmdEventRing;\r
+  Urb->EvtRing     = &Xhc->EventRing;\r
   XhcSyncEventRing (Xhc, Urb->EvtRing);\r
   Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
 \r
@@ -106,7 +106,7 @@ XhcCmdTransfer (
     goto ON_EXIT;\r
   }\r
 \r
-  ASSERT (Urb->EvtRing == &Xhc->CmdEventRing);\r
+  ASSERT (Urb->EvtRing == &Xhc->EventRing);\r
 \r
   Status  = XhcExecTransfer (Xhc, TRUE, Urb, Timeout);\r
   *EvtTrb = Urb->EvtTrbStart;\r
@@ -125,7 +125,7 @@ ON_EXIT:
   Create a new URB for a new transaction.\r
 \r
   @param  Xhc       The XHCI Instance\r
-  @param  DevAddr   The device address\r
+  @param  BusAddr   The logical device address assigned by UsbBus driver\r
   @param  EpAddr    Endpoint addrress\r
   @param  DevSpeed  The device speed\r
   @param  MaxPacket The max packet length of the endpoint\r
@@ -142,7 +142,7 @@ ON_EXIT:
 URB*\r
 XhcCreateUrb (\r
   IN USB_XHCI_INSTANCE                  *Xhc,\r
-  IN UINT8                              DevAddr,\r
+  IN UINT8                              BusAddr,\r
   IN UINT8                              EpAddr,\r
   IN UINT8                              DevSpeed,\r
   IN UINTN                              MaxPacket,\r
@@ -167,7 +167,7 @@ XhcCreateUrb (
   InitializeListHead (&Urb->UrbList);\r
 \r
   Ep            = &Urb->Ep;\r
-  Ep->DevAddr   = DevAddr;\r
+  Ep->BusAddr   = BusAddr;\r
   Ep->EpAddr    = (UINT8)(EpAddr & 0x0F);\r
   Ep->Direction = ((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;\r
   Ep->DevSpeed  = DevSpeed;\r
@@ -201,7 +201,7 @@ XhcCreateTransferTrb (
   IN URB                        *Urb\r
   )\r
 {\r
-  DEVICE_CONTEXT                *OutputContext;\r
+  VOID                          *OutputContext;\r
   TRANSFER_RING                 *EPRing;\r
   UINT8                         EPType;\r
   UINT8                         SlotId;\r
@@ -211,13 +211,21 @@ XhcCreateTransferTrb (
   UINTN                         Len;\r
   UINTN                         TrbNum;\r
 \r
-  SlotId    = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr);\r
+  SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+  if (SlotId == 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
   Dci       = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
   ASSERT (Dci < 32);\r
   EPRing    = (TRANSFER_RING *)(UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];\r
   Urb->Ring = EPRing;\r
-  OutputContext = (DEVICE_CONTEXT *)(UINTN) Xhc->DCBAA[SlotId];\r
-  EPType    = (UINT8) OutputContext->EP[Dci-1].EPType;\r
+  OutputContext = (VOID *)(UINTN)Xhc->DCBAA[SlotId];\r
+  if (Xhc->HcCParams.Data.Csz == 0) {\r
+    EPType  = (UINT8) ((DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType;\r
+  } else {\r
+    EPType  = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType;\r
+  }\r
 \r
   //\r
   // Construct the TRB\r
@@ -226,7 +234,7 @@ XhcCreateTransferTrb (
   Urb->TrbStart = EPRing->RingEnqueue;\r
   switch (EPType) {\r
     case ED_CONTROL_BIDIR:\r
-      Urb->EvtRing     = &Xhc->CtrlTrEventRing;\r
+      Urb->EvtRing     = &Xhc->EventRing;\r
       XhcSyncEventRing (Xhc, Urb->EvtRing);\r
       Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
       //\r
@@ -239,7 +247,7 @@ XhcCreateTransferTrb (
       TrbStart->TrbCtrSetup.wIndex        = Urb->Request->Index;\r
       TrbStart->TrbCtrSetup.wLength       = Urb->Request->Length;\r
       TrbStart->TrbCtrSetup.Lenth         = 8;\r
-      TrbStart->TrbCtrSetup.IntTarget     = Urb->EvtRing->EventInterrupter;\r
+      TrbStart->TrbCtrSetup.IntTarget     = 0;\r
       TrbStart->TrbCtrSetup.IOC           = 1;\r
       TrbStart->TrbCtrSetup.IDT           = 1;\r
       TrbStart->TrbCtrSetup.Type          = TRB_TYPE_SETUP_STAGE;\r
@@ -266,7 +274,7 @@ XhcCreateTransferTrb (
         TrbStart->TrbCtrData.TRBPtrHi  = XHC_HIGH_32BIT(Urb->Data);\r
         TrbStart->TrbCtrData.Lenth     = (UINT32) Urb->DataLen;\r
         TrbStart->TrbCtrData.TDSize    = 0;\r
-        TrbStart->TrbCtrData.IntTarget = Urb->EvtRing->EventInterrupter;\r
+        TrbStart->TrbCtrData.IntTarget = 0;\r
         TrbStart->TrbCtrData.ISP       = 1;\r
         TrbStart->TrbCtrData.IOC       = 1;\r
         TrbStart->TrbCtrData.IDT       = 0;\r
@@ -291,7 +299,7 @@ XhcCreateTransferTrb (
       //\r
       XhcSyncTrsRing (Xhc, EPRing);\r
       TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
-      TrbStart->TrbCtrStatus.IntTarget = Urb->EvtRing->EventInterrupter;\r
+      TrbStart->TrbCtrStatus.IntTarget = 0;\r
       TrbStart->TrbCtrStatus.IOC       = 1;\r
       TrbStart->TrbCtrStatus.CH        = 0;\r
       TrbStart->TrbCtrStatus.Type      = TRB_TYPE_STATUS_STAGE;\r
@@ -317,7 +325,7 @@ XhcCreateTransferTrb (
 \r
     case ED_BULK_OUT:\r
     case ED_BULK_IN:\r
-      Urb->EvtRing     = &Xhc->BulkTrEventRing;\r
+      Urb->EvtRing     = &Xhc->EventRing;\r
       XhcSyncEventRing (Xhc, Urb->EvtRing);\r
       Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
 \r
@@ -336,7 +344,7 @@ XhcCreateTransferTrb (
         TrbStart->TrbNormal.TRBPtrHi  = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
         TrbStart->TrbNormal.Lenth     = (UINT32) Len;\r
         TrbStart->TrbNormal.TDSize    = 0;\r
-        TrbStart->TrbNormal.IntTarget = Urb->EvtRing->EventInterrupter;\r
+        TrbStart->TrbNormal.IntTarget = 0;\r
         TrbStart->TrbNormal.ISP       = 1;\r
         TrbStart->TrbNormal.IOC       = 1;\r
         TrbStart->TrbNormal.Type      = TRB_TYPE_NORMAL;\r
@@ -356,14 +364,7 @@ XhcCreateTransferTrb (
 \r
     case ED_INTERRUPT_OUT:\r
     case ED_INTERRUPT_IN:\r
-      if (Urb->Ep.Type == XHC_INT_TRANSFER_ASYNC) {\r
-        Urb->EvtRing = &Xhc->AsynIntTrEventRing;\r
-      } else if(Urb->Ep.Type == XHC_INT_TRANSFER_SYNC){\r
-        Urb->EvtRing = &Xhc->IntTrEventRing;\r
-      } else {\r
-        DEBUG ((EFI_D_ERROR, "EP Interrupt type error!\n"));\r
-        ASSERT(FALSE);\r
-      }\r
+      Urb->EvtRing = &Xhc->EventRing;\r
       XhcSyncEventRing (Xhc, Urb->EvtRing);\r
       Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
 \r
@@ -382,7 +383,7 @@ XhcCreateTransferTrb (
         TrbStart->TrbNormal.TRBPtrHi  = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
         TrbStart->TrbNormal.Lenth     = (UINT32) Len;\r
         TrbStart->TrbNormal.TDSize    = 0;\r
-        TrbStart->TrbNormal.IntTarget = Urb->EvtRing->EventInterrupter;\r
+        TrbStart->TrbNormal.IntTarget = 0;\r
         TrbStart->TrbNormal.ISP       = 1;\r
         TrbStart->TrbNormal.IOC       = 1;\r
         TrbStart->TrbNormal.Type      = TRB_TYPE_NORMAL;\r
@@ -481,7 +482,12 @@ XhcInitSched (
   // a 64-bit address pointing to where the Device Context Base Address Array is located.\r
   //\r
   Xhc->DCBAA = (UINT64 *)(UINTN)Dcbaa;\r
-  XhcWriteOpReg64 (Xhc, XHC_DCBAAP_OFFSET, (UINT64)(UINTN)Xhc->DCBAA);\r
+  //\r
+  // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+  // So divide it to two 32-bytes width register access.\r
+  //\r
+  XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT(Xhc->DCBAA));\r
+  XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET + 4, XHC_HIGH_32BIT (Xhc->DCBAA));\r
   DEBUG ((EFI_D_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)(UINTN)Xhc->DCBAA));\r
 \r
   //\r
@@ -499,7 +505,12 @@ XhcInitSched (
   CmdRing  = (UINT64)(UINTN)Xhc->CmdRing.RingSeg0;\r
   ASSERT ((CmdRing & 0x3F) == 0);\r
   CmdRing |= XHC_CRCR_RCS;\r
-  XhcWriteOpReg64 (Xhc, XHC_CRCR_OFFSET, CmdRing);\r
+  //\r
+  // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+  // So divide it to two 32-bytes width register access.\r
+  //\r
+  XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT(CmdRing));\r
+  XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRing));\r
 \r
   DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0));\r
 \r
@@ -516,11 +527,8 @@ XhcInitSched (
   //\r
   // Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer\r
   //\r
-  CreateEventRing (Xhc, CMD_INTER, &Xhc->CmdEventRing);\r
-  CreateEventRing (Xhc, CTRL_INTER, &Xhc->CtrlTrEventRing);\r
-  CreateEventRing (Xhc, BULK_INTER, &Xhc->BulkTrEventRing);\r
-  CreateEventRing (Xhc, INT_INTER, &Xhc->IntTrEventRing);\r
-  CreateEventRing (Xhc, INT_INTER_ASYNC, &Xhc->AsynIntTrEventRing);\r
+  CreateEventRing (Xhc, &Xhc->EventRing);\r
+  DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0));\r
 }\r
 \r
 /**\r
@@ -551,10 +559,14 @@ XhcRecoverHaltedEndpoint (
   UINT8                       Dci;\r
   UINT8                       SlotId;\r
 \r
-  Status     = EFI_SUCCESS;\r
-  SlotId     = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr);\r
-  Dci        = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
-\r
+  Status = EFI_SUCCESS;\r
+  SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+  if (SlotId == 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+  ASSERT (Dci < 32);\r
+  \r
   DEBUG ((EFI_D_INFO, "Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci));\r
 \r
   //\r
@@ -603,14 +615,12 @@ XhcRecoverHaltedEndpoint (
   Create XHCI event ring.\r
 \r
   @param  Xhc                 The XHCI Instance.\r
-  @param  EventInterrupter    The interrupter of event.\r
   @param  EventRing           The created event ring.\r
 \r
 **/\r
 VOID\r
 CreateEventRing (\r
   IN  USB_XHCI_INSTANCE     *Xhc,\r
-  IN  UINT8                 EventInterrupter,\r
   OUT EVENT_RING            *EventRing\r
   )\r
 {\r
@@ -625,7 +635,6 @@ CreateEventRing (
   ZeroMem (Buf, sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER);\r
 \r
   EventRing->EventRingSeg0    = Buf;\r
-  EventRing->EventInterrupter = EventInterrupter;\r
   EventRing->TrbNumber        = EVENT_RING_TRB_NUMBER;\r
   EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;\r
   EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;\r
@@ -651,29 +660,45 @@ CreateEventRing (
   //\r
   XhcWriteRuntimeReg (\r
     Xhc,\r
-    XHC_ERSTSZ_OFFSET + (32 * EventRing->EventInterrupter),\r
+    XHC_ERSTSZ_OFFSET,\r
     ERST_NUMBER\r
     );\r
   //\r
   // Program the Interrupter Event Ring Dequeue Pointer (ERDP) register (5.5.2.3.3)\r
   //\r
-  XhcWriteRuntimeReg64 (\r
+  // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+  // So divide it to two 32-bytes width register access.\r
+  //\r
+  XhcWriteRuntimeReg (\r
+    Xhc,\r
+    XHC_ERDP_OFFSET,\r
+    XHC_LOW_32BIT((UINT64)(UINTN)EventRing->EventRingDequeue)\r
+    );\r
+  XhcWriteRuntimeReg (\r
     Xhc,\r
-    XHC_ERDP_OFFSET + (32 * EventRing->EventInterrupter),\r
-    (UINT64)(UINTN)EventRing->EventRingDequeue\r
+    XHC_ERDP_OFFSET + 4,\r
+    XHC_HIGH_32BIT((UINT64)(UINTN)EventRing->EventRingDequeue)\r
     );\r
   //\r
   // Program the Interrupter Event Ring Segment Table Base Address (ERSTBA) register(5.5.2.3.2)\r
   //\r
-  XhcWriteRuntimeReg64 (\r
+  // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+  // So divide it to two 32-bytes width register access.\r
+  //\r
+  XhcWriteRuntimeReg (\r
+    Xhc,\r
+    XHC_ERSTBA_OFFSET,\r
+    XHC_LOW_32BIT((UINT64)(UINTN)ERSTBase)\r
+    );\r
+  XhcWriteRuntimeReg (\r
     Xhc,\r
-    XHC_ERSTBA_OFFSET + (32 * EventRing->EventInterrupter),\r
-    (UINT64)(UINTN)ERSTBase\r
+    XHC_ERSTBA_OFFSET + 4,\r
+    XHC_HIGH_32BIT((UINT64)(UINTN)ERSTBase)\r
     );\r
   //\r
   // Need set IMAN IE bit to enble the ring interrupt\r
   //\r
-  XhcSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET + (32 * EventRing->EventInterrupter), XHC_IMAN_IE);\r
+  XhcSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET, XHC_IMAN_IE);\r
 }\r
 \r
 /**\r
@@ -800,11 +825,7 @@ XhcFreeSched (
     Xhc->CmdRing.RingSeg0 = NULL;\r
   }\r
 \r
-  XhcFreeEventRing (Xhc,&Xhc->CmdEventRing);\r
-  XhcFreeEventRing (Xhc,&Xhc->CtrlTrEventRing);\r
-  XhcFreeEventRing (Xhc,&Xhc->BulkTrEventRing);\r
-  XhcFreeEventRing (Xhc,&Xhc->AsynIntTrEventRing);\r
-  XhcFreeEventRing (Xhc,&Xhc->IntTrEventRing);\r
+  XhcFreeEventRing (Xhc,&Xhc->EventRing);\r
 }\r
 \r
 /**\r
@@ -894,74 +915,82 @@ XhcCheckUrbResult (
       goto EXIT;\r
     }\r
 \r
-    TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | (UINT64) EvtTrb->TRBPtrHi << 32);\r
+    //\r
+    // Only handle COMMAND_COMPLETETION_EVENT and TRANSFER_EVENT.\r
+    //\r
+    if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) {\r
+      continue;\r
+    }\r
 \r
-    switch (EvtTrb->Completecode) {\r
-      case TRB_COMPLETION_STALL_ERROR:\r
-        Urb->Result |= EFI_USB_ERR_STALL;\r
-        Status       = EFI_DEVICE_ERROR;\r
-        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
-        goto EXIT;\r
-        break;\r
+    TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | (UINT64) EvtTrb->TRBPtrHi << 32);\r
+    if (IsTransferRingTrb (Urb->Ring, TRBPtr)) {\r
+      switch (EvtTrb->Completecode) {\r
+        case TRB_COMPLETION_STALL_ERROR:\r
+          Urb->Result |= EFI_USB_ERR_STALL;\r
+          Status       = EFI_DEVICE_ERROR;\r
+          DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
+          goto EXIT;\r
+          break;\r
 \r
-      case TRB_COMPLETION_BABBLE_ERROR:\r
-        Urb->Result |= EFI_USB_ERR_BABBLE;\r
-        Status       = EFI_DEVICE_ERROR;\r
-        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
-        goto EXIT;\r
-        break;\r
+        case TRB_COMPLETION_BABBLE_ERROR:\r
+          Urb->Result |= EFI_USB_ERR_BABBLE;\r
+          Status       = EFI_DEVICE_ERROR;\r
+          DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
+          goto EXIT;\r
+          break;\r
 \r
-      case TRB_COMPLETION_DATA_BUFFER_ERROR:\r
-        Urb->Result |= EFI_USB_ERR_BUFFER;\r
-        Status       = EFI_DEVICE_ERROR;\r
-        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));\r
-        goto EXIT;\r
-        break;\r
+        case TRB_COMPLETION_DATA_BUFFER_ERROR:\r
+          Urb->Result |= EFI_USB_ERR_BUFFER;\r
+          Status       = EFI_DEVICE_ERROR;\r
+          DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));\r
+          goto EXIT;\r
+          break;\r
 \r
-      case TRB_COMPLETION_USB_TRANSACTION_ERROR:\r
-        Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
-        Status       = EFI_DEVICE_ERROR;\r
-        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
-        goto EXIT;\r
-        break;\r
+        case TRB_COMPLETION_USB_TRANSACTION_ERROR:\r
+          Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
+          Status       = EFI_DEVICE_ERROR;\r
+          DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
+          goto EXIT;\r
+          break;\r
 \r
-      case TRB_COMPLETION_SHORT_PACKET:\r
-      case TRB_COMPLETION_SUCCESS:\r
-        if (IsTransferRingTrb (Urb->Ring, TRBPtr)) {\r
+        case TRB_COMPLETION_SHORT_PACKET:\r
+        case TRB_COMPLETION_SUCCESS:\r
           if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {\r
             DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: short packet happens!\n"));\r
           }\r
+\r
           TRBType = (UINT8) (TRBPtr->Type);\r
           if ((TRBType == TRB_TYPE_DATA_STAGE) ||\r
               (TRBType == TRB_TYPE_NORMAL) ||\r
               (TRBType == TRB_TYPE_ISOCH)) {\r
             Urb->Completed += (Urb->DataLen - EvtTrb->Lenth);\r
           }\r
-        }\r
-        Status = EFI_SUCCESS;\r
-        break;\r
 \r
-      default:\r
-        DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));\r
-        Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
-        Status = EFI_DEVICE_ERROR;\r
-        goto EXIT;\r
-        break;\r
-    }\r
+          Status = EFI_SUCCESS;\r
+          break;\r
 \r
-    //\r
-    // Only check first and end Trb event address\r
-    //\r
-    if (TRBPtr == Urb->TrbStart) {\r
-      StartDone = TRUE;\r
-    }\r
+        default:\r
+          DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));\r
+          Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
+          Status = EFI_DEVICE_ERROR;\r
+          goto EXIT;\r
+          break;\r
+      }\r
 \r
-    if (TRBPtr == Urb->TrbEnd) {\r
-      EndDone = TRUE;\r
-    }\r
+      //\r
+      // Only check first and end Trb event address\r
+      //\r
+      if (TRBPtr == Urb->TrbStart) {\r
+        StartDone = TRUE;\r
+      }\r
 \r
-    if (StartDone && EndDone) {\r
-      break;\r
+      if (TRBPtr == Urb->TrbEnd) {\r
+        EndDone = TRUE;\r
+      }\r
+\r
+      if (StartDone && EndDone) {\r
+        break;\r
+      }\r
     }\r
   }\r
 \r
@@ -1001,8 +1030,12 @@ XhcExecTransfer (
     SlotId = 0;\r
     Dci    = 0;\r
   } else {\r
-    SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr);\r
-    Dci    = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+    SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+    if (SlotId == 0) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+    Dci  = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+    ASSERT (Dci < 32);\r
   }\r
 \r
   Status = EFI_SUCCESS;\r
@@ -1029,7 +1062,7 @@ XhcExecTransfer (
   the device and endpoint.\r
 \r
   @param  Xhc                   The XHCI Instance.\r
-  @param  DevAddr               The address of the target device.\r
+  @param  BusAddr               The logical device address assigned by UsbBus driver.\r
   @param  EpNum                 The endpoint of the target.\r
 \r
   @retval EFI_SUCCESS           An asynchronous transfer is removed.\r
@@ -1039,7 +1072,7 @@ XhcExecTransfer (
 EFI_STATUS\r
 XhciDelAsyncIntTransfer (\r
   IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT8               DevAddr,\r
+  IN  UINT8               BusAddr,\r
   IN  UINT8               EpNum\r
   )\r
 {\r
@@ -1051,11 +1084,11 @@ XhciDelAsyncIntTransfer (
   Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;\r
   EpNum    &= 0x0F;\r
 \r
-  Urb   = NULL;\r
+  Urb = NULL;\r
 \r
   EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
     Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
-    if ((Urb->Ep.DevAddr == DevAddr) &&\r
+    if ((Urb->Ep.BusAddr == BusAddr) &&\r
         (Urb->Ep.EpAddr == EpNum) &&\r
         (Urb->Ep.Direction == Direction)) {\r
       RemoveEntryList (&Urb->UrbList);\r
@@ -1108,9 +1141,13 @@ XhcUpdateAsyncRequest (
 \r
   if (Urb->Result == EFI_USB_NOERROR) {\r
     Status = XhcCreateTransferTrb (Xhc, Urb);\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
     Status = RingIntTransferDoorBell (Xhc, Urb);\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
   }\r
 }\r
 \r
@@ -1148,7 +1185,7 @@ XhcMonitorAsyncRequests (
     //\r
     // Make sure that the device is available before every check.\r
     //\r
-    SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr);\r
+    SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
     if (SlotId == 0) {\r
       continue;\r
     }\r
@@ -1271,7 +1308,11 @@ XhcPollPortStatusChange (
     //\r
     SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);\r
     if (SlotId == 0) {\r
-      Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+      if (Xhc->HcCParams.Data.Csz == 0) {\r
+        Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+      } else {\r
+        Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+      }\r
       ASSERT_EFI_ERROR (Status);\r
     }\r
   } else if ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) == 0) {\r
@@ -1280,7 +1321,11 @@ XhcPollPortStatusChange (
     //\r
     SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);\r
     if (SlotId != 0) {\r
-      Status = XhcDisableSlotCmd (Xhc, SlotId);\r
+      if (Xhc->HcCParams.Data.Csz == 0) {\r
+        Status = XhcDisableSlotCmd (Xhc, SlotId);\r
+      } else {\r
+        Status = XhcDisableSlotCmd64 (Xhc, SlotId);\r
+      }\r
       ASSERT_EFI_ERROR (Status);\r
     }\r
   }\r
@@ -1316,38 +1361,6 @@ XhcEndpointToDci (
   }\r
 }\r
 \r
-/**\r
-  Find out the slot id according to device address assigned by XHCI's Address_Device cmd.\r
-\r
-  @param  Xhc             The XHCI Instance.\r
-  @param  DevAddr         The device address of the target device.\r
-\r
-  @return The slot id used by the device.\r
-\r
-**/\r
-UINT8\r
-XhcDevAddrToSlotId (\r
-  IN  USB_XHCI_INSTANCE  *Xhc,\r
-  IN  UINT8              DevAddr\r
-  )\r
-{\r
-  UINT8  Index;\r
-\r
-  for (Index = 0; Index < 255; Index++) {\r
-    if (Xhc->UsbDevContext[Index + 1].Enabled &&\r
-        (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&\r
-        (Xhc->UsbDevContext[Index + 1].XhciDevAddr == DevAddr)) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (Index == 255) {\r
-    return 0;\r
-  }\r
-\r
-  return Xhc->UsbDevContext[Index + 1].SlotId;\r
-}\r
-\r
 /**\r
   Find out the actual device address according to the requested device address from UsbBus.\r
 \r
@@ -1433,7 +1446,9 @@ XhcSyncEventRing (
   UINTN               Index;\r
   TRB_TEMPLATE        *EvtTrb1;\r
   TRB_TEMPLATE        *EvtTrb2;\r
-  TRB_TEMPLATE        *XhcDequeue;\r
+  UINT64              XhcDequeue;\r
+  UINT32              High;\r
+  UINT32              Low;\r
 \r
   ASSERT (EvtRing != NULL);\r
 \r
@@ -1462,17 +1477,20 @@ XhcSyncEventRing (
   //\r
   // Apply the EventRingDequeue to Xhc\r
   //\r
-  XhcDequeue = (TRB_TEMPLATE *)(UINTN) XhcReadRuntimeReg64 (\r
-                                         Xhc,\r
-                                         XHC_ERDP_OFFSET + (32 * EvtRing->EventInterrupter)\r
-                                         );\r
-\r
-  if (((UINT64)(UINTN)XhcDequeue & (~0x0F)) != ((UINT64)(UINTN)EvtRing->EventRingDequeue & (~0x0F))) {\r
-    XhcWriteRuntimeReg64 (\r
-      Xhc,\r
-      XHC_ERDP_OFFSET + (32 * EvtRing->EventInterrupter),\r
-      (UINT64)(UINTN)EvtRing->EventRingDequeue | BIT3\r
-      );\r
+  // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+  // So divide it to two 32-bytes width register access.\r
+  //\r
+  Low  = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET);\r
+  High = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4);\r
+  XhcDequeue = (UINT64)(LShiftU64((UINT64)High, 32) | Low);\r
+\r
+  if ((XhcDequeue & (~0x0F)) != ((UINT64)(UINTN)EvtRing->EventRingDequeue & (~0x0F))) {\r
+    //\r
+    // Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
+    // So divide it to two 32-bytes width register access.\r
+    //\r
+    XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET, Low | BIT3);\r
+    XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4, High);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1635,8 +1653,8 @@ RingIntTransferDoorBell (
   UINT8                SlotId;\r
   UINT8                Dci;\r
 \r
-  SlotId = XhcDevAddrToSlotId(Xhc, Urb->Ep.DevAddr);\r
-  Dci    = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+  SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+  Dci    = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
   XhcRingDoorBell (Xhc, SlotId, Dci);\r
   return EFI_SUCCESS;\r
 }\r
@@ -1835,100 +1853,587 @@ XhcInitializeDeviceSlot (
 }\r
 \r
 /**\r
-  Disable the specified device slot.\r
+  Assign and initialize the device slot for a new device.\r
 \r
-  @param  Xhc           The XHCI Instance.\r
-  @param  SlotId        The slot id to be disabled.\r
+  @param  Xhc                 The XHCI Instance.\r
+  @param  ParentRouteChart    The route string pointed to the parent device.\r
+  @param  ParentPort          The port at which the device is located.\r
+  @param  RouteChart          The route string pointed to the device.\r
+  @param  DeviceSpeed         The device speed.\r
 \r
-  @retval EFI_SUCCESS   Successfully disable the device slot.\r
+  @retval EFI_SUCCESS   Successfully assign a slot to the device and assign an address to it.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-XhcDisableSlotCmd (\r
-  IN USB_XHCI_INSTANCE         *Xhc,\r
-  IN UINT8                     SlotId\r
+XhcInitializeDeviceSlot64 (\r
+  IN  USB_XHCI_INSTANCE         *Xhc,\r
+  IN  USB_DEV_ROUTE             ParentRouteChart,\r
+  IN  UINT16                    ParentPort,\r
+  IN  USB_DEV_ROUTE             RouteChart,\r
+  IN  UINT8                     DeviceSpeed\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  TRB_TEMPLATE          *EvtTrb;\r
-  CMD_TRB_DISABLE_SLOT  CmdTrbDisSlot;\r
-  UINT8                 Index;\r
-  VOID                  *RingSeg;\r
+  EFI_STATUS                  Status;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  INPUT_CONTEXT_64            *InputContext;\r
+  DEVICE_CONTEXT_64           *OutputContext;\r
+  TRANSFER_RING               *EndpointTransferRing;\r
+  CMD_TRB_ADDRESS_DEVICE      CmdTrbAddr;\r
+  UINT8                       DeviceAddress;\r
+  CMD_TRB_ENABLE_SLOT         CmdTrb;\r
+  UINT8                       SlotId;\r
+  UINT8                       ParentSlotId;\r
+  DEVICE_CONTEXT_64           *ParentDeviceContext;\r
 \r
-  //\r
-  // Disable the device slots occupied by these devices on its downstream ports.\r
-  // Entry 0 is reserved.\r
-  //\r
-  for (Index = 0; Index < 255; Index++) {\r
-    if (!Xhc->UsbDevContext[Index + 1].Enabled ||\r
-        (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||\r
-        (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {\r
-      continue;\r
-    }\r
+  ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));\r
+  CmdTrb.CycleBit = 1;\r
+  CmdTrb.Type     = TRB_TYPE_EN_SLOT;\r
 \r
-    Status = XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);\r
+  Status = XhcCmdTransfer (\r
+              Xhc,\r
+              (TRB_TEMPLATE *) (UINTN) &CmdTrb,\r
+              XHC_GENERIC_TIMEOUT,\r
+              (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+              );\r
+  ASSERT_EFI_ERROR (Status);\r
+  ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);\r
+  DEBUG ((EFI_D_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));\r
+  SlotId = (UINT8)EvtTrb->SlotId;\r
+  ASSERT (SlotId != 0);\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
-      Xhc->UsbDevContext[Index + 1].SlotId = 0;\r
-    }\r
-  }\r
+  ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT));\r
+  Xhc->UsbDevContext[SlotId].Enabled                 = TRUE;\r
+  Xhc->UsbDevContext[SlotId].SlotId                  = SlotId;\r
+  Xhc->UsbDevContext[SlotId].RouteString.Dword       = RouteChart.Dword;\r
+  Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;\r
 \r
   //\r
-  // Construct the disable slot command\r
+  // 4.3.3 Device Slot Initialization\r
+  // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.\r
   //\r
-  DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));\r
+  InputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT_64)));\r
+  ASSERT (InputContext != NULL);\r
+  ASSERT (((UINTN) InputContext & 0x3F) == 0);\r
+  ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+\r
+  Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
 \r
-  ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));\r
-  CmdTrbDisSlot.CycleBit = 1;\r
-  CmdTrbDisSlot.Type     = TRB_TYPE_DIS_SLOT;\r
-  CmdTrbDisSlot.SlotId   = SlotId;\r
-  Status = XhcCmdTransfer (\r
-             Xhc,\r
-             (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,\r
-             XHC_GENERIC_TIMEOUT,\r
-             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
-             );\r
-  ASSERT_EFI_ERROR(Status);\r
   //\r
-  // Free the slot's device context entry\r
+  // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1\r
+  //    flags to '1'. These flags indicate that the Slot Context and the Endpoint 0 Context of the Input\r
+  //    Context are affected by the command.\r
   //\r
-  Xhc->DCBAA[SlotId] = 0;\r
+  InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);\r
 \r
   //\r
-  // Free the slot related data structure\r
+  // 3) Initialize the Input Slot Context data structure\r
   //\r
-  for (Index = 0; Index < 31; Index++) {\r
-    if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
-      RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
-      if (RingSeg != NULL) {\r
-        FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER));\r
-      }\r
-      FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
-    }\r
-  }\r
+  InputContext->Slot.RouteString    = RouteChart.Route.RouteString;\r
+  InputContext->Slot.Speed          = DeviceSpeed + 1;\r
+  InputContext->Slot.ContextEntries = 1;\r
+  InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;\r
 \r
-  for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
-    if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
-      FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);\r
+  if (RouteChart.Route.RouteString) {\r
+    //\r
+    // The device is behind of hub device.\r
+    //\r
+    ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart);\r
+    ASSERT (ParentSlotId != 0);\r
+    //\r
+    //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context\r
+    //\r
+    ParentDeviceContext = (DEVICE_CONTEXT_64 *)Xhc->UsbDevContext[ParentSlotId].OutputContext;\r
+    if ((ParentDeviceContext->Slot.TTPortNum == 0) &&\r
+        (ParentDeviceContext->Slot.TTHubSlotId == 0)) {\r
+      if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {\r
+        //\r
+        // Full/Low device attached to High speed hub port that isolates the high speed signaling\r
+        // environment from Full/Low speed signaling environment for a device\r
+        //\r
+        InputContext->Slot.TTPortNum   = ParentPort;\r
+        InputContext->Slot.TTHubSlotId = ParentSlotId;\r
+      }\r
+    } else {\r
+      //\r
+      // Inherit the TT parameters from parent device.\r
+      //\r
+      InputContext->Slot.TTPortNum   = ParentDeviceContext->Slot.TTPortNum;\r
+      InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId;\r
+      //\r
+      // If the device is a High speed device then down the speed to be the same as its parent Hub\r
+      //\r
+      if (DeviceSpeed == EFI_USB_SPEED_HIGH) {\r
+        InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed;\r
+      }\r
     }\r
   }\r
 \r
-  if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
-    FreePages (Xhc->UsbDevContext[SlotId].InputContext, EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT)));\r
-  }\r
-\r
-  if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {\r
-    FreePages (Xhc->UsbDevContext[SlotId].OutputContext, EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT)));\r
-  }\r
   //\r
-  // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established\r
-  // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to\r
-  // remove urb from XHCI's asynchronous transfer list.\r
+  // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.\r
   //\r
-  Xhc->UsbDevContext[SlotId].Enabled = FALSE;\r
-\r
+  EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING));\r
+  Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;\r
+  CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]);\r
+  //\r
+  // 5) Initialize the Input default control Endpoint 0 Context (6.2.3).\r
+  //\r
+  InputContext->EP[0].EPType = ED_CONTROL_BIDIR;\r
+\r
+  if (DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
+    InputContext->EP[0].MaxPacketSize = 512;\r
+  } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {\r
+    InputContext->EP[0].MaxPacketSize = 64;\r
+  } else {\r
+    InputContext->EP[0].MaxPacketSize = 8;\r
+  }\r
+  //\r
+  // Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints\r
+  // 1KB, and Bulk and Isoch endpoints 3KB.\r
+  //\r
+  InputContext->EP[0].AverageTRBLength = 8;\r
+  InputContext->EP[0].MaxBurstSize     = 0;\r
+  InputContext->EP[0].Interval         = 0;\r
+  InputContext->EP[0].MaxPStreams      = 0;\r
+  InputContext->EP[0].Mult             = 0;\r
+  InputContext->EP[0].CErr             = 3;\r
+\r
+  //\r
+  // Init the DCS(dequeue cycle state) as the transfer ring's CCS\r
+  //\r
+  InputContext->EP[0].PtrLo = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0;\r
+  InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0);\r
+\r
+  //\r
+  // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.\r
+  //\r
+  OutputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT_64)));\r
+  ASSERT (OutputContext != NULL);\r
+  ASSERT (((UINTN) OutputContext & 0x3F) == 0);\r
+  ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));\r
+\r
+  Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;\r
+  //\r
+  // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with\r
+  //    a pointer to the Output Device Context data structure (6.2.1).\r
+  //\r
+  Xhc->DCBAA[SlotId] = (UINT64) (UINTN) OutputContext;\r
+\r
+  //\r
+  // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input\r
+  //    Context data structure described above.\r
+  //\r
+  ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr));\r
+  CmdTrbAddr.PtrLo    = XHC_LOW_32BIT (Xhc->UsbDevContext[SlotId].InputContext);\r
+  CmdTrbAddr.PtrHi    = XHC_HIGH_32BIT (Xhc->UsbDevContext[SlotId].InputContext);\r
+  CmdTrbAddr.CycleBit = 1;\r
+  CmdTrbAddr.Type     = TRB_TYPE_ADDRESS_DEV;\r
+  CmdTrbAddr.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
+  Status = XhcCmdTransfer (\r
+             Xhc,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr,\r
+             XHC_GENERIC_TIMEOUT,\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+             );\r
+  ASSERT (!EFI_ERROR(Status));\r
+\r
+  DeviceAddress = (UINT8) ((DEVICE_CONTEXT_64 *) OutputContext)->Slot.DeviceAddress;\r
+  DEBUG ((EFI_D_INFO, "    Address %d assigned succeefully\n", DeviceAddress));\r
+\r
+  Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Disable the specified device slot.\r
+\r
+  @param  Xhc           The XHCI Instance.\r
+  @param  SlotId        The slot id to be disabled.\r
+\r
+  @retval EFI_SUCCESS   Successfully disable the device slot.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcDisableSlotCmd (\r
+  IN USB_XHCI_INSTANCE         *Xhc,\r
+  IN UINT8                     SlotId\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  TRB_TEMPLATE          *EvtTrb;\r
+  CMD_TRB_DISABLE_SLOT  CmdTrbDisSlot;\r
+  UINT8                 Index;\r
+  VOID                  *RingSeg;\r
+\r
+  //\r
+  // Disable the device slots occupied by these devices on its downstream ports.\r
+  // Entry 0 is reserved.\r
+  //\r
+  for (Index = 0; Index < 255; Index++) {\r
+    if (!Xhc->UsbDevContext[Index + 1].Enabled ||\r
+        (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||\r
+        (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {\r
+      continue;\r
+    }\r
+\r
+    Status = XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
+      Xhc->UsbDevContext[Index + 1].SlotId = 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Construct the disable slot command\r
+  //\r
+  DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));\r
+\r
+  ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));\r
+  CmdTrbDisSlot.CycleBit = 1;\r
+  CmdTrbDisSlot.Type     = TRB_TYPE_DIS_SLOT;\r
+  CmdTrbDisSlot.SlotId   = SlotId;\r
+  Status = XhcCmdTransfer (\r
+             Xhc,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,\r
+             XHC_GENERIC_TIMEOUT,\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+             );\r
+  ASSERT_EFI_ERROR(Status);\r
+  //\r
+  // Free the slot's device context entry\r
+  //\r
+  Xhc->DCBAA[SlotId] = 0;\r
+\r
+  //\r
+  // Free the slot related data structure\r
+  //\r
+  for (Index = 0; Index < 31; Index++) {\r
+    if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
+      RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
+      if (RingSeg != NULL) {\r
+        FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER));\r
+      }\r
+      FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
+    }\r
+  }\r
+\r
+  for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
+    if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
+      FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);\r
+    }\r
+  }\r
+\r
+  if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
+    FreePages (Xhc->UsbDevContext[SlotId].InputContext, EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT)));\r
+  }\r
+\r
+  if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {\r
+    FreePages (Xhc->UsbDevContext[SlotId].OutputContext, EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT)));\r
+  }\r
+  //\r
+  // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established\r
+  // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to\r
+  // remove urb from XHCI's asynchronous transfer list.\r
+  //\r
+  Xhc->UsbDevContext[SlotId].Enabled = FALSE;\r
+  Xhc->UsbDevContext[SlotId].SlotId  = 0;\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Disable the specified device slot.\r
+\r
+  @param  Xhc           The XHCI Instance.\r
+  @param  SlotId        The slot id to be disabled.\r
+\r
+  @retval EFI_SUCCESS   Successfully disable the device slot.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcDisableSlotCmd64 (\r
+  IN USB_XHCI_INSTANCE         *Xhc,\r
+  IN UINT8                     SlotId\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  TRB_TEMPLATE          *EvtTrb;\r
+  CMD_TRB_DISABLE_SLOT  CmdTrbDisSlot;\r
+  UINT8                 Index;\r
+  VOID                  *RingSeg;\r
+\r
+  //\r
+  // Disable the device slots occupied by these devices on its downstream ports.\r
+  // Entry 0 is reserved.\r
+  //\r
+  for (Index = 0; Index < 255; Index++) {\r
+    if (!Xhc->UsbDevContext[Index + 1].Enabled ||\r
+        (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||\r
+        (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) {\r
+      continue;\r
+    }\r
+\r
+    Status = XhcDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
+      Xhc->UsbDevContext[Index + 1].SlotId = 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Construct the disable slot command\r
+  //\r
+  DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId));\r
+\r
+  ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot));\r
+  CmdTrbDisSlot.CycleBit = 1;\r
+  CmdTrbDisSlot.Type     = TRB_TYPE_DIS_SLOT;\r
+  CmdTrbDisSlot.SlotId   = SlotId;\r
+  Status = XhcCmdTransfer (\r
+             Xhc,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,\r
+             XHC_GENERIC_TIMEOUT,\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+             );\r
+  ASSERT_EFI_ERROR(Status);\r
+  //\r
+  // Free the slot's device context entry\r
+  //\r
+  Xhc->DCBAA[SlotId] = 0;\r
+\r
+  //\r
+  // Free the slot related data structure\r
+  //\r
+  for (Index = 0; Index < 31; Index++) {\r
+    if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
+      RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
+      if (RingSeg != NULL) {\r
+        FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER));\r
+      }\r
+      FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
+    }\r
+  }\r
+\r
+  for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
+    if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
+      FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);\r
+    }\r
+  }\r
+\r
+  if (Xhc->UsbDevContext[SlotId].InputContext != NULL) {\r
+    FreePages (Xhc->UsbDevContext[SlotId].InputContext, EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT_64)));\r
+  }\r
+\r
+  if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) {\r
+    FreePages (Xhc->UsbDevContext[SlotId].OutputContext, EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT_64)));\r
+  }\r
+  //\r
+  // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established\r
+  // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to\r
+  // remove urb from XHCI's asynchronous transfer list.\r
+  //\r
+  Xhc->UsbDevContext[SlotId].Enabled = FALSE;\r
+  Xhc->UsbDevContext[SlotId].SlotId  = 0;\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Configure all the device endpoints 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
+\r
+  @retval EFI_SUCCESS   Successfully configure all the device endpoints.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcSetConfigCmd (\r
+  IN USB_XHCI_INSTANCE        *Xhc,\r
+  IN UINT8                    SlotId,\r
+  IN UINT8                    DeviceSpeed,\r
+  IN USB_CONFIG_DESCRIPTOR    *ConfigDesc\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+\r
+  USB_INTERFACE_DESCRIPTOR    *IfDesc;\r
+  USB_ENDPOINT_DESCRIPTOR     *EpDesc;\r
+  UINT8                       Index;\r
+  UINTN                       NumEp;\r
+  UINTN                       EpIndex;\r
+  UINT8                       EpAddr;\r
+  UINT8                       Direction;\r
+  UINT8                       Dci;\r
+  UINT8                       MaxDci;\r
+  UINT32                      PhyAddr;\r
+  UINT8                       Interval;\r
+\r
+  TRANSFER_RING               *EndpointTransferRing;\r
+  CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
+  INPUT_CONTEXT               *InputContext;\r
+  DEVICE_CONTEXT              *OutputContext;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  //\r
+  // 4.6.6 Configure Endpoint\r
+  //\r
+  InputContext  = Xhc->UsbDevContext[SlotId].InputContext;\r
+  OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\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
+  IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1);\r
+  for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {\r
+    while (IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) {\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
+            // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.\r
+            //\r
+            InputContext->EP[Dci-1].Interval = 6;\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  = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+      PhyAddr &= ~(0x0F);\r
+      PhyAddr |= ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\r
+      InputContext->EP[Dci-1].PtrLo = PhyAddr;\r
+      InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+\r
+      EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length);\r
+    }\r
+    IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length);\r
+  }\r
+\r
+  InputContext->InputControlContext.Dword2 |= BIT0;\r
+  InputContext->Slot.ContextEntries         = MaxDci;\r
+  //\r
+  // configure endpoint\r
+  //\r
+  ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));\r
+  CmdTrbCfgEP.PtrLo    = XHC_LOW_32BIT (InputContext);\r
+  CmdTrbCfgEP.PtrHi    = XHC_HIGH_32BIT (InputContext);\r
+  CmdTrbCfgEP.CycleBit = 1;\r
+  CmdTrbCfgEP.Type     = TRB_TYPE_CON_ENDPOINT;\r
+  CmdTrbCfgEP.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
+  DEBUG ((EFI_D_INFO, "Configure Endpoint\n"));\r
+  Status = XhcCmdTransfer (\r
+             Xhc,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
+             XHC_GENERIC_TIMEOUT,\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+             );\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
   return Status;\r
 }\r
 \r
@@ -1945,7 +2450,7 @@ XhcDisableSlotCmd (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-XhcSetConfigCmd (\r
+XhcSetConfigCmd64 (\r
   IN USB_XHCI_INSTANCE        *Xhc,\r
   IN UINT8                    SlotId,\r
   IN UINT8                    DeviceSpeed,\r
@@ -1968,16 +2473,16 @@ XhcSetConfigCmd (
 \r
   TRANSFER_RING               *EndpointTransferRing;\r
   CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
-  INPUT_CONTEXT               *InputContext;\r
-  DEVICE_CONTEXT              *OutputContext;\r
+  INPUT_CONTEXT_64            *InputContext;\r
+  DEVICE_CONTEXT_64           *OutputContext;\r
   EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
   //\r
   // 4.6.6 Configure Endpoint\r
   //\r
   InputContext  = Xhc->UsbDevContext[SlotId].InputContext;\r
   OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
-  ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
-  CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));\r
+  ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+  CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64));\r
 \r
   ASSERT (ConfigDesc != NULL);\r
 \r
@@ -2124,6 +2629,7 @@ XhcSetConfigCmd (
   return Status;\r
 }\r
 \r
+\r
 /**\r
   Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
 \r
@@ -2176,6 +2682,59 @@ XhcEvaluateContext (
   return Status;\r
 }\r
 \r
+/**\r
+  Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
+\r
+  @param  Xhc           The XHCI Instance.\r
+  @param  SlotId        The slot id to be evaluated.\r
+  @param  MaxPacketSize The max packet size supported by the device control transfer.\r
+\r
+  @retval EFI_SUCCESS   Successfully evaluate the device endpoint 0.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcEvaluateContext64 (\r
+  IN USB_XHCI_INSTANCE        *Xhc,\r
+  IN UINT8                    SlotId,\r
+  IN UINT32                   MaxPacketSize\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  CMD_TRB_EVALUATE_CONTEXT    CmdTrbEvalu;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  INPUT_CONTEXT_64            *InputContext;\r
+\r
+  ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
+\r
+  //\r
+  // 4.6.7 Evaluate Context\r
+  //\r
+  InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
+  ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+\r
+  InputContext->InputControlContext.Dword2 |= BIT1;\r
+  InputContext->EP[0].MaxPacketSize         = MaxPacketSize;\r
+\r
+  ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu));\r
+  CmdTrbEvalu.PtrLo    = XHC_LOW_32BIT (InputContext);\r
+  CmdTrbEvalu.PtrHi    = XHC_HIGH_32BIT (InputContext);\r
+  CmdTrbEvalu.CycleBit = 1;\r
+  CmdTrbEvalu.Type     = TRB_TYPE_EVALU_CONTXT;\r
+  CmdTrbEvalu.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
+  DEBUG ((EFI_D_INFO, "Evaluate context\n"));\r
+  Status = XhcCmdTransfer (\r
+             Xhc,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu,\r
+             XHC_GENERIC_TIMEOUT,\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+             );\r
+  ASSERT (!EFI_ERROR(Status));\r
+\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd.\r
 \r
@@ -2242,3 +2801,70 @@ XhcConfigHubContext (
   return Status;\r
 }\r
 \r
+/**\r
+  Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd.\r
+\r
+  @param  Xhc           The XHCI Instance.\r
+  @param  SlotId        The slot id to be configured.\r
+  @param  PortNum       The total number of downstream port supported by the hub.\r
+  @param  TTT           The TT think time of the hub device.\r
+  @param  MTT           The multi-TT of the hub device.\r
+\r
+  @retval EFI_SUCCESS   Successfully configure the hub device's slot context.\r
+\r
+**/\r
+EFI_STATUS\r
+XhcConfigHubContext64 (\r
+  IN USB_XHCI_INSTANCE        *Xhc,\r
+  IN UINT8                    SlotId,\r
+  IN UINT8                    PortNum,\r
+  IN UINT8                    TTT,\r
+  IN UINT8                    MTT\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  INPUT_CONTEXT_64            *InputContext;\r
+  DEVICE_CONTEXT_64           *OutputContext;\r
+  CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
+\r
+  ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
+  InputContext  = Xhc->UsbDevContext[SlotId].InputContext;\r
+  OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
+\r
+  //\r
+  // 4.6.7 Evaluate Context\r
+  //\r
+  ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));\r
+\r
+  InputContext->InputControlContext.Dword2 |= BIT0;\r
+\r
+  //\r
+  // Copy the slot context from OutputContext to Input context\r
+  //\r
+  CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT_64));\r
+  InputContext->Slot.Hub     = 1;\r
+  InputContext->Slot.PortNum = PortNum;\r
+  InputContext->Slot.TTT     = TTT;\r
+  InputContext->Slot.MTT     = MTT;\r
+\r
+  ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP));\r
+  CmdTrbCfgEP.PtrLo    = XHC_LOW_32BIT (InputContext);\r
+  CmdTrbCfgEP.PtrHi    = XHC_HIGH_32BIT (InputContext);\r
+  CmdTrbCfgEP.CycleBit = 1;\r
+  CmdTrbCfgEP.Type     = TRB_TYPE_CON_ENDPOINT;\r
+  CmdTrbCfgEP.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
+  DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n"));\r
+  Status = XhcCmdTransfer (\r
+              Xhc,\r
+              (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
+              XHC_GENERIC_TIMEOUT,\r
+              (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
+              );\r
+  ASSERT (!EFI_ERROR(Status));\r
+\r
+  return Status;\r
+}\r
+\r
+\r