]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
MdeModulePkg: Fixed 'variable set but not used' build warning.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciSched.c
index 370b8ea44178ee361c8aaf7c0269830b76a2cd81..e6c0d1564241ac99a6e7f3d7bf7fdc86ac40a55c 100644 (file)
@@ -2,7 +2,7 @@
 \r
   XHCI transfer scheduling routines.\r
 \r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2012, 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
@@ -15,167 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "Xhci.h"\r
 \r
-/**\r
-  Allocates a buffer of a certain pool type at a specified alignment.\r
-\r
-  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
-  specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0, then a valid\r
-  buffer of 0 size is returned.  If there is not enough memory at the specified alignment remaining\r
-  to satisfy the request, then NULL is returned.\r
-  If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
-\r
-  @param  PoolType              The type of pool to allocate.\r
-  @param  AllocationSize        The number of bytes to allocate.\r
-  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.\r
-                                If Alignment is zero, then byte alignment is used.\r
-\r
-  @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-InternalAllocateAlignedPool (\r
-  IN EFI_MEMORY_TYPE  PoolType,\r
-  IN UINTN            AllocationSize,\r
-  IN UINTN            Alignment\r
-  )\r
-{\r
-  VOID        *RawAddress;\r
-  UINTN       AlignedAddress;\r
-  UINTN       AlignmentMask;\r
-  UINTN       OverAllocationSize;\r
-  UINTN       RealAllocationSize;\r
-  VOID        **FreePointer;\r
-\r
-  //\r
-  // Alignment must be a power of two or zero.\r
-  //\r
-  ASSERT ((Alignment & (Alignment - 1)) == 0);\r
-\r
-  if (Alignment == 0) {\r
-    AlignmentMask = Alignment;\r
-  } else {\r
-    AlignmentMask = Alignment - 1;\r
-  }\r
-  //\r
-  // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.\r
-  //\r
-  OverAllocationSize  = sizeof (RawAddress) + AlignmentMask;\r
-  RealAllocationSize  = AllocationSize + OverAllocationSize;\r
-  //\r
-  // Make sure that AllocationSize plus OverAllocationSize does not overflow.\r
-  //\r
-  ASSERT (RealAllocationSize > AllocationSize);\r
-\r
-  RawAddress = NULL;\r
-  gBS->AllocatePool (PoolType, RealAllocationSize, &RawAddress);\r
-  if (RawAddress == NULL) {\r
-    return NULL;\r
-  }\r
-  AlignedAddress      = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;\r
-  //\r
-  // Save the original memory address just before the aligned address.\r
-  //\r
-  FreePointer         = (VOID **)(AlignedAddress - sizeof (RawAddress));\r
-  *FreePointer        = RawAddress;\r
-\r
-  return (VOID *) AlignedAddress;\r
-}\r
-\r
-/**\r
-  Allocates and zeros a buffer of a certain pool type at a specified alignment.\r
-\r
-  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
-  specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated\r
-  buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there is not\r
-  enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
-  If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
-\r
-  @param  PoolType              The type of pool to allocate.\r
-  @param  AllocationSize        The number of bytes to allocate.\r
-  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.\r
-                                If Alignment is zero, then byte alignment is used.\r
-\r
-  @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-InternalAllocateAlignedZeroPool (\r
-  IN EFI_MEMORY_TYPE  PoolType,\r
-  IN UINTN            AllocationSize,\r
-  IN UINTN            Alignment\r
-  )\r
-{\r
-  VOID    *Memory;\r
-  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
-  if (Memory != NULL) {\r
-    ZeroMem (Memory, AllocationSize);\r
-  }\r
-  return Memory;\r
-}\r
-\r
-/**\r
-  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
-\r
-  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an\r
-  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the\r
-  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there\r
-  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is\r
-  returned.\r
-  If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
-\r
-  @param  AllocationSize        The number of bytes to allocate.\r
-  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.\r
-                                If Alignment is zero, then byte alignment is used.\r
-\r
-  @return A pointer to the allocated buffer or NULL if allocation fails.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-AllocateAlignedZeroPool (\r
-  IN UINTN  AllocationSize,\r
-  IN UINTN  Alignment\r
-  )\r
-{\r
-  return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);\r
-}\r
-\r
-/**\r
-  Frees a buffer that was previously allocated with one of the aligned pool allocation functions\r
-  in the Memory Allocation Library.\r
-\r
-  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the\r
-  aligned pool allocation services of the Memory Allocation Library.\r
-  If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation\r
-  Library, then ASSERT().\r
-\r
-  @param  Buffer                Pointer to the buffer to free.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-FreeAlignedPool (\r
-  IN VOID   *Buffer\r
-  )\r
-{\r
-  VOID        *RawAddress;\r
-  VOID        **FreePointer;\r
-  EFI_STATUS  Status;\r
-\r
-  //\r
-  // Get the pre-saved original address in the over-allocate pool.\r
-  //\r
-  FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));\r
-  RawAddress  = *FreePointer;\r
-\r
-  Status = gBS->FreePool (RawAddress);\r
-  ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
 /**\r
   Create a command transfer TRB to support XHCI command interfaces.\r
 \r
-  @param  Xhc       The XHCI device.\r
+  @param  Xhc       The XHCI Instance.\r
   @param  CmdTrb    The cmd TRB to be executed.\r
 \r
   @return Created URB or NULL.\r
@@ -183,8 +26,8 @@ FreeAlignedPool (
 **/\r
 URB*\r
 XhcCreateCmdTrb (\r
-  IN USB_XHCI_DEV    *Xhc,\r
-  IN TRB             *CmdTrb\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN TRB_TEMPLATE       *CmdTrb\r
   )\r
 {\r
   URB    *Urb;\r
@@ -200,23 +43,19 @@ XhcCreateCmdTrb (
   XhcSyncTrsRing (Xhc, Urb->Ring);\r
   Urb->TrbNum     = 1;\r
   Urb->TrbStart   = Urb->Ring->RingEnqueue;\r
-  CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB));\r
+  CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB_TEMPLATE));\r
   Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0;\r
   Urb->TrbEnd             = Urb->TrbStart;\r
 \r
-  Urb->EvtRing     = &Xhc->CmdEventRing;\r
-  XhcSyncEventRing (Xhc, Urb->EvtRing);\r
-  Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
-\r
   return Urb;\r
 }\r
 \r
 /**\r
   Execute a XHCI cmd TRB pointed by CmdTrb.\r
 \r
-  @param  Xhc                   The XHCI device.\r
+  @param  Xhc                   The XHCI Instance.\r
   @param  CmdTrb                The cmd TRB to be executed.\r
-  @param  TimeOut               Indicates the maximum time, in millisecond, which the\r
+  @param  Timeout               Indicates the maximum time, in millisecond, which the\r
                                 transfer is allowed to complete.\r
   @param  EvtTrb                The event TRB corresponding to the cmd TRB.\r
 \r
@@ -229,10 +68,10 @@ XhcCreateCmdTrb (
 EFI_STATUS\r
 EFIAPI\r
 XhcCmdTransfer (\r
-  IN  USB_XHCI_DEV          *Xhc,\r
-  IN  TRB                   *CmdTrb,\r
-  IN  UINTN                 TimeOut,\r
-  OUT TRB                   **EvtTrb\r
+  IN  USB_XHCI_INSTANCE     *Xhc,\r
+  IN  TRB_TEMPLATE          *CmdTrb,\r
+  IN  UINTN                 Timeout,\r
+  OUT TRB_TEMPLATE          **EvtTrb\r
   )\r
 {\r
   EFI_STATUS      Status;\r
@@ -263,10 +102,8 @@ XhcCmdTransfer (
     goto ON_EXIT;\r
   }\r
 \r
-  ASSERT (Urb->EvtRing == &Xhc->CmdEventRing);\r
-\r
-  Status  = XhcExecTransfer (Xhc, TRUE, Urb, TimeOut);\r
-  *EvtTrb = Urb->EvtTrbStart;\r
+  Status  = XhcExecTransfer (Xhc, TRUE, Urb, Timeout);\r
+  *EvtTrb = Urb->EvtTrb;\r
 \r
   if (Urb->Result == EFI_USB_NOERROR) {\r
     Status = EFI_SUCCESS;\r
@@ -281,8 +118,8 @@ ON_EXIT:
 /**\r
   Create a new URB for a new transaction.\r
 \r
-  @param  Xhc       The XHCI device\r
-  @param  DevAddr   The device address\r
+  @param  Xhc       The XHCI Instance\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
@@ -298,8 +135,8 @@ ON_EXIT:
 **/\r
 URB*\r
 XhcCreateUrb (\r
-  IN USB_XHCI_DEV                       *Xhc,\r
-  IN UINT8                              DevAddr,\r
+  IN USB_XHCI_INSTANCE                  *Xhc,\r
+  IN UINT8                              BusAddr,\r
   IN UINT8                              EpAddr,\r
   IN UINT8                              DevSpeed,\r
   IN UINTN                              MaxPacket,\r
@@ -324,7 +161,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
@@ -338,6 +175,7 @@ XhcCreateUrb (
   Urb->Context  = Context;\r
 \r
   Status = XhcCreateTransferTrb (Xhc, Urb);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   return Urb;\r
 }\r
@@ -345,7 +183,7 @@ XhcCreateUrb (
 /**\r
   Create a transfer TRB.\r
 \r
-  @param  Xhc     The XHCI device\r
+  @param  Xhc     The XHCI Instance\r
   @param  Urb     The urb used to construct the transfer TRB.\r
 \r
   @return Created TRB or NULL\r
@@ -353,11 +191,11 @@ XhcCreateUrb (
 **/\r
 EFI_STATUS\r
 XhcCreateTransferTrb (\r
-  IN USB_XHCI_DEV               *Xhc,\r
+  IN USB_XHCI_INSTANCE          *Xhc,\r
   IN URB                        *Urb\r
   )\r
 {\r
-  DEVICE_CONTEXT                *OutputDevContxt;\r
+  VOID                          *OutputContext;\r
   TRANSFER_RING                 *EPRing;\r
   UINT8                         EPType;\r
   UINT8                         SlotId;\r
@@ -367,12 +205,27 @@ XhcCreateTransferTrb (
   UINTN                         Len;\r
   UINTN                         TrbNum;\r
 \r
-  SlotId    = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
+  SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
+  if (SlotId == 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Urb->Finished  = FALSE;\r
+  Urb->StartDone = FALSE;\r
+  Urb->EndDone   = FALSE;\r
+  Urb->Completed = 0;\r
+  Urb->Result    = EFI_USB_NOERROR;\r
+\r
   Dci       = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
-  EPRing    = (TRANSFER_RING *)(UINTN) UsbDevContext[SlotId].EndpointTransferRing[Dci-1];\r
+  ASSERT (Dci < 32);\r
+  EPRing    = (TRANSFER_RING *)(UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];\r
   Urb->Ring = EPRing;\r
-  OutputDevContxt = (DEVICE_CONTEXT *)(UINTN) Xhc->DCBAA[SlotId];\r
-  EPType    = (UINT8) OutputDevContxt->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
@@ -381,34 +234,31 @@ XhcCreateTransferTrb (
   Urb->TrbStart = EPRing->RingEnqueue;\r
   switch (EPType) {\r
     case ED_CONTROL_BIDIR:\r
-      Urb->EvtRing     = &Xhc->CtrlTrEventRing;\r
-      XhcSyncEventRing (Xhc, Urb->EvtRing);\r
-      Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
       //\r
       // For control transfer, create SETUP_STAGE_TRB first.\r
       //\r
-      TrbStart = EPRing->RingEnqueue;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->bmRequestType = Urb->Request->RequestType;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->bRequest      = Urb->Request->Request;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wValue        = Urb->Request->Value;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wIndex        = Urb->Request->Index;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->wLength       = Urb->Request->Length;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->Lenth         = 8;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IntTarget     = Urb->EvtRing->EventInterrupter;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IOC           = 1;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->IDT           = 1;\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->Type          = TRB_TYPE_SETUP_STAGE;\r
+      TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+      TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType;\r
+      TrbStart->TrbCtrSetup.bRequest      = Urb->Request->Request;\r
+      TrbStart->TrbCtrSetup.wValue        = Urb->Request->Value;\r
+      TrbStart->TrbCtrSetup.wIndex        = Urb->Request->Index;\r
+      TrbStart->TrbCtrSetup.wLength       = Urb->Request->Length;\r
+      TrbStart->TrbCtrSetup.Lenth         = 8;\r
+      TrbStart->TrbCtrSetup.IntTarget     = 0;\r
+      TrbStart->TrbCtrSetup.IOC           = 1;\r
+      TrbStart->TrbCtrSetup.IDT           = 1;\r
+      TrbStart->TrbCtrSetup.Type          = TRB_TYPE_SETUP_STAGE;\r
       if (Urb->Ep.Direction == EfiUsbDataIn) {\r
-        ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 3;\r
+        TrbStart->TrbCtrSetup.TRT = 3;\r
       } else if (Urb->Ep.Direction == EfiUsbDataOut) {\r
-        ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 2;\r
+        TrbStart->TrbCtrSetup.TRT = 2;\r
       } else {\r
-        ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->TRT = 0;\r
+        TrbStart->TrbCtrSetup.TRT = 0;\r
       }\r
       //\r
       // Update the cycle bit\r
       //\r
-      ((TRANSFER_TRB_CONTROL_SETUP *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+      TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0;\r
       Urb->TrbNum++;\r
 \r
       //\r
@@ -416,28 +266,28 @@ XhcCreateTransferTrb (
       //\r
       if (Urb->DataLen > 0) {\r
         XhcSyncTrsRing (Xhc, EPRing);\r
-        TrbStart = EPRing->RingEnqueue;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TRBPtrLo  = XHC_LOW_32BIT(Urb->Data);\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TRBPtrHi  = XHC_HIGH_32BIT(Urb->Data);\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->Lenth     = (UINT32) Urb->DataLen;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->TDSize    = 0;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->ISP       = 1;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IOC       = 1;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->IDT       = 0;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->CH        = 0;\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->Type      = TRB_TYPE_DATA_STAGE;\r
+        TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+        TrbStart->TrbCtrData.TRBPtrLo  = XHC_LOW_32BIT(Urb->Data);\r
+        TrbStart->TrbCtrData.TRBPtrHi  = XHC_HIGH_32BIT(Urb->Data);\r
+        TrbStart->TrbCtrData.Lenth     = (UINT32) Urb->DataLen;\r
+        TrbStart->TrbCtrData.TDSize    = 0;\r
+        TrbStart->TrbCtrData.IntTarget = 0;\r
+        TrbStart->TrbCtrData.ISP       = 1;\r
+        TrbStart->TrbCtrData.IOC       = 1;\r
+        TrbStart->TrbCtrData.IDT       = 0;\r
+        TrbStart->TrbCtrData.CH        = 0;\r
+        TrbStart->TrbCtrData.Type      = TRB_TYPE_DATA_STAGE;\r
         if (Urb->Ep.Direction == EfiUsbDataIn) {\r
-          ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 1;\r
+          TrbStart->TrbCtrData.DIR = 1;\r
         } else if (Urb->Ep.Direction == EfiUsbDataOut) {\r
-          ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 0;\r
+          TrbStart->TrbCtrData.DIR = 0;\r
         } else {\r
-          ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->DIR = 0;\r
+          TrbStart->TrbCtrData.DIR = 0;\r
         }\r
         //\r
         // Update the cycle bit\r
         //\r
-        ((TRANSFER_TRB_CONTROL_DATA *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+        TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0;\r
         Urb->TrbNum++;\r
       }\r
       //\r
@@ -445,60 +295,56 @@ XhcCreateTransferTrb (
       // Get the pointer to next TRB for status stage use\r
       //\r
       XhcSyncTrsRing (Xhc, EPRing);\r
-      TrbStart = EPRing->RingEnqueue;\r
-      ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
-      ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->IOC       = 1;\r
-      ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->CH        = 0;\r
-      ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->Type      = TRB_TYPE_STATUS_STAGE;\r
+      TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+      TrbStart->TrbCtrStatus.IntTarget = 0;\r
+      TrbStart->TrbCtrStatus.IOC       = 1;\r
+      TrbStart->TrbCtrStatus.CH        = 0;\r
+      TrbStart->TrbCtrStatus.Type      = TRB_TYPE_STATUS_STAGE;\r
       if (Urb->Ep.Direction == EfiUsbDataIn) {\r
-        ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 0;\r
+        TrbStart->TrbCtrStatus.DIR = 0;\r
       } else if (Urb->Ep.Direction == EfiUsbDataOut) {\r
-        ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 1;\r
+        TrbStart->TrbCtrStatus.DIR = 1;\r
       } else {\r
-        ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->DIR = 0;\r
+        TrbStart->TrbCtrStatus.DIR = 0;\r
       }\r
       //\r
       // Update the cycle bit\r
       //\r
-      ((TRANSFER_TRB_CONTROL_STATUS *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+      TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0;\r
       //\r
       // Update the enqueue pointer\r
       //\r
       XhcSyncTrsRing (Xhc, EPRing);\r
       Urb->TrbNum++;\r
-      Urb->TrbEnd = TrbStart;\r
+      Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart;\r
 \r
       break;\r
 \r
     case ED_BULK_OUT:\r
     case ED_BULK_IN:\r
-      Urb->EvtRing     = &Xhc->BulkTrEventRing;\r
-      XhcSyncEventRing (Xhc, Urb->EvtRing);\r
-      Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
-\r
       TotalLen = 0;\r
       Len      = 0;\r
       TrbNum   = 0;\r
-      TrbStart = EPRing->RingEnqueue;\r
+      TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
       while (TotalLen < Urb->DataLen) {\r
         if ((TotalLen + 0x10000) >= Urb->DataLen) {\r
           Len = Urb->DataLen - TotalLen;\r
         } else {\r
           Len = 0x10000;\r
         }\r
-        TrbStart = EPRing->RingEnqueue;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrLo  = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrHi  = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->Lenth     = (UINT32) Len;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->TDSize    = 0;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->ISP       = 1;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->IOC       = 1;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->Type      = TRB_TYPE_NORMAL;\r
+        TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+        TrbStart->TrbNormal.TRBPtrLo  = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
+        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 = 0;\r
+        TrbStart->TrbNormal.ISP       = 1;\r
+        TrbStart->TrbNormal.IOC       = 1;\r
+        TrbStart->TrbNormal.Type      = TRB_TYPE_NORMAL;\r
         //\r
         // Update the cycle bit\r
         //\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+        TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;\r
 \r
         XhcSyncTrsRing (Xhc, EPRing);\r
         TrbNum++;\r
@@ -506,45 +352,34 @@ XhcCreateTransferTrb (
       }\r
 \r
       Urb->TrbNum = TrbNum;\r
-      Urb->TrbEnd = TrbStart;\r
+      Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart;\r
       break;\r
 \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
-      XhcSyncEventRing (Xhc, Urb->EvtRing);\r
-      Urb->EvtTrbStart = Urb->EvtRing->EventRingEnqueue;\r
-\r
       TotalLen = 0;\r
       Len      = 0;\r
       TrbNum   = 0;\r
-      TrbStart = EPRing->RingEnqueue;\r
+      TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
       while (TotalLen < Urb->DataLen) {\r
         if ((TotalLen + 0x10000) >= Urb->DataLen) {\r
           Len = Urb->DataLen - TotalLen;\r
         } else {\r
           Len = 0x10000;\r
         }\r
-        TrbStart = EPRing->RingEnqueue;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrLo  = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->TRBPtrHi  = XHC_HIGH_32BIT((UINT8 *) Urb->Data + TotalLen);\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->Lenth     = (UINT32) Len;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->TDSize    = 0;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->IntTarget = Urb->EvtRing->EventInterrupter;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->ISP       = 1;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->IOC       = 1;\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->Type      = TRB_TYPE_NORMAL;\r
+        TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+        TrbStart->TrbNormal.TRBPtrLo  = XHC_LOW_32BIT((UINT8 *) Urb->Data + TotalLen);\r
+        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 = 0;\r
+        TrbStart->TrbNormal.ISP       = 1;\r
+        TrbStart->TrbNormal.IOC       = 1;\r
+        TrbStart->TrbNormal.Type      = TRB_TYPE_NORMAL;\r
         //\r
         // Update the cycle bit\r
         //\r
-        ((TRANSFER_TRB_NORMAL *) TrbStart)->CycleBit = EPRing->RingPCS & BIT0;\r
+        TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;\r
 \r
         XhcSyncTrsRing (Xhc, EPRing);\r
         TrbNum++;\r
@@ -552,7 +387,7 @@ XhcCreateTransferTrb (
       }\r
 \r
       Urb->TrbNum = TrbNum;\r
-      Urb->TrbEnd = TrbStart;\r
+      Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart;\r
       break;\r
 \r
     default:\r
@@ -568,12 +403,12 @@ XhcCreateTransferTrb (
 /**\r
   Initialize the XHCI host controller for schedule.\r
 \r
-  @param  Xhc        The XHCI device to be initialized.\r
+  @param  Xhc        The XHCI Instance to be initialized.\r
 \r
 **/\r
 VOID\r
 XhcInitSched (\r
-  IN USB_XHCI_DEV         *Xhc\r
+  IN USB_XHCI_INSTANCE    *Xhc\r
   )\r
 {\r
   VOID                  *Dcbaa;\r
@@ -599,8 +434,9 @@ XhcInitSched (
   // Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.\r
   //\r
   Entries = (Xhc->MaxSlotsEn + 1) * sizeof(UINT64);\r
-  Dcbaa   = AllocateAlignedZeroPool(Entries, 64);\r
+  Dcbaa   = AllocatePages (EFI_SIZE_TO_PAGES (Entries));\r
   ASSERT (Dcbaa != NULL);\r
+  ZeroMem (Dcbaa, Entries);\r
 \r
   //\r
   // A Scratchpad Buffer is a PAGESIZE block of system memory located on a PAGESIZE boundary.\r
@@ -611,12 +447,15 @@ XhcInitSched (
   Xhc->MaxScratchpadBufs = MaxScratchpadBufs;\r
   ASSERT (MaxScratchpadBufs <= 1023);\r
   if (MaxScratchpadBufs != 0) {\r
-    ScratchBuf      = AllocateAlignedZeroPool(MaxScratchpadBufs * sizeof (UINT64), Xhc->PageSize);\r
+    ScratchBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)), Xhc->PageSize);\r
     ASSERT (ScratchBuf != NULL);\r
+    ZeroMem (ScratchBuf, MaxScratchpadBufs * sizeof (UINT64));\r
     Xhc->ScratchBuf = ScratchBuf;\r
 \r
     for (Index = 0; Index < MaxScratchpadBufs; Index++) {\r
-      ScratchEntryBuf = AllocateAlignedZeroPool(Xhc->PageSize, Xhc->PageSize);\r
+      ScratchEntryBuf = AllocateAlignedPages (EFI_SIZE_TO_PAGES (Xhc->PageSize), Xhc->PageSize);\r
+      ASSERT (ScratchEntryBuf != NULL);\r
+      ZeroMem (ScratchEntryBuf, Xhc->PageSize);\r
       *ScratchBuf++   = (UINT64)(UINTN)ScratchEntryBuf;\r
     }\r
 \r
@@ -631,8 +470,13 @@ XhcInitSched (
   // Program the Device Context Base Address Array Pointer (DCBAAP) register (5.4.6) with\r
   // 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
+  Xhc->DCBAA = (UINT64 *)(UINTN)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
@@ -650,7 +494,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
@@ -667,11 +516,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
@@ -681,7 +527,7 @@ XhcInitSched (
   reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the\r
   Stopped to the Running state.\r
 \r
-  @param  Xhc                   The XHCI device.\r
+  @param  Xhc                   The XHCI Instance.\r
   @param  Urb                   The urb which makes the endpoint halted.\r
 \r
   @retval EFI_SUCCESS           The recovery is successful.\r
@@ -691,21 +537,25 @@ XhcInitSched (
 EFI_STATUS\r
 EFIAPI\r
 XhcRecoverHaltedEndpoint (\r
-  IN  USB_XHCI_DEV        *Xhc,\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  URB                 *Urb\r
   )\r
 {\r
-  EFI_STATUS                 Status;\r
-  EVT_TRB_COMMAND            *EvtTrb;\r
-  CMD_TRB_RESET_ED           CmdTrbResetED;\r
-  CMD_SET_TR_DEQ             CmdSetTRDeq;\r
-  UINT8                      Dci;\r
-  UINT8                      SlotId;\r
-\r
-  Status     = EFI_SUCCESS;\r
-  SlotId     = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
-  Dci        = XhcEndpointToDci(Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction));\r
+  EFI_STATUS                  Status;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  CMD_TRB_RESET_ENDPOINT      CmdTrbResetED;\r
+  CMD_SET_TR_DEQ_POINTER      CmdSetTRDeq;\r
+  UINT8                       Dci;\r
+  UINT8                       SlotId;\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
@@ -718,9 +568,9 @@ XhcRecoverHaltedEndpoint (
   CmdTrbResetED.SlotId   = SlotId;\r
   Status = XhcCmdTransfer (\r
              Xhc,\r
-             (TRB *) (UINTN) &CmdTrbResetED,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED,\r
              XHC_GENERIC_TIMEOUT,\r
-             (TRB **) (UINTN) &EvtTrb\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
              );\r
   ASSERT (!EFI_ERROR(Status));\r
 \r
@@ -736,9 +586,9 @@ XhcRecoverHaltedEndpoint (
   CmdSetTRDeq.SlotId   = SlotId;\r
   Status = XhcCmdTransfer (\r
              Xhc,\r
-             (TRB *) (UINTN) &CmdSetTRDeq,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq,\r
              XHC_GENERIC_TIMEOUT,\r
-             (TRB **) (UINTN) &EvtTrb\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
              );\r
   ASSERT (!EFI_ERROR(Status));\r
 \r
@@ -753,15 +603,13 @@ XhcRecoverHaltedEndpoint (
 /**\r
   Create XHCI event ring.\r
 \r
-  @param  Xhc                 The XHCI device.\r
-  @param  EventInterrupter    The interrupter of event.\r
+  @param  Xhc                 The XHCI Instance.\r
   @param  EventRing           The created event ring.\r
 \r
 **/\r
 VOID\r
 CreateEventRing (\r
-  IN  USB_XHCI_DEV          *Xhc,\r
-  IN  UINT8                 EventInterrupter,\r
+  IN  USB_XHCI_INSTANCE     *Xhc,\r
   OUT EVENT_RING            *EventRing\r
   )\r
 {\r
@@ -770,24 +618,25 @@ CreateEventRing (
 \r
   ASSERT (EventRing != NULL);\r
 \r
-  Buf = AllocateAlignedZeroPool(sizeof (TRB) * EVENT_RING_TRB_NUMBER, 64);\r
+  Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER));\r
   ASSERT (Buf != NULL);\r
   ASSERT (((UINTN) Buf & 0x3F) == 0);\r
+  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 *) EventRing->EventRingSeg0;\r
-  EventRing->EventRingEnqueue = (TRB *) EventRing->EventRingSeg0;\r
+  EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;\r
+  EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0;\r
   //\r
   // Software maintains an Event Ring Consumer Cycle State (CCS) bit, initializing it to '1'\r
   // and toggling it every time the Event Ring Dequeue Pointer wraps back to the beginning of the Event Ring.\r
   //\r
   EventRing->EventRingCCS = 1;\r
 \r
-  Buf = AllocateAlignedZeroPool(sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER, 64);\r
+  Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER));\r
   ASSERT (Buf != NULL);\r
   ASSERT (((UINTN) Buf & 0x3F) == 0);\r
+  ZeroMem (Buf, sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER);\r
 \r
   ERSTBase              = (EVENT_RING_SEG_TABLE_ENTRY *) Buf;\r
   EventRing->ERSTBase   = ERSTBase;\r
@@ -800,64 +649,81 @@ 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 + (32 * EventRing->EventInterrupter),\r
-    (UINT64)(UINTN)ERSTBase\r
+    XHC_ERSTBA_OFFSET,\r
+    XHC_LOW_32BIT((UINT64)(UINTN)ERSTBase)\r
+    );\r
+  XhcWriteRuntimeReg (\r
+    Xhc,\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
   Create XHCI transfer ring.\r
 \r
-  @param  Xhc               The XHCI device.\r
+  @param  Xhc               The XHCI Instance.\r
   @param  TrbNum            The number of TRB in the ring.\r
   @param  TransferRing           The created transfer ring.\r
 \r
 **/\r
 VOID\r
 CreateTransferRing (\r
-  IN  USB_XHCI_DEV          *Xhc,\r
+  IN  USB_XHCI_INSTANCE     *Xhc,\r
   IN  UINTN                 TrbNum,\r
   OUT TRANSFER_RING         *TransferRing\r
   )\r
 {\r
   VOID                  *Buf;\r
-  LNK_TRB               *EndTrb;\r
+  LINK_TRB              *EndTrb;\r
 \r
-  Buf = AllocateAlignedZeroPool(sizeof (TRB) * TrbNum, 64);\r
+  Buf = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TrbNum));\r
   ASSERT (Buf != NULL);\r
   ASSERT (((UINTN) Buf & 0x3F) == 0);\r
+  ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);\r
 \r
   TransferRing->RingSeg0     = Buf;\r
   TransferRing->TrbNumber    = TrbNum;\r
-  TransferRing->RingEnqueue  = (TRB *) TransferRing->RingSeg0;\r
-  TransferRing->RingDequeue  = (TRB *) TransferRing->RingSeg0;\r
+  TransferRing->RingEnqueue  = (TRB_TEMPLATE *) TransferRing->RingSeg0;\r
+  TransferRing->RingDequeue  = (TRB_TEMPLATE *) TransferRing->RingSeg0;\r
   TransferRing->RingPCS      = 1;\r
   //\r
   // 4.9.2 Transfer Ring Management\r
   // To form a ring (or circular queue) a Link TRB may be inserted at the end of a ring to\r
   // point to the first TRB in the ring.\r
   //\r
-  EndTrb        = (LNK_TRB*) ((UINTN)Buf + sizeof (TRB) * (TrbNum - 1));\r
+  EndTrb        = (LINK_TRB *) ((UINTN)Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1));\r
   EndTrb->Type  = TRB_TYPE_LINK;\r
   EndTrb->PtrLo = XHC_LOW_32BIT (Buf);\r
   EndTrb->PtrHi = XHC_HIGH_32BIT (Buf);\r
@@ -874,14 +740,14 @@ CreateTransferRing (
 /**\r
   Free XHCI event ring.\r
 \r
-  @param  Xhc                 The XHCI device.\r
+  @param  Xhc                 The XHCI Instance.\r
   @param  EventRing           The event ring to be freed.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 XhcFreeEventRing (\r
-  IN  USB_XHCI_DEV        *Xhc,\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  EVENT_RING          *EventRing\r
 )\r
 {\r
@@ -889,13 +755,11 @@ XhcFreeEventRing (
   EVENT_RING_SEG_TABLE_ENTRY    *TablePtr;\r
   VOID                          *RingBuf;\r
   EVENT_RING_SEG_TABLE_ENTRY    *EventRingPtr;\r
-  UINTN                         InterrupterTarget;\r
 \r
   if(EventRing->EventRingSeg0 == NULL) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  InterrupterTarget = EventRing->EventInterrupter;\r
   //\r
   // Get the Event Ring Segment Table base address\r
   //\r
@@ -906,94 +770,133 @@ XhcFreeEventRing (
   //\r
   for (Index = 0; Index < ERST_NUMBER; Index++) {\r
     EventRingPtr = TablePtr + Index;\r
-    RingBuf      = (VOID *)(UINTN)(EventRingPtr->PtrLo | ((UINT64)EventRingPtr->PtrHi << 32));\r
+    RingBuf      = (VOID *)(UINTN)(EventRingPtr->PtrLo | LShiftU64 ((UINT64)EventRingPtr->PtrHi, 32));\r
 \r
     if(RingBuf != NULL) {\r
-      FreeAlignedPool (RingBuf);\r
+      FreePages (RingBuf, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER));\r
       ZeroMem (EventRingPtr, sizeof (EVENT_RING_SEG_TABLE_ENTRY));\r
     }\r
   }\r
 \r
-  FreeAlignedPool (TablePtr);\r
+  FreePages (TablePtr, EFI_SIZE_TO_PAGES (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER));\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Free the resouce allocated at initializing schedule.\r
 \r
-  @param  Xhc        The XHCI device.\r
+  @param  Xhc        The XHCI Instance.\r
 \r
 **/\r
 VOID\r
 XhcFreeSched (\r
-  IN USB_XHCI_DEV         *Xhc\r
+  IN USB_XHCI_INSTANCE    *Xhc\r
   )\r
 {\r
   UINT32    Index;\r
+  UINT64    *ScratchBuf;\r
 \r
   if (Xhc->ScratchBuf != NULL) {\r
+    ScratchBuf = Xhc->ScratchBuf;\r
     for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) {\r
-      FreeAlignedPool ((VOID*)(UINTN)*Xhc->ScratchBuf++);\r
+      FreeAlignedPages ((VOID*)(UINTN)*ScratchBuf++, EFI_SIZE_TO_PAGES (Xhc->PageSize));\r
     }\r
+    FreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)));\r
   }\r
 \r
   if (Xhc->DCBAA != NULL) {\r
-    FreeAlignedPool (Xhc->DCBAA);\r
+    FreePages (Xhc->DCBAA, EFI_SIZE_TO_PAGES((Xhc->MaxSlotsEn + 1) * sizeof(UINT64)));\r
     Xhc->DCBAA = NULL;\r
   }\r
 \r
   if (Xhc->CmdRing.RingSeg0 != NULL){\r
-    FreeAlignedPool (Xhc->CmdRing.RingSeg0);\r
+    FreePages (Xhc->CmdRing.RingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER));\r
     Xhc->CmdRing.RingSeg0 = NULL;\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
+\r
+  XhcFreeEventRing (Xhc,&Xhc->EventRing);\r
+}\r
+\r
+/**\r
+  Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.\r
+\r
+  @param Xhc    The XHCI Instance.\r
+  @param Trb    The TRB to be checked.\r
+  @param Urb    The pointer to the matched Urb.\r
+\r
+  @retval TRUE  The Trb is matched with a transaction of the URBs in the async list.\r
+  @retval FALSE The Trb is not matched with any URBs in the async list.\r
+\r
+**/\r
+BOOLEAN\r
+IsAsyncIntTrb (\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
+  IN  TRB_TEMPLATE        *Trb,\r
+  OUT URB                 **Urb\r
+  )\r
+{\r
+  LIST_ENTRY              *Entry;\r
+  LIST_ENTRY              *Next;\r
+  TRB_TEMPLATE            *CheckedTrb;\r
+  URB                     *CheckedUrb;\r
+  UINTN                   Index;\r
+\r
+  EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
+    CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
+    CheckedTrb = CheckedUrb->TrbStart;\r
+    for (Index = 0; Index < CheckedUrb->TrbNum; Index++) {\r
+      if (Trb == CheckedTrb) {\r
+        *Urb = CheckedUrb;\r
+        return TRUE;\r
+      }\r
+      CheckedTrb++;\r
+      if ((UINTN)CheckedTrb >= ((UINTN) CheckedUrb->Ring->RingSeg0 + sizeof (TRB_TEMPLATE) * CheckedUrb->Ring->TrbNumber)) {\r
+        CheckedTrb = (TRB_TEMPLATE*) CheckedUrb->Ring->RingSeg0;\r
+      }\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
 }\r
 \r
 /**\r
-  Check if it is ring TRB.\r
+  Check if the Trb is a transaction of the URB.\r
 \r
-  @param Ring   The transfer ring\r
-  @param Trb    The TRB to check if it's in the transfer ring\r
+  @param Trb    The TRB to be checked\r
+  @param Urb    The transfer ring to be checked.\r
 \r
-  @retval TRUE  It is in the ring\r
-  @retval FALSE It is not in the ring\r
+  @retval TRUE  It is a transaction of the URB.\r
+  @retval FALSE It is not any transaction of the URB.\r
 \r
 **/\r
 BOOLEAN\r
 IsTransferRingTrb (\r
-  IN  TRANSFER_RING       *Ring,\r
-  IN  TRB                 *Trb\r
+  IN  TRB_TEMPLATE        *Trb,\r
+  IN  URB                 *Urb\r
   )\r
 {\r
-  BOOLEAN       Flag;\r
-  TRB           *Trb1;\r
+  TRB_TEMPLATE  *CheckedTrb;\r
   UINTN         Index;\r
 \r
-  Trb1 = Ring->RingSeg0;\r
-  Flag = FALSE;\r
+  CheckedTrb = Urb->Ring->RingSeg0;\r
 \r
-  ASSERT (Ring->TrbNumber == CMD_RING_TRB_NUMBER || Ring->TrbNumber == TR_RING_TRB_NUMBER);\r
+  ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER);\r
 \r
-  for (Index = 0; Index < Ring->TrbNumber; Index++) {\r
-    if (Trb == Trb1) {\r
-      Flag = TRUE;\r
-      break;\r
+  for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) {\r
+    if (Trb == CheckedTrb) {\r
+      return TRUE;\r
     }\r
-    Trb1++;\r
+    CheckedTrb++;\r
   }\r
 \r
-  return Flag;\r
+  return FALSE;\r
 }\r
 \r
 /**\r
   Check the URB's execution result and update the URB's\r
   result accordingly.\r
 \r
-  @param  Xhc             The XHCI device.\r
+  @param  Xhc             The XHCI Instance.\r
   @param  Urb             The URB to check result.\r
 \r
   @return Whether the result of URB transfer is finialized.\r
@@ -1001,24 +904,31 @@ IsTransferRingTrb (
 **/\r
 EFI_STATUS\r
 XhcCheckUrbResult (\r
-  IN  USB_XHCI_DEV        *Xhc,\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  URB                 *Urb\r
   )\r
 {\r
-  BOOLEAN                 StartDone;\r
-  BOOLEAN                 EndDone;\r
   EVT_TRB_TRANSFER        *EvtTrb;\r
-  TRB                     *TRBPtr;\r
+  TRB_TEMPLATE            *TRBPtr;\r
   UINTN                   Index;\r
   UINT8                   TRBType;\r
   EFI_STATUS              Status;\r
+  URB                     *AsyncUrb;\r
+  URB                     *CheckedUrb;\r
+  UINT64                  XhcDequeue;\r
+  UINT32                  High;\r
+  UINT32                  Low;\r
 \r
   ASSERT ((Xhc != NULL) && (Urb != NULL));\r
 \r
-  Urb->Completed  = 0;\r
-  Urb->Result     = EFI_USB_NOERROR;\r
-  Status          = EFI_SUCCESS;\r
-  EvtTrb          = NULL;\r
+  Status   = EFI_SUCCESS;\r
+  AsyncUrb = NULL;\r
+\r
+  if (Urb->Finished) {\r
+    goto EXIT;\r
+  }\r
+\r
+  EvtTrb = NULL;\r
 \r
   if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {\r
     Urb->Result |= EFI_USB_ERR_SYSTEM;\r
@@ -1027,91 +937,126 @@ XhcCheckUrbResult (
   }\r
 \r
   //\r
-  // Restore the EventRingDequeue and poll the transfer event ring from beginning\r
+  // Traverse the event ring to find out all new events from the previous check.\r
   //\r
-  StartDone = FALSE;\r
-  EndDone   = FALSE;\r
-  Urb->EvtRing->EventRingDequeue = Urb->EvtTrbStart;\r
-  for (Index = 0; Index < Urb->EvtRing->TrbNumber; Index++) {\r
-    XhcSyncEventRing (Xhc, Urb->EvtRing);\r
-    Status = XhcCheckNewEvent (Xhc, Urb->EvtRing, ((TRB **)&EvtTrb));\r
+  XhcSyncEventRing (Xhc, &Xhc->EventRing);\r
+  for (Index = 0; Index < Xhc->EventRing.TrbNumber; Index++) {\r
+    Status = XhcCheckNewEvent (Xhc, &Xhc->EventRing, ((TRB_TEMPLATE **)&EvtTrb));\r
     if (Status == EFI_NOT_READY) {\r
-      Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
+      //\r
+      // All new events are handled, return directly.\r
+      //\r
       goto EXIT;\r
     }\r
 \r
-    TRBPtr = (TRB *)(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
+    TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64) EvtTrb->TRBPtrHi, 32));\r
 \r
-    switch (EvtTrb->Completcode) {\r
+    //\r
+    // Update the status of Urb according to the finished event regardless of whether\r
+    // the urb is current checked one or in the XHCI's async transfer list.\r
+    // This way is used to avoid that those completed async transfer events don't get\r
+    // handled in time and are flushed by newer coming events.\r
+    //\r
+    if (IsTransferRingTrb (TRBPtr, Urb)) {\r
+      CheckedUrb = Urb;\r
+    } else if (IsAsyncIntTrb (Xhc, TRBPtr, &AsyncUrb)) {    \r
+      CheckedUrb = AsyncUrb;\r
+    } else {\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! Completcode = %x\n",EvtTrb->Completcode));\r
-        goto EXIT;\r
+        CheckedUrb->Result  |= EFI_USB_ERR_STALL;\r
+        CheckedUrb->Finished = TRUE;\r
+        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));\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! Completcode = %x\n",EvtTrb->Completcode));\r
-        goto EXIT;\r
+        CheckedUrb->Result  |= EFI_USB_ERR_BABBLE;\r
+        CheckedUrb->Finished = TRUE;\r
+        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));\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! Completcode = %x\n",EvtTrb->Completcode));\r
-        goto EXIT;\r
+        CheckedUrb->Result  |= EFI_USB_ERR_BUFFER;\r
+        CheckedUrb->Finished = TRUE;\r
+        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));\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! Completcode = %x\n",EvtTrb->Completcode));\r
-        goto EXIT;\r
+        CheckedUrb->Result  |= EFI_USB_ERR_TIMEOUT;\r
+        CheckedUrb->Finished = TRUE;\r
+        DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));\r
         break;\r
 \r
       case TRB_COMPLETION_SHORT_PACKET:\r
       case TRB_COMPLETION_SUCCESS:\r
-        if (IsTransferRingTrb (Urb->Ring, TRBPtr)) {\r
-          if (EvtTrb->Completcode == TRB_COMPLETION_SHORT_PACKET) {\r
-            DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: short packet happens!\n"));\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
+        if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {\r
+          DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: short packet happens!\n"));\r
         }\r
-        Status = EFI_SUCCESS;\r
+\r
+        TRBType = (UINT8) (TRBPtr->Type);\r
+        if ((TRBType == TRB_TYPE_DATA_STAGE) ||\r
+            (TRBType == TRB_TYPE_NORMAL) ||\r
+            (TRBType == TRB_TYPE_ISOCH)) {\r
+          CheckedUrb->Completed += (CheckedUrb->DataLen - EvtTrb->Lenth);\r
+        }\r
+\r
         break;\r
 \r
       default:\r
-        DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completcode = 0x%x!\n",EvtTrb->Completcode));\r
-        Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
-        Status = EFI_DEVICE_ERROR;\r
-        goto EXIT;\r
+        DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));\r
+        CheckedUrb->Result  |= EFI_USB_ERR_TIMEOUT;\r
+        CheckedUrb->Finished = TRUE;\r
         break;\r
     }\r
 \r
     //\r
     // Only check first and end Trb event address\r
     //\r
-    if (TRBPtr == Urb->TrbStart) {\r
-      StartDone = TRUE;\r
+    if (TRBPtr == CheckedUrb->TrbStart) {\r
+      CheckedUrb->StartDone = TRUE;\r
     }\r
 \r
-    if (TRBPtr == Urb->TrbEnd) {\r
-      EndDone = TRUE;\r
+    if (TRBPtr == CheckedUrb->TrbEnd) {\r
+      CheckedUrb->EndDone = TRUE;\r
     }\r
 \r
-    if (StartDone && EndDone) {\r
-      break;\r
+    if (CheckedUrb->StartDone && CheckedUrb->EndDone) {\r
+      CheckedUrb->Finished = TRUE;\r
+      CheckedUrb->EvtTrb   = (TRB_TEMPLATE *)EvtTrb;\r
     }\r
   }\r
 \r
 EXIT:\r
+\r
+  //\r
+  // Advance event ring to last available entry\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)Xhc->EventRing.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, XHC_LOW_32BIT (Xhc->EventRing.EventRingDequeue) | BIT3);\r
+    XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4, XHC_HIGH_32BIT (Xhc->EventRing.EventRingDequeue));\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -1119,10 +1064,10 @@ EXIT:
 /**\r
   Execute the transfer by polling the URB. This is a synchronous operation.\r
 \r
-  @param  Xhc               The XHCI device.\r
+  @param  Xhc               The XHCI Instance.\r
   @param  CmdTransfer       The executed URB is for cmd transfer or not.\r
   @param  Urb               The URB to execute.\r
-  @param  TimeOut           The time to wait before abort, in millisecond.\r
+  @param  Timeout           The time to wait before abort, in millisecond.\r
 \r
   @return EFI_DEVICE_ERROR  The transfer failed due to transfer error.\r
   @return EFI_TIMEOUT       The transfer failed due to time out.\r
@@ -1131,10 +1076,10 @@ EXIT:
 **/\r
 EFI_STATUS\r
 XhcExecTransfer (\r
-  IN  USB_XHCI_DEV        *Xhc,\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  BOOLEAN             CmdTransfer,\r
   IN  URB                 *Urb,\r
-  IN  UINTN               TimeOut\r
+  IN  UINTN               Timeout\r
   )\r
 {\r
   EFI_STATUS              Status;\r
@@ -1147,13 +1092,17 @@ XhcExecTransfer (
     SlotId = 0;\r
     Dci    = 0;\r
   } else {\r
-    SlotId = XhcDevAddrToSlotId(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
-  Loop   = (TimeOut * XHC_1_MILLISECOND / XHC_SYNC_POLL_INTERVAL) + 1;\r
-  if (TimeOut == 0) {\r
+  Loop   = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
+  if (Timeout == 0) {\r
     Loop = 0xFFFFFFFF;\r
   }\r
 \r
@@ -1161,10 +1110,14 @@ XhcExecTransfer (
 \r
   for (Index = 0; Index < Loop; Index++) {\r
     Status = XhcCheckUrbResult (Xhc, Urb);\r
-    if ((Status != EFI_NOT_READY)) {\r
+    if (Urb->Finished) {\r
       break;\r
     }\r
-    gBS->Stall (XHC_SYNC_POLL_INTERVAL);\r
+    gBS->Stall (XHC_POLL_DELAY);\r
+  }\r
+\r
+  if (Index == Loop) {\r
+    Urb->Result = EFI_USB_ERR_TIMEOUT;\r
   }\r
 \r
   return Status;\r
@@ -1174,8 +1127,8 @@ XhcExecTransfer (
   Delete a single asynchronous interrupt transfer for\r
   the device and endpoint.\r
 \r
-  @param  Xhc                   The XHCI device.\r
-  @param  DevAddr               The address of the target device.\r
+  @param  Xhc                   The XHCI Instance.\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
@@ -1184,8 +1137,8 @@ XhcExecTransfer (
 **/\r
 EFI_STATUS\r
 XhciDelAsyncIntTransfer (\r
-  IN  USB_XHCI_DEV        *Xhc,\r
-  IN  UINT8               DevAddr,\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
+  IN  UINT8               BusAddr,\r
   IN  UINT8               EpNum\r
   )\r
 {\r
@@ -1193,17 +1146,15 @@ XhciDelAsyncIntTransfer (
   LIST_ENTRY              *Next;\r
   URB                     *Urb;\r
   EFI_USB_DATA_DIRECTION  Direction;\r
-  BOOLEAN                 Found;\r
 \r
   Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;\r
   EpNum    &= 0x0F;\r
 \r
-  Found = FALSE;\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
@@ -1219,12 +1170,12 @@ XhciDelAsyncIntTransfer (
 /**\r
   Remove all the asynchronous interrutp transfers.\r
 \r
-  @param  Xhc    The XHCI device.\r
+  @param  Xhc    The XHCI Instance.\r
 \r
 **/\r
 VOID\r
 XhciDelAllAsyncIntTransfers (\r
-  IN USB_XHCI_DEV         *Xhc\r
+  IN USB_XHCI_INSTANCE    *Xhc\r
   )\r
 {\r
   LIST_ENTRY              *Entry;\r
@@ -1242,13 +1193,13 @@ XhciDelAllAsyncIntTransfers (
 /**\r
   Update the queue head for next round of asynchronous transfer\r
 \r
-  @param  Xhc     The XHCI device.\r
+  @param  Xhc     The XHCI Instance.\r
   @param  Urb     The URB to update\r
 \r
 **/\r
 VOID\r
 XhcUpdateAsyncRequest (\r
-  IN USB_XHCI_DEV*            Xhc,\r
+  IN USB_XHCI_INSTANCE        *Xhc,\r
   IN URB                      *Urb\r
   )\r
 {\r
@@ -1256,9 +1207,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
@@ -1267,7 +1222,7 @@ XhcUpdateAsyncRequest (
   Interrupt transfer periodic check handler.\r
 \r
   @param  Event                 Interrupt event.\r
-  @param  Context               Pointer to USB_XHCI_DEV.\r
+  @param  Context               Pointer to USB_XHCI_INSTANCE.\r
 \r
 **/\r
 VOID\r
@@ -1277,18 +1232,17 @@ XhcMonitorAsyncRequests (
   IN VOID                 *Context\r
   )\r
 {\r
-  USB_XHCI_DEV            *Xhc;\r
+  USB_XHCI_INSTANCE       *Xhc;\r
   LIST_ENTRY              *Entry;\r
   LIST_ENTRY              *Next;\r
   UINT8                   *ProcBuf;\r
   URB                     *Urb;\r
   UINT8                   SlotId;\r
-  EFI_STATUS              Status;\r
   EFI_TPL                 OldTpl;\r
 \r
   OldTpl = gBS->RaiseTPL (XHC_TPL);\r
 \r
-  Xhc    = (USB_XHCI_DEV*) Context;\r
+  Xhc    = (USB_XHCI_INSTANCE*) Context;\r
 \r
   EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
     Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
@@ -1296,7 +1250,7 @@ XhcMonitorAsyncRequests (
     //\r
     // Make sure that the device is available before every check.\r
     //\r
-    SlotId = XhcDevAddrToSlotId(Urb->Ep.DevAddr);\r
+    SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
     if (SlotId == 0) {\r
       continue;\r
     }\r
@@ -1305,9 +1259,9 @@ XhcMonitorAsyncRequests (
     // Check the result of URB execution. If it is still\r
     // active, check the next one.\r
     //\r
-    Status = XhcCheckUrbResult (Xhc, Urb);\r
+    XhcCheckUrbResult (Xhc, Urb);\r
 \r
-    if (Status == EFI_NOT_READY) {\r
+    if (!Urb->Finished) {\r
       continue;\r
     }\r
 \r
@@ -1320,7 +1274,7 @@ XhcMonitorAsyncRequests (
     if (Urb->Result == EFI_USB_NOERROR) {\r
       ASSERT (Urb->Completed <= Urb->DataLen);\r
 \r
-      ProcBuf = AllocatePool (Urb->Completed);\r
+      ProcBuf = AllocateZeroPool (Urb->Completed);\r
 \r
       if (ProcBuf == NULL) {\r
         XhcUpdateAsyncRequest (Xhc, Urb);\r
@@ -1330,8 +1284,6 @@ XhcMonitorAsyncRequests (
       CopyMem (ProcBuf, Urb->Data, Urb->Completed);\r
     }\r
 \r
-    XhcUpdateAsyncRequest (Xhc, Urb);\r
-\r
     //\r
     // Leave error recovery to its related device driver. A\r
     // common case of the error recovery is to re-submit the\r
@@ -1355,6 +1307,8 @@ XhcMonitorAsyncRequests (
     if (ProcBuf != NULL) {\r
       gBS->FreePool (ProcBuf);\r
     }\r
+\r
+    XhcUpdateAsyncRequest (Xhc, Urb);\r
   }\r
   gBS->RestoreTPL (OldTpl);\r
 }\r
@@ -1362,7 +1316,7 @@ XhcMonitorAsyncRequests (
 /**\r
   Monitor the port status change. Enable/Disable device slot if there is a device attached/detached.\r
 \r
-  @param  Xhc                   The XHCI device.\r
+  @param  Xhc                   The XHCI Instance.\r
   @param  ParentRouteChart      The route string pointed to the parent device if it exists.\r
   @param  Port                  The port to be polled.\r
   @param  PortState             The port state.\r
@@ -1374,7 +1328,7 @@ XhcMonitorAsyncRequests (
 EFI_STATUS\r
 EFIAPI\r
 XhcPollPortStatusChange (\r
-  IN  USB_XHCI_DEV*         Xhc,\r
+  IN  USB_XHCI_INSTANCE     *Xhc,\r
   IN  USB_DEV_ROUTE         ParentRouteChart,\r
   IN  UINT8                 Port,\r
   IN  EFI_USB_PORT_STATUS   *PortState\r
@@ -1388,17 +1342,17 @@ XhcPollPortStatusChange (
   Status = EFI_SUCCESS;\r
 \r
   if (ParentRouteChart.Dword == 0) {\r
-    RouteChart.Field.RouteString = 0;\r
-    RouteChart.Field.RootPortNum = Port + 1;\r
-    RouteChart.Field.TierNum     = 1;\r
+    RouteChart.Route.RouteString = 0;\r
+    RouteChart.Route.RootPortNum = Port + 1;\r
+    RouteChart.Route.TierNum     = 1;\r
   } else {\r
     if(Port < 14) {\r
-      RouteChart.Field.RouteString = ParentRouteChart.Field.RouteString | (Port << (4 * (ParentRouteChart.Field.TierNum - 1)));\r
+      RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1)));\r
     } else {\r
-      RouteChart.Field.RouteString = ParentRouteChart.Field.RouteString | (15 << (4 * (ParentRouteChart.Field.TierNum - 1)));\r
+      RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1)));\r
     }\r
-    RouteChart.Field.RootPortNum   = ParentRouteChart.Field.RootPortNum;\r
-    RouteChart.Field.TierNum       = ParentRouteChart.Field.TierNum + 1;\r
+    RouteChart.Route.RootPortNum   = ParentRouteChart.Route.RootPortNum;\r
+    RouteChart.Route.TierNum       = ParentRouteChart.Route.TierNum + 1;\r
   }\r
 \r
   if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&\r
@@ -1417,18 +1371,26 @@ XhcPollPortStatusChange (
     //\r
     // Execute Enable_Slot cmd for attached device, initialize device context and assign device address.\r
     //\r
-    SlotId = XhcRouteStringToSlotId (RouteChart);\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
     //\r
     // Device is detached. Disable the allocated device slot and release resource.\r
     //\r
-    SlotId = XhcRouteStringToSlotId (RouteChart);\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
@@ -1464,40 +1426,11 @@ XhcEndpointToDci (
   }\r
 }\r
 \r
-/**\r
-  Find out the slot id according to device address assigned by XHCI's Address_Device cmd.\r
-\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  UINT8       DevAddr\r
-  )\r
-{\r
-  UINT8  Index;\r
-\r
-  for (Index = 0; Index < 255; Index++) {\r
-    if (UsbDevContext[Index + 1].Enabled &&\r
-        (UsbDevContext[Index + 1].SlotId != 0) &&\r
-        (UsbDevContext[Index + 1].XhciDevAddr == DevAddr)) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (Index == 255) {\r
-    return 0;\r
-  }\r
-\r
-  return UsbDevContext[Index + 1].SlotId;\r
-}\r
-\r
 /**\r
   Find out the actual device address according to the requested device address from UsbBus.\r
 \r
-  @param  BusDevAddr       The requested device address by UsbBus upper driver.\r
+  @param  Xhc             The XHCI Instance.\r
+  @param  BusDevAddr      The requested device address by UsbBus upper driver.\r
 \r
   @return The actual device address assigned to the device.\r
 \r
@@ -1505,15 +1438,16 @@ XhcDevAddrToSlotId (
 UINT8\r
 EFIAPI\r
 XhcBusDevAddrToSlotId (\r
-  IN  UINT8       BusDevAddr\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  UINT8              BusDevAddr\r
   )\r
 {\r
   UINT8  Index;\r
 \r
   for (Index = 0; Index < 255; Index++) {\r
-    if (UsbDevContext[Index + 1].Enabled &&\r
-        (UsbDevContext[Index + 1].SlotId != 0) &&\r
-        (UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) {\r
+    if (Xhc->UsbDevContext[Index + 1].Enabled &&\r
+        (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&\r
+        (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) {\r
       break;\r
     }\r
   }\r
@@ -1522,13 +1456,14 @@ XhcBusDevAddrToSlotId (
     return 0;\r
   }\r
 \r
-  return UsbDevContext[Index + 1].SlotId;\r
+  return Xhc->UsbDevContext[Index + 1].SlotId;\r
 }\r
 \r
 /**\r
   Find out the slot id according to the device's route string.\r
 \r
-  @param  RouteString      The route string described the device location.\r
+  @param  Xhc             The XHCI Instance.\r
+  @param  RouteString     The route string described the device location.\r
 \r
   @return The slot id used by the device.\r
 \r
@@ -1536,15 +1471,16 @@ XhcBusDevAddrToSlotId (
 UINT8\r
 EFIAPI\r
 XhcRouteStringToSlotId (\r
-  IN  USB_DEV_ROUTE     RouteString\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  USB_DEV_ROUTE      RouteString\r
   )\r
 {\r
   UINT8  Index;\r
 \r
   for (Index = 0; Index < 255; Index++) {\r
-    if (UsbDevContext[Index + 1].Enabled &&\r
-        (UsbDevContext[Index + 1].SlotId != 0) &&\r
-        (UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) {\r
+    if (Xhc->UsbDevContext[Index + 1].Enabled &&\r
+        (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&\r
+        (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) {\r
       break;\r
     }\r
   }\r
@@ -1553,13 +1489,13 @@ XhcRouteStringToSlotId (
     return 0;\r
   }\r
 \r
-  return UsbDevContext[Index + 1].SlotId;\r
+  return Xhc->UsbDevContext[Index + 1].SlotId;\r
 }\r
 \r
 /**\r
   Synchronize the specified event ring to update the enqueue and dequeue pointer.\r
 \r
-  @param  Xhc         The XHCI device.\r
+  @param  Xhc         The XHCI Instance.\r
   @param  EvtRing     The event ring to sync.\r
 \r
   @retval EFI_SUCCESS The event ring is synchronized successfully.\r
@@ -1568,14 +1504,12 @@ XhcRouteStringToSlotId (
 EFI_STATUS\r
 EFIAPI\r
 XhcSyncEventRing (\r
-  IN USB_XHCI_DEV         *Xhc,\r
+  IN USB_XHCI_INSTANCE    *Xhc,\r
   IN EVENT_RING           *EvtRing\r
   )\r
 {\r
   UINTN               Index;\r
-  TRB                 *EvtTrb1;\r
-  TRB                 *EvtTrb2;\r
-  TRB                 *XhcDequeue;\r
+  TRB_TEMPLATE        *EvtTrb1;\r
 \r
   ASSERT (EvtRing != NULL);\r
 \r
@@ -1583,38 +1517,25 @@ XhcSyncEventRing (
   // Calculate the EventRingEnqueue and EventRingCCS.\r
   // Note: only support single Segment\r
   //\r
-  EvtTrb1 = EvtRing->EventRingSeg0;\r
-  EvtTrb2 = EvtRing->EventRingSeg0;\r
+  EvtTrb1 = EvtRing->EventRingDequeue;\r
 \r
   for (Index = 0; Index < EvtRing->TrbNumber; Index++) {\r
-    if (EvtTrb1->CycleBit != EvtTrb2->CycleBit) {\r
+    if (EvtTrb1->CycleBit != EvtRing->EventRingCCS) {\r
       break;\r
     }\r
+\r
     EvtTrb1++;\r
+\r
+    if ((UINTN)EvtTrb1 >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
+      EvtTrb1 = EvtRing->EventRingSeg0;\r
+      EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1;\r
+    }\r
   }\r
 \r
   if (Index < EvtRing->TrbNumber) {\r
     EvtRing->EventRingEnqueue = EvtTrb1;\r
-    EvtRing->EventRingCCS     = (EvtTrb2->CycleBit) ? 1 : 0;\r
   } else {\r
-    EvtRing->EventRingEnqueue = EvtTrb2;\r
-    EvtRing->EventRingCCS     = (EvtTrb2->CycleBit) ? 0 : 1;\r
-  }\r
-\r
-  //\r
-  // Apply the EventRingDequeue to Xhc\r
-  //\r
-  XhcDequeue = (TRB *)(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
+    ASSERT (FALSE);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1623,7 +1544,7 @@ XhcSyncEventRing (
 /**\r
   Synchronize the specified transfer ring to update the enqueue and dequeue pointer.\r
 \r
-  @param  Xhc         The XHCI device.\r
+  @param  Xhc         The XHCI Instance.\r
   @param  TrsRing     The transfer ring to sync.\r
 \r
   @retval EFI_SUCCESS The transfer ring is synchronized successfully.\r
@@ -1632,12 +1553,12 @@ XhcSyncEventRing (
 EFI_STATUS\r
 EFIAPI\r
 XhcSyncTrsRing (\r
-  IN USB_XHCI_DEV         *Xhc,\r
+  IN USB_XHCI_INSTANCE    *Xhc,\r
   IN TRANSFER_RING        *TrsRing\r
   )\r
 {\r
   UINTN               Index;\r
-  TRB                 *TrsTrb;\r
+  TRB_TEMPLATE        *TrsTrb;\r
 \r
   ASSERT (TrsRing != NULL);\r
   //\r
@@ -1652,16 +1573,16 @@ XhcSyncTrsRing (
     }\r
     TrsTrb++;\r
     if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) {\r
-      ASSERT (((LNK_TRB*)TrsTrb)->TC != 0);\r
+      ASSERT (((LINK_TRB*)TrsTrb)->TC != 0);\r
       //\r
       // set cycle bit in Link TRB as normal\r
       //\r
-      ((LNK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;\r
+      ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;\r
       //\r
       // Toggle PCS maintained by software\r
       //\r
       TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1;\r
-      TrsTrb           = (TRB*)(UINTN)((TrsTrb->Dword1 | ((UINT64)TrsTrb->Dword2 << 32)) & ~0x0F);\r
+      TrsTrb           = (TRB_TEMPLATE *)(UINTN)((TrsTrb->Parameter1 | LShiftU64 ((UINT64)TrsTrb->Parameter2, 32)) & ~0x0F);\r
     }\r
   }\r
 \r
@@ -1674,12 +1595,12 @@ XhcSyncTrsRing (
   //\r
   // Clear the Trb context for enqueue, but reserve the PCS bit\r
   //\r
-  TrsTrb->Dword1  = 0;\r
-  TrsTrb->Dword2  = 0;\r
-  TrsTrb->Dword3  = 0;\r
-  TrsTrb->RsvdZ1  = 0;\r
-  TrsTrb->Type    = 0;\r
-  TrsTrb->RsvdZ2  = 0;\r
+  TrsTrb->Parameter1 = 0;\r
+  TrsTrb->Parameter2 = 0;\r
+  TrsTrb->Status     = 0;\r
+  TrsTrb->RsvdZ1     = 0;\r
+  TrsTrb->Type       = 0;\r
+  TrsTrb->Control    = 0;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1687,7 +1608,7 @@ XhcSyncTrsRing (
 /**\r
   Check if there is a new generated event.\r
 \r
-  @param  Xhc           The XHCI device.\r
+  @param  Xhc           The XHCI Instance.\r
   @param  EvtRing       The event ring to check.\r
   @param  NewEvtTrb     The new event TRB found.\r
 \r
@@ -1698,44 +1619,34 @@ XhcSyncTrsRing (
 EFI_STATUS\r
 EFIAPI\r
 XhcCheckNewEvent (\r
-  IN  USB_XHCI_DEV            *Xhc,\r
+  IN  USB_XHCI_INSTANCE       *Xhc,\r
   IN  EVENT_RING              *EvtRing,\r
-  OUT TRB                     **NewEvtTrb\r
+  OUT TRB_TEMPLATE            **NewEvtTrb\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  TRB         *EvtTrb;\r
-\r
   ASSERT (EvtRing != NULL);\r
 \r
-  EvtTrb     = EvtRing->EventRingDequeue;\r
   *NewEvtTrb = EvtRing->EventRingDequeue;\r
 \r
   if (EvtRing->EventRingDequeue == EvtRing->EventRingEnqueue) {\r
     return EFI_NOT_READY;\r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
-\r
-  if (((EvtTrb->Dword3 >> 24) & 0xFF) != TRB_COMPLETION_SUCCESS) {\r
-    Status = EFI_DEVICE_ERROR;\r
-  }\r
-\r
   EvtRing->EventRingDequeue++;\r
   //\r
   // If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring.\r
   //\r
-  if ((UINTN)EvtRing->EventRingDequeue >=  ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB) * EvtRing->TrbNumber)) {\r
+  if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
     EvtRing->EventRingDequeue = EvtRing->EventRingSeg0;\r
   }\r
 \r
-  return Status;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Ring the door bell to notify XHCI there is a transaction to be executed.\r
 \r
-  @param  Xhc           The XHCI device.\r
+  @param  Xhc           The XHCI Instance.\r
   @param  SlotId        The slot id of the target device.\r
   @param  Dci           The device context index of the target slot or endpoint.\r
 \r
@@ -1745,7 +1656,7 @@ XhcCheckNewEvent (
 EFI_STATUS\r
 EFIAPI\r
 XhcRingDoorBell (\r
-  IN USB_XHCI_DEV         *Xhc,\r
+  IN USB_XHCI_INSTANCE    *Xhc,\r
   IN UINT8                SlotId,\r
   IN UINT8                Dci\r
   )\r
@@ -1762,7 +1673,7 @@ XhcRingDoorBell (
 /**\r
   Ring the door bell to notify XHCI there is a transaction to be executed through URB.\r
 \r
-  @param  Xhc           The XHCI device.\r
+  @param  Xhc           The XHCI Instance.\r
   @param  Urb           The URB to be rung.\r
 \r
   @retval EFI_SUCCESS   Successfully ring the door bell.\r
@@ -1770,15 +1681,15 @@ XhcRingDoorBell (
 **/\r
 EFI_STATUS\r
 RingIntTransferDoorBell (\r
-  IN  USB_XHCI_DEV        *Xhc,\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  URB                 *Urb\r
   )\r
 {\r
   UINT8                SlotId;\r
   UINT8                Dci;\r
 \r
-  SlotId = XhcDevAddrToSlotId(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
@@ -1786,7 +1697,7 @@ RingIntTransferDoorBell (
 /**\r
   Assign and initialize the device slot for a new device.\r
 \r
-  @param  Xhc                 The XHCI device.\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
@@ -1798,34 +1709,34 @@ RingIntTransferDoorBell (
 EFI_STATUS\r
 EFIAPI\r
 XhcInitializeDeviceSlot (\r
-  IN  USB_XHCI_DEV              *Xhc,\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
-  EVT_TRB_COMMAND       *EvtTrb;\r
-  INPUT_CONTEXT         *InputContext;\r
-  DEVICE_CONTEXT        *OutputDevContxt;\r
-  TRANSFER_RING         *EndpointTransferRing;\r
-  CMD_TRB_ADDR_DEV      CmdTrbAddr;\r
-  UINT8                 DeviceAddress;\r
-  CMD_TRB_EN_SLOT       CmdTrb;\r
-  UINT8                 SlotId;\r
-  UINT8                 ParentSlotId;\r
-  DEVICE_CONTEXT        *ParentDeviceContext;\r
-\r
-  ZeroMem (&CmdTrb, sizeof (CMD_TRB_EN_SLOT));\r
+  EFI_STATUS                  Status;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  INPUT_CONTEXT               *InputContext;\r
+  DEVICE_CONTEXT              *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              *ParentDeviceContext;\r
+\r
+  ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));\r
   CmdTrb.CycleBit = 1;\r
   CmdTrb.Type     = TRB_TYPE_EN_SLOT;\r
 \r
   Status = XhcCmdTransfer (\r
               Xhc,\r
-              (TRB *) (UINTN) &CmdTrb,\r
+              (TRB_TEMPLATE *) (UINTN) &CmdTrb,\r
               XHC_GENERIC_TIMEOUT,\r
-              (TRB **) (UINTN) &EvtTrb\r
+              (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
               );\r
   ASSERT_EFI_ERROR (Status);\r
   ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);\r
@@ -1833,21 +1744,22 @@ XhcInitializeDeviceSlot (
   SlotId = (UINT8)EvtTrb->SlotId;\r
   ASSERT (SlotId != 0);\r
 \r
-  ZeroMem (&UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT));\r
-  UsbDevContext[SlotId].Enabled                 = TRUE;\r
-  UsbDevContext[SlotId].SlotId                  = SlotId;\r
-  UsbDevContext[SlotId].RouteString.Dword       = RouteChart.Dword;\r
-  UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;\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
   // 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
-  InputContext = AllocateAlignedZeroPool(sizeof (INPUT_CONTEXT), 64);\r
+  InputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (INPUT_CONTEXT)));\r
   ASSERT (InputContext != NULL);\r
   ASSERT (((UINTN) InputContext & 0x3F) == 0);\r
+  ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
 \r
-  UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
+  Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
 \r
   //\r
   // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1\r
@@ -1859,21 +1771,21 @@ XhcInitializeDeviceSlot (
   //\r
   // 3) Initialize the Input Slot Context data structure\r
   //\r
-  InputContext->Slot.RouteStr       = RouteChart.Field.RouteString;\r
+  InputContext->Slot.RouteString    = RouteChart.Route.RouteString;\r
   InputContext->Slot.Speed          = DeviceSpeed + 1;\r
   InputContext->Slot.ContextEntries = 1;\r
-  InputContext->Slot.RootHubPortNum = RouteChart.Field.RootPortNum;\r
+  InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;\r
 \r
-  if (RouteChart.Field.RouteString) {\r
+  if (RouteChart.Route.RouteString) {\r
     //\r
     // The device is behind of hub device.\r
     //\r
-    ParentSlotId = XhcRouteStringToSlotId(ParentRouteChart);\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 *)UsbDevContext[ParentSlotId].OutputDevContxt;\r
+    ParentDeviceContext = (DEVICE_CONTEXT *)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
@@ -1902,9 +1814,9 @@ XhcInitializeDeviceSlot (
   //\r
   // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.\r
   //\r
-  EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64);\r
-  UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;\r
-  CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[0]);\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
@@ -1931,92 +1843,386 @@ XhcInitializeDeviceSlot (
   //\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)UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0) | BIT0;\r
-  InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0);\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
-  OutputDevContxt = AllocateAlignedZeroPool(sizeof (DEVICE_CONTEXT), 64);\r
-  ASSERT (OutputDevContxt != NULL);\r
-  ASSERT (((UINTN) OutputDevContxt & 0x3F) == 0);\r
+  OutputContext = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (DEVICE_CONTEXT)));\r
+  ASSERT (OutputContext != NULL);\r
+  ASSERT (((UINTN) OutputContext & 0x3F) == 0);\r
+  ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));\r
 \r
-  UsbDevContext[SlotId].OutputDevContxt = OutputDevContxt;\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) OutputDevContxt;\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 (UsbDevContext[SlotId].InputContext);\r
-  CmdTrbAddr.PtrHi    = XHC_HIGH_32BIT (UsbDevContext[SlotId].InputContext);\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   = UsbDevContext[SlotId].SlotId;\r
+  CmdTrbAddr.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
   Status = XhcCmdTransfer (\r
              Xhc,\r
-             (TRB *) (UINTN) &CmdTrbAddr,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr,\r
              XHC_GENERIC_TIMEOUT,\r
-             (TRB **) (UINTN) &EvtTrb\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
              );\r
   ASSERT (!EFI_ERROR(Status));\r
 \r
-  DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputDevContxt)->Slot.DeviceAddress;\r
-  DEBUG ((EFI_D_INFO, "    Address %d assigned succeefully\n", DeviceAddress));\r
+  DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputContext)->Slot.DeviceAddress;\r
+  DEBUG ((EFI_D_INFO, "    Address %d assigned successfully\n", DeviceAddress));\r
 \r
-  UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;\r
+  Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;\r
 \r
   return Status;\r
 }\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 device.\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_DEV              *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                   *EvtTrb;\r
-  CMD_TRB_DIS_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
+  ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));\r
+  CmdTrb.CycleBit = 1;\r
+  CmdTrb.Type     = TRB_TYPE_EN_SLOT;\r
+\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
+  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
-  // Disable the device slots occupied by these devices on its downstream ports.\r
-  // Entry 0 is reserved.\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
-  for (Index = 0; Index < 255; Index++) {\r
-    if (!UsbDevContext[Index + 1].Enabled ||\r
-        (UsbDevContext[Index + 1].SlotId == 0) ||\r
-        (UsbDevContext[Index + 1].ParentRouteString.Dword != UsbDevContext[SlotId].RouteString.Dword)) {\r
-      continue;\r
-    }\r
-\r
-    Status = XhcDisableSlotCmd (Xhc, UsbDevContext[Index + 1].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
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n"));\r
-      UsbDevContext[Index + 1].SlotId = 0;\r
-    }\r
-  }\r
+  Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext;\r
 \r
   //\r
-  // Construct the disable slot command\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
+  InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);\r
+\r
+  //\r
+  // 3) Initialize the Input Slot Context data structure\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
+  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
+  //\r
+  // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint.\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 successfully\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
@@ -2026,9 +2232,9 @@ XhcDisableSlotCmd (
   CmdTrbDisSlot.SlotId   = SlotId;\r
   Status = XhcCmdTransfer (\r
              Xhc,\r
-             (TRB *) (UINTN) &CmdTrbDisSlot,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot,\r
              XHC_GENERIC_TIMEOUT,\r
-             (TRB **) (UINTN) &EvtTrb\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
              );\r
   ASSERT_EFI_ERROR(Status);\r
   //\r
@@ -2040,42 +2246,44 @@ XhcDisableSlotCmd (
   // Free the slot related data structure\r
   //\r
   for (Index = 0; Index < 31; Index++) {\r
-    if (UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
-      RingSeg = ((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
+    if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) {\r
+      RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;\r
       if (RingSeg != NULL) {\r
-        FreeAlignedPool(RingSeg);\r
+        FreePages (RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER));\r
       }\r
-      FreeAlignedPool(UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
+      FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);\r
     }\r
   }\r
 \r
-  for (Index = 0; Index < UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {\r
-    if (UsbDevContext[SlotId].ConfDesc[Index] != NULL) {\r
-      FreePool (UsbDevContext[SlotId].ConfDesc[Index]);\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 (UsbDevContext[SlotId].InputContext != NULL) {\r
-    FreeAlignedPool (UsbDevContext[SlotId].InputContext);\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 (UsbDevContext[SlotId].OutputDevContxt != NULL) {\r
-    FreeAlignedPool (UsbDevContext[SlotId].OutputDevContxt);\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
-  UsbDevContext[SlotId].Enabled = FALSE;\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 device.\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
@@ -2086,38 +2294,38 @@ XhcDisableSlotCmd (
 EFI_STATUS\r
 EFIAPI\r
 XhcSetConfigCmd (\r
-  IN USB_XHCI_DEV             *Xhc,\r
+  IN USB_XHCI_INSTANCE        *Xhc,\r
   IN UINT8                    SlotId,\r
-  IN  UINT8                   DeviceSpeed,\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_CFG_ED                 CmdTrbCfgEP;\r
-  INPUT_CONTEXT              *InputContext;\r
-  DEVICE_CONTEXT             *OutputDevContxt;\r
-  EVT_TRB_COMMAND            *EvtTrb;\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    = UsbDevContext[SlotId].InputContext;\r
-  OutputDevContxt = UsbDevContext[SlotId].OutputDevContxt;\r
+  InputContext  = Xhc->UsbDevContext[SlotId].InputContext;\r
+  OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;\r
   ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
-  CopyMem (&InputContext->Slot, &OutputDevContxt->Slot, sizeof (SLOT_CONTEXT));\r
+  CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT));\r
 \r
   ASSERT (ConfigDesc != NULL);\r
 \r
@@ -2141,6 +2349,7 @@ XhcSetConfigCmd (
       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
@@ -2168,10 +2377,10 @@ XhcSetConfigCmd (
           }\r
 \r
           InputContext->EP[Dci-1].AverageTRBLength = 0x1000;\r
-          if (UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
-            EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64);\r
-            UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
-            CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\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
@@ -2200,22 +2409,26 @@ XhcSetConfigCmd (
           if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {\r
             Interval = EpDesc->Interval;\r
             //\r
-            // BUGBUG: Hard code the interval to MAX\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_SUPER) {\r
+          } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {\r
             Interval = EpDesc->Interval;\r
-            InputContext->EP[Dci-1].Interval         = 0x0F;\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 (UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) {\r
-            EndpointTransferRing = AllocateAlignedZeroPool(sizeof (TRANSFER_RING), 64);\r
-            UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
-            CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\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
@@ -2225,11 +2438,11 @@ XhcSetConfigCmd (
           break;\r
       }\r
 \r
-      PhyAddr  = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
+      PhyAddr  = XHC_LOW_32BIT (((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\r
       PhyAddr &= ~(0x0F);\r
-      PhyAddr |= ((TRANSFER_RING *)(UINTN)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS;\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)UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0);\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
@@ -2246,23 +2459,216 @@ XhcSetConfigCmd (
   CmdTrbCfgEP.PtrHi    = XHC_HIGH_32BIT (InputContext);\r
   CmdTrbCfgEP.CycleBit = 1;\r
   CmdTrbCfgEP.Type     = TRB_TYPE_CON_ENDPOINT;\r
-  CmdTrbCfgEP.SlotId   = UsbDevContext[SlotId].SlotId;\r
+  CmdTrbCfgEP.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
   DEBUG ((EFI_D_INFO, "Configure Endpoint\n"));\r
   Status = XhcCmdTransfer (\r
              Xhc,\r
-             (TRB *) (UINTN) &CmdTrbCfgEP,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
              XHC_GENERIC_TIMEOUT,\r
-             (TRB **) (UINTN) &EvtTrb\r
+             (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
              );\r
   ASSERT_EFI_ERROR(Status);\r
 \r
   return Status;\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
+XhcSetConfigCmd64 (\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_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_64));\r
+  CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64));\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
+\r
 /**\r
   Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd.\r
 \r
-  @param  Xhc           The XHCI device.\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
@@ -2272,22 +2678,22 @@ XhcSetConfigCmd (
 EFI_STATUS\r
 EFIAPI\r
 XhcEvaluateContext (\r
-  IN USB_XHCI_DEV             *Xhc,\r
+  IN USB_XHCI_INSTANCE        *Xhc,\r
   IN UINT8                    SlotId,\r
   IN UINT32                   MaxPacketSize\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  CMD_TRB_EVALU_CONTX   CmdTrbEvalu;\r
-  EVT_TRB_COMMAND       *EvtTrb;\r
-  INPUT_CONTEXT         *InputContext;\r
+  EFI_STATUS                  Status;\r
+  CMD_TRB_EVALUATE_CONTEXT    CmdTrbEvalu;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  INPUT_CONTEXT               *InputContext;\r
 \r
-  ASSERT (UsbDevContext[SlotId].SlotId != 0);\r
+  ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);\r
 \r
   //\r
   // 4.6.7 Evaluate Context\r
   //\r
-  InputContext = UsbDevContext[SlotId].InputContext;\r
+  InputContext = Xhc->UsbDevContext[SlotId].InputContext;\r
   ZeroMem (InputContext, sizeof (INPUT_CONTEXT));\r
 \r
   InputContext->InputControlContext.Dword2 |= BIT1;\r
@@ -2298,23 +2704,76 @@ XhcEvaluateContext (
   CmdTrbEvalu.PtrHi    = XHC_HIGH_32BIT (InputContext);\r
   CmdTrbEvalu.CycleBit = 1;\r
   CmdTrbEvalu.Type     = TRB_TYPE_EVALU_CONTXT;\r
-  CmdTrbEvalu.SlotId   = UsbDevContext[SlotId].SlotId;\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
+  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 *) (UINTN) &CmdTrbEvalu,\r
+             (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu,\r
              XHC_GENERIC_TIMEOUT,\r
-             (TRB **) (UINTN) &EvtTrb\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
-  @param  Xhc           The XHCI device.\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
@@ -2325,23 +2784,23 @@ XhcEvaluateContext (
 **/\r
 EFI_STATUS\r
 XhcConfigHubContext (\r
-  IN USB_XHCI_DEV             *Xhc,\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
+  EFI_STATUS                  Status;\r
 \r
-  EVT_TRB_COMMAND       *EvtTrb;\r
-  INPUT_CONTEXT         *InputContext;\r
-  DEVICE_CONTEXT        *OutputDevContxt;\r
-  CMD_CFG_ED            CmdTrbCfgEP;\r
+  EVT_TRB_COMMAND_COMPLETION  *EvtTrb;\r
+  INPUT_CONTEXT               *InputContext;\r
+  DEVICE_CONTEXT              *OutputContext;\r
+  CMD_TRB_CONFIG_ENDPOINT     CmdTrbCfgEP;\r
 \r
-  ASSERT (UsbDevContext[SlotId].SlotId != 0);\r
-  InputContext    = UsbDevContext[SlotId].InputContext;\r
-  OutputDevContxt = UsbDevContext[SlotId].OutputDevContxt;\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
@@ -2353,7 +2812,73 @@ XhcConfigHubContext (
   //\r
   // Copy the slot context from OutputContext to Input context\r
   //\r
-  CopyMem(&(InputContext->Slot), &(OutputDevContxt->Slot), sizeof (SLOT_CONTEXT));\r
+  CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT));\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
+  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
@@ -2364,16 +2889,17 @@ XhcConfigHubContext (
   CmdTrbCfgEP.PtrHi    = XHC_HIGH_32BIT (InputContext);\r
   CmdTrbCfgEP.CycleBit = 1;\r
   CmdTrbCfgEP.Type     = TRB_TYPE_CON_ENDPOINT;\r
-  CmdTrbCfgEP.SlotId   = UsbDevContext[SlotId].SlotId;\r
+  CmdTrbCfgEP.SlotId   = Xhc->UsbDevContext[SlotId].SlotId;\r
   DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n"));\r
   Status = XhcCmdTransfer (\r
               Xhc,\r
-              (TRB *) (UINTN) &CmdTrbCfgEP,\r
+              (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP,\r
               XHC_GENERIC_TIMEOUT,\r
-              (TRB **) (UINTN) &EvtTrb\r
+              (TRB_TEMPLATE **) (UINTN) &EvtTrb\r
               );\r
   ASSERT (!EFI_ERROR(Status));\r
 \r
   return Status;\r
 }\r
 \r
+\r