Revision: 17002
          http://sourceforge.net/p/edk2/code/17002
Author:   zwei4
Date:     2015-03-03 09:13:32 +0000 (Tue, 03 Mar 2015)
Log Message:
-----------
Enhance error handling of XHCI driver.

Enhance error handling of XHCI driver. After babble error detected, end point 
needs to be reset to recover from "halt" state. 
This override is a temp solution. It will be removed after 
MdeModulePkg/Bus/Pci/XhciDxe driver get enhanced.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <[email protected]>

Modified Paths:
--------------
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/PlatformPkg.fdf
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/PlatformPkgX64.dsc

Added Paths:
-----------
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.uni
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxeExtra.uni
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
    
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h

Added: 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c
===================================================================
--- 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c
                                (rev 0)
+++ 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c
        2015-03-03 09:13:32 UTC (rev 17002)
@@ -0,0 +1,224 @@
+/** @file
+  UEFI Component Name(2) protocol implementation for XHCI driver.
+
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution.  The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Xhci.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gXhciComponentName 
= {
+  XhciComponentNameGetDriverName,
+  XhciComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gXhciComponentName2 
= {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) XhciComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) XhciComponentNameGetControllerName,
+  "en"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mXhciDriverNameTable[] 
= {
+  { "eng;en", L"Usb Xhci Driver" },
+  { NULL , NULL }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+XhciComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mXhciDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gXhciComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified 
by
+  Language, then a pointer to the controller name is returned in 
ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not 
currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter 
that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus 
drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name 
in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+XhciComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  EFI_HANDLE                   ControllerHandle,
+  IN  EFI_HANDLE                   ChildHandle OPTIONAL,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **ControllerName
+  )
+{
+  EFI_STATUS           Status;
+  EFI_USB2_HC_PROTOCOL *Usb2Hc;
+  USB_XHCI_INSTANCE    *XhciDev;
+
+  //
+  // This is a device driver, so ChildHandle must be NULL.
+  //
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Make sure this driver is currently managing ControllerHandle
+  //
+  Status = EfiTestManagedDevice (
+             ControllerHandle,
+             gXhciDriverBinding.DriverBindingHandle,
+             &gEfiPciIoProtocolGuid
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the device context
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiUsb2HcProtocolGuid,
+                  (VOID **) &Usb2Hc,
+                  gXhciDriverBinding.DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  XhciDev = XHC_FROM_THIS (Usb2Hc);
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           XhciDev->ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gXhciComponentName)
+           );
+
+}

Added: 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h
===================================================================
--- 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h
                                (rev 0)
+++ 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h
        2015-03-03 09:13:32 UTC (rev 17002)
@@ -0,0 +1,146 @@
+/** @file
+
+  This file contains the delarations for componet name routines.
+
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_COMPONENT_NAME_H_
+#define _EFI_COMPONENT_NAME_H_
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+XhciComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified 
by
+  Language, then a pointer to the controller name is returned in 
ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not 
currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter 
that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus 
drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name 
in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+XhciComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  EFI_HANDLE                   ControllerHandle,
+  IN  EFI_HANDLE                   ChildHandle OPTIONAL,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **ControllerName
+  );
+
+#endif
+

Added: 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
===================================================================
--- 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
                             (rev 0)
+++ 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
     2015-03-03 09:13:32 UTC (rev 17002)
@@ -0,0 +1,758 @@
+/** @file
+
+  Routine procedures for memory allocate/free.
+
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "Xhci.h"
+
+
+/**
+  Allocate a block of memory to be used by the buffer pool.
+
+  @param  Pool           The buffer pool to allocate memory for.
+  @param  Pages          How many pages to allocate.
+
+  @return The allocated memory block or NULL if failed.
+
+**/
+USBHC_MEM_BLOCK *
+UsbHcAllocMemBlock (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Pages
+  )
+{
+  USBHC_MEM_BLOCK         *Block;
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  VOID                    *BufHost;
+  VOID                    *Mapping;
+  EFI_PHYSICAL_ADDRESS    MappedAddr;
+  UINTN                   Bytes;
+  EFI_STATUS              Status;
+
+  PciIo = Pool->PciIo;
+
+  Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK));
+  if (Block == NULL) {
+    return NULL;
+  }
+
+  //
+  // each bit in the bit array represents USBHC_MEM_UNIT
+  // bytes of memory in the memory block.
+  //
+  ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);
+
+  Block->BufLen   = EFI_PAGES_TO_SIZE (Pages);
+  Block->BitsLen  = Block->BufLen / (USBHC_MEM_UNIT * 8);
+  Block->Bits     = AllocateZeroPool (Block->BitsLen);
+
+  if (Block->Bits == NULL) {
+    gBS->FreePool (Block);
+    return NULL;
+  }
+
+  //
+  // Allocate the number of Pages of memory, then map it for
+  // bus master read and write.
+  //
+  Status = PciIo->AllocateBuffer (
+                    PciIo,
+                    AllocateAnyPages,
+                    EfiBootServicesData,
+                    Pages,
+                    &BufHost,
+                    0
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto FREE_BITARRAY;
+  }
+
+  Bytes = EFI_PAGES_TO_SIZE (Pages);
+  Status = PciIo->Map (
+                    PciIo,
+                    EfiPciIoOperationBusMasterCommonBuffer,
+                    BufHost,
+                    &Bytes,
+                    &MappedAddr,
+                    &Mapping
+                    );
+
+  if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) {
+    goto FREE_BUFFER;
+  }
+
+  Block->BufHost  = BufHost;
+  Block->Buf      = (UINT8 *) ((UINTN) MappedAddr);
+  Block->Mapping  = Mapping;
+
+  return Block;
+
+FREE_BUFFER:
+  PciIo->FreeBuffer (PciIo, Pages, BufHost);
+
+FREE_BITARRAY:
+  gBS->FreePool (Block->Bits);
+  gBS->FreePool (Block);
+  return NULL;
+}
+
+
+/**
+  Free the memory block from the memory pool.
+
+  @param  Pool           The memory pool to free the block from.
+  @param  Block          The memory block to free.
+
+**/
+VOID
+UsbHcFreeMemBlock (
+  IN USBHC_MEM_POOL       *Pool,
+  IN USBHC_MEM_BLOCK      *Block
+  )
+{
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+
+  ASSERT ((Pool != NULL) && (Block != NULL));
+
+  PciIo = Pool->PciIo;
+
+  //
+  // Unmap the common buffer then free the structures
+  //
+  PciIo->Unmap (PciIo, Block->Mapping);
+  PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost);
+
+  gBS->FreePool (Block->Bits);
+  gBS->FreePool (Block);
+}
+
+
+/**
+  Alloc some memory from the block.
+
+  @param  Block          The memory block to allocate memory from.
+  @param  Units          Number of memory units to allocate.
+
+  @return The pointer to the allocated memory. If couldn't allocate the needed 
memory,
+          the return value is NULL.
+
+**/
+VOID *
+UsbHcAllocMemFromBlock (
+  IN  USBHC_MEM_BLOCK     *Block,
+  IN  UINTN               Units
+  )
+{
+  UINTN                   Byte;
+  UINT8                   Bit;
+  UINTN                   StartByte;
+  UINT8                   StartBit;
+  UINTN                   Available;
+  UINTN                   Count;
+
+  ASSERT ((Block != 0) && (Units != 0));
+
+  StartByte  = 0;
+  StartBit   = 0;
+  Available  = 0;
+
+  for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
+    //
+    // If current bit is zero, the corresponding memory unit is
+    // available, otherwise we need to restart our searching.
+    // Available counts the consective number of zero bit.
+    //
+    if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+      Available++;
+
+      if (Available >= Units) {
+        break;
+      }
+
+      NEXT_BIT (Byte, Bit);
+
+    } else {
+      NEXT_BIT (Byte, Bit);
+
+      Available  = 0;
+      StartByte  = Byte;
+      StartBit   = Bit;
+    }
+  }
+
+  if (Available < Units) {
+    return NULL;
+  }
+
+  //
+  // Mark the memory as allocated
+  //
+  Byte  = StartByte;
+  Bit   = StartBit;
+
+  for (Count = 0; Count < Units; Count++) {
+    ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+    Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | USB_HC_BIT (Bit));
+    NEXT_BIT (Byte, Bit);
+  }
+
+  return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
+}
+
+/**
+  Calculate the corresponding pci bus address according to the Mem parameter.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The pointer to host memory.
+  @param  Size           The size of the memory region.
+
+  @return                The pci memory address
+
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetPciAddrForHostAddr (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  UINTN                   AllocSize;
+  EFI_PHYSICAL_ADDRESS    PhyAddr;
+  UINTN                   Offset;
+
+  Head      = Pool->Head;
+  AllocSize = USBHC_MEM_ROUND (Size);
+
+  if (Mem == NULL) {
+    return 0;
+  }
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    //
+    // scan the memory block list for the memory block that
+    // completely contains the allocated memory.
+    //
+    if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= 
(Block->BufHost + Block->BufLen))) {
+      break;
+    }
+  }
+
+  ASSERT ((Block != NULL));
+  //
+  // calculate the pci memory address for host memory address.
+  //
+  Offset = (UINT8 *)Mem - Block->BufHost;
+  PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
+  return PhyAddr;
+}
+
+/**
+  Calculate the corresponding host address according to the pci address.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The pointer to pci memory.
+  @param  Size           The size of the memory region.
+
+  @return                The host memory address
+
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetHostAddrForPciAddr (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  UINTN                   AllocSize;
+  EFI_PHYSICAL_ADDRESS    HostAddr;
+  UINTN                   Offset;
+
+  Head      = Pool->Head;
+  AllocSize = USBHC_MEM_ROUND (Size);
+
+  if (Mem == NULL) {
+    return 0;
+  }
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    //
+    // scan the memory block list for the memory block that
+    // completely contains the allocated memory.
+    //
+    if ((Block->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= 
(Block->Buf + Block->BufLen))) {
+      break;
+    }
+  }
+
+  ASSERT ((Block != NULL));
+  //
+  // calculate the pci memory address for host memory address.
+  //
+  Offset = (UINT8 *)Mem - Block->Buf;
+  HostAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->BufHost + Offset);
+  return HostAddr;
+}
+
+/**
+  Insert the memory block to the pool's list of the blocks.
+
+  @param  Head           The head of the memory pool's block list.
+  @param  Block          The memory block to insert.
+
+**/
+VOID
+UsbHcInsertMemBlockToPool (
+  IN USBHC_MEM_BLOCK      *Head,
+  IN USBHC_MEM_BLOCK      *Block
+  )
+{
+  ASSERT ((Head != NULL) && (Block != NULL));
+  Block->Next = Head->Next;
+  Head->Next  = Block;
+}
+
+
+/**
+  Is the memory block empty?
+
+  @param  Block   The memory block to check.
+
+  @retval TRUE    The memory block is empty.
+  @retval FALSE   The memory block isn't empty.
+
+**/
+BOOLEAN
+UsbHcIsMemBlockEmpty (
+  IN USBHC_MEM_BLOCK     *Block
+  )
+{
+  UINTN                   Index;
+
+  for (Index = 0; Index < Block->BitsLen; Index++) {
+    if (Block->Bits[Index] != 0) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
+/**
+  Unlink the memory block from the pool's list.
+
+  @param  Head           The block list head of the memory's pool.
+  @param  BlockToUnlink  The memory block to unlink.
+
+**/
+VOID
+UsbHcUnlinkMemBlock (
+  IN USBHC_MEM_BLOCK      *Head,
+  IN USBHC_MEM_BLOCK      *BlockToUnlink
+  )
+{
+  USBHC_MEM_BLOCK         *Block;
+
+  ASSERT ((Head != NULL) && (BlockToUnlink != NULL));
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    if (Block->Next == BlockToUnlink) {
+      Block->Next         = BlockToUnlink->Next;
+      BlockToUnlink->Next = NULL;
+      break;
+    }
+  }
+}
+
+
+/**
+  Initialize the memory management pool for the host controller.
+
+  @param  PciIo                The PciIo that can be used to access the host 
controller.
+
+  @retval EFI_SUCCESS          The memory pool is initialized.
+  @retval EFI_OUT_OF_RESOURCE  Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo
+  )
+{
+  USBHC_MEM_POOL          *Pool;
+
+  Pool = AllocatePool (sizeof (USBHC_MEM_POOL));
+
+  if (Pool == NULL) {
+    return Pool;
+  }
+
+  Pool->PciIo   = PciIo;
+  Pool->Head    = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES);
+
+  if (Pool->Head == NULL) {
+    gBS->FreePool (Pool);
+    Pool = NULL;
+  }
+
+  return Pool;
+}
+
+
+/**
+  Release the memory management pool.
+
+  @param  Pool              The USB memory pool to free.
+
+  @retval EFI_SUCCESS       The memory pool is freed.
+  @retval EFI_DEVICE_ERROR  Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+  IN USBHC_MEM_POOL       *Pool
+  )
+{
+  USBHC_MEM_BLOCK *Block;
+
+  ASSERT (Pool->Head != NULL);
+
+  //
+  // Unlink all the memory blocks from the pool, then free them.
+  // UsbHcUnlinkMemBlock can't be used to unlink and free the
+  // first block.
+  //
+  for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
+    UsbHcUnlinkMemBlock (Pool->Head, Block);
+    UsbHcFreeMemBlock (Pool, Block);
+  }
+
+  UsbHcFreeMemBlock (Pool, Pool->Head);
+  gBS->FreePool (Pool);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Allocate some memory from the host controller's memory pool
+  which can be used to communicate with host controller.
+
+  @param  Pool           The host controller's memory pool.
+  @param  Size           Size of the memory to allocate.
+
+  @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  USBHC_MEM_BLOCK         *NewBlock;
+  VOID                    *Mem;
+  UINTN                   AllocSize;
+  UINTN                   Pages;
+
+  Mem       = NULL;
+  AllocSize = USBHC_MEM_ROUND (Size);
+  Head      = Pool->Head;
+  ASSERT (Head != NULL);
+
+  //
+  // First check whether current memory blocks can satisfy the allocation.
+  //
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+
+    if (Mem != NULL) {
+      ZeroMem (Mem, Size);
+      break;
+    }
+  }
+
+  if (Mem != NULL) {
+    return Mem;
+  }
+
+  //
+  // Create a new memory block if there is not enough memory
+  // in the pool. If the allocation size is larger than the
+  // default page number, just allocate a large enough memory
+  // block. Otherwise allocate default pages.
+  //
+  if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {
+    Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1;
+  } else {
+    Pages = USBHC_MEM_DEFAULT_PAGES;
+  }
+
+  NewBlock = UsbHcAllocMemBlock (Pool, Pages);
+
+  if (NewBlock == NULL) {
+    DEBUG ((EFI_D_ERROR, "UsbHcAllocateMem: failed to allocate block\n"));
+    return NULL;
+  }
+
+  //
+  // Add the new memory block to the pool, then allocate memory from it
+  //
+  UsbHcInsertMemBlockToPool (Head, NewBlock);
+  Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+
+  if (Mem != NULL) {
+    ZeroMem (Mem, Size);
+  }
+
+  return Mem;
+}
+
+
+/**
+  Free the allocated memory back to the memory pool.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The memory to free.
+  @param  Size           The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  UINT8                   *ToFree;
+  UINTN                   AllocSize;
+  UINTN                   Byte;
+  UINTN                   Bit;
+  UINTN                   Count;
+
+  Head      = Pool->Head;
+  AllocSize = USBHC_MEM_ROUND (Size);
+  ToFree    = (UINT8 *) Mem;
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    //
+    // scan the memory block list for the memory block that
+    // completely contains the memory to free.
+    //
+    if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost 
+ Block->BufLen))) {
+      //
+      // compute the start byte and bit in the bit array
+      //
+      Byte  = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;
+      Bit   = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;
+
+      //
+      // reset associated bits in bit arry
+      //
+      for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {
+        ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+        Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));
+        NEXT_BIT (Byte, Bit);
+      }
+
+      break;
+    }
+  }
+
+  //
+  // If Block == NULL, it means that the current memory isn't
+  // in the host controller's pool. This is critical because
+  // the caller has passed in a wrong memory point
+  //
+  ASSERT (Block != NULL);
+
+  //
+  // Release the current memory block if it is empty and not the head
+  //
+  if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
+    UsbHcUnlinkMemBlock (Head, Block);
+    UsbHcFreeMemBlock (Pool, Block);
+  }
+
+  return ;
+}
+
+/**  
+  Allocates pages at a specified alignment that are suitable for an 
EfiPciIoOperationBusMasterCommonBuffer mapping.
+  
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+  @param  PciIo                 The PciIo that can be used to access the host 
controller.
+  @param  Pages                 The number of pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  
Must be a power of two.
+  @param  HostAddress           The system memory address to map to the PCI 
controller.
+  @param  DeviceAddress         The resulting map address for the bus master 
PCI controller to 
+                                use to access the hosts HostAddress.
+  @param  Mapping               A resulting value to pass to Unmap().
+
+  @retval EFI_SUCCESS           Success to allocate aligned pages.
+  @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid.
+  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to allocate 
memory.
+  
+
+**/
+EFI_STATUS
+UsbHcAllocateAlignedPages (
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,
+  IN UINTN                  Pages,
+  IN UINTN                  Alignment,
+  OUT VOID                  **HostAddress,
+  OUT EFI_PHYSICAL_ADDRESS  *DeviceAddress,
+  OUT VOID                  **Mapping
+  )
+{
+  EFI_STATUS            Status;
+  VOID                  *Memory;
+  UINTN                 AlignedMemory;
+  UINTN                 AlignmentMask;
+  UINTN                 UnalignedPages;
+  UINTN                 RealPages;
+  UINTN                 Bytes;
+
+  //
+  // Alignment must be a power of two or zero.
+  //
+  ASSERT ((Alignment & (Alignment - 1)) == 0);
+  
+  if ((Alignment & (Alignment - 1)) != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+ 
+  if (Pages == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (Alignment > EFI_PAGE_SIZE) {
+    //
+    // Caculate the total number of pages since alignment is larger than page 
size.
+    //
+    AlignmentMask  = Alignment - 1;
+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
+    //
+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not 
overflow.
+    //
+    ASSERT (RealPages > Pages);
+ 
+    Status = PciIo->AllocateBuffer (
+                      PciIo,
+                      AllocateAnyPages,
+                      EfiBootServicesData,
+                      Pages,
+                      &Memory,
+                      0
+                      );    
+    if (EFI_ERROR (Status)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
+    if (UnalignedPages > 0) {
+      //
+      // Free first unaligned page(s).
+      //
+      Status = PciIo->FreeBuffer (PciIo, UnalignedPages, Memory);
+      ASSERT_EFI_ERROR (Status);
+    }
+    Memory         = (VOID *)(UINTN)(AlignedMemory + EFI_PAGES_TO_SIZE 
(Pages));
+    UnalignedPages = RealPages - Pages - UnalignedPages;
+    if (UnalignedPages > 0) {
+      //
+      // Free last unaligned page(s).
+      //
+      Status = PciIo->FreeBuffer (PciIo, UnalignedPages, Memory);
+      ASSERT_EFI_ERROR (Status);
+    }
+  } else {
+    //
+    // Do not over-allocate pages in this case.
+    //
+    Status = PciIo->AllocateBuffer (
+                      PciIo,
+                      AllocateAnyPages,
+                      EfiBootServicesData,
+                      Pages,
+                      &Memory,
+                      0
+                      );
+    if (EFI_ERROR (Status)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    AlignedMemory  = (UINTN) Memory;
+  }
+
+  Bytes = EFI_PAGES_TO_SIZE (Pages);
+  Status = PciIo->Map (
+                    PciIo,
+                    EfiPciIoOperationBusMasterCommonBuffer,
+                    (VOID *) AlignedMemory,
+                    &Bytes,
+                    DeviceAddress,
+                    Mapping
+                    );
+
+  if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) {
+    Status = PciIo->FreeBuffer (PciIo, Pages, (VOID *) AlignedMemory);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  
+  *HostAddress = (VOID *) AlignedMemory;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Frees memory that was allocated with UsbHcAllocateAlignedPages().
+  
+  @param  PciIo                 The PciIo that can be used to access the host 
controller.
+  @param  HostAddress           The system memory address to map to the PCI 
controller.
+  @param  Pages                 The number of 4 KB pages to free.
+  @param  Mapping               The mapping value returned from Map().
+
+**/
+VOID
+UsbHcFreeAlignedPages (
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,
+  IN VOID                   *HostAddress,
+  IN UINTN                  Pages,
+  VOID                      *Mapping
+  )
+{
+  EFI_STATUS      Status;
+  
+  ASSERT (Pages != 0);
+  
+  Status = PciIo->Unmap (PciIo, Mapping);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PciIo->FreeBuffer (
+                    PciIo,
+                    Pages,
+                    HostAddress
+                    );     
+  ASSERT_EFI_ERROR (Status);
+}

Added: 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
===================================================================
--- 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
                             (rev 0)
+++ 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
     2015-03-03 09:13:32 UTC (rev 17002)
@@ -0,0 +1,213 @@
+/** @file
+
+  This file contains the definination for host controller memory management 
routines.
+
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_XHCI_MEM_H_
+#define _EFI_XHCI_MEM_H_
+
+#define USB_HC_BIT(a)                  ((UINTN)(1 << (a)))
+
+#define USB_HC_BIT_IS_SET(Data, Bit)   \
+          ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit)))
+
+typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK;
+struct _USBHC_MEM_BLOCK {
+  UINT8                   *Bits;    // Bit array to record which unit is 
allocated
+  UINTN                   BitsLen;
+  UINT8                   *Buf;
+  UINT8                   *BufHost;
+  UINTN                   BufLen;   // Memory size in bytes
+  VOID                    *Mapping;
+  USBHC_MEM_BLOCK         *Next;
+};
+
+//
+// USBHC_MEM_POOL is used to manage the memory used by USB
+// host controller. XHCI requires the control memory and transfer
+// data to be on the same 4G memory.
+//
+typedef struct _USBHC_MEM_POOL {
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  BOOLEAN                 Check4G;
+  UINT32                  Which4G;
+  USBHC_MEM_BLOCK         *Head;
+} USBHC_MEM_POOL;
+
+//
+// Memory allocation unit, must be 2^n, n>4
+//
+#define USBHC_MEM_UNIT           64
+
+#define USBHC_MEM_UNIT_MASK      (USBHC_MEM_UNIT - 1)
+#define USBHC_MEM_DEFAULT_PAGES  16
+
+#define USBHC_MEM_ROUND(Len)  (((Len) + USBHC_MEM_UNIT_MASK) & 
(~USBHC_MEM_UNIT_MASK))
+
+//
+// Advance the byte and bit to the next bit, adjust byte accordingly.
+//
+#define NEXT_BIT(Byte, Bit)   \
+          do {                \
+            (Bit)++;          \
+            if ((Bit) > 7) {  \
+              (Byte)++;       \
+              (Bit) = 0;      \
+            }                 \
+          } while (0)
+
+
+
+/**
+  Initialize the memory management pool for the host controller.
+
+  @param  PciIo               The PciIo that can be used to access the host 
controller.
+
+  @retval EFI_SUCCESS         The memory pool is initialized.
+  @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo
+  );
+
+
+/**
+  Release the memory management pool.
+
+  @param   Pool               The USB memory pool to free.
+
+  @retval EFI_SUCCESS       The memory pool is freed.
+  @retval EFI_DEVICE_ERROR  Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+  IN USBHC_MEM_POOL       *Pool
+  );
+
+
+/**
+  Allocate some memory from the host controller's memory pool
+  which can be used to communicate with host controller.
+
+  @param  Pool  The host controller's memory pool.
+  @param  Size  Size of the memory to allocate.
+
+  @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Size
+  );
+
+
+/**
+  Free the allocated memory back to the memory pool.
+
+  @param  Pool  The memory pool of the host controller.
+  @param  Mem   The memory to free.
+  @param  Size  The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  );
+
+/**
+  Calculate the corresponding pci bus address according to the Mem parameter.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The pointer to host memory.
+  @param  Size           The size of the memory region.
+
+  @return                The pci memory address
+
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetPciAddrForHostAddr (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  );
+
+/**
+  Calculate the corresponding host address according to the pci address.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The pointer to pci memory.
+  @param  Size           The size of the memory region.
+
+  @return                The host memory address
+
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetHostAddrForPciAddr (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  );
+
+/**  
+  Allocates pages at a specified alignment that are suitable for an 
EfiPciIoOperationBusMasterCommonBuffer mapping.
+  
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+  @param  PciIo                 The PciIo that can be used to access the host 
controller.
+  @param  Pages                 The number of pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  
Must be a power of two.
+  @param  HostAddress           The system memory address to map to the PCI 
controller.
+  @param  DeviceAddress         The resulting map address for the bus master 
PCI controller to 
+                                use to access the hosts HostAddress.
+  @param  Mapping               A resulting value to pass to Unmap().
+
+  @retval EFI_SUCCESS           Success to allocate aligned pages.
+  @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid.
+  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to allocate 
memory.
+  
+
+**/
+EFI_STATUS
+UsbHcAllocateAlignedPages (
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,
+  IN UINTN                  Pages,
+  IN UINTN                  Alignment,
+  OUT VOID                  **HostAddress,
+  OUT EFI_PHYSICAL_ADDRESS  *DeviceAddress,
+  OUT VOID                  **Mapping
+  );
+  
+/**
+  Frees memory that was allocated with UsbHcAllocateAlignedPages().
+  
+  @param  PciIo                 The PciIo that can be used to access the host 
controller.
+  @param  HostAddress           The system memory address to map to the PCI 
controller.
+  @param  Pages                 The number of pages to free.
+  @param  Mapping               The mapping value returned from Map().
+
+**/
+VOID
+UsbHcFreeAlignedPages (
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,
+  IN VOID                   *HostAddress,
+  IN UINTN                  Pages,
+  VOID                      *Mapping
+  );
+
+#endif

Added: 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
===================================================================
--- 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
                         (rev 0)
+++ 
branches/UDK2014.SP1/Vlv2TbltDevicePkg/Override/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
 2015-03-03 09:13:32 UTC (rev 17002)
@@ -0,0 +1,2223 @@
+/** @file
+  The XHCI controller driver.
+
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Xhci.h"
+
+//
+// Two arrays used to translate the XHCI port state (change)
+// to the UEFI protocol's port state (change).
+//
+USB_PORT_STATE_MAP  mUsbPortStateMap[] = {
+  {XHC_PORTSC_CCS,   USB_PORT_STAT_CONNECTION},
+  {XHC_PORTSC_PED,   USB_PORT_STAT_ENABLE},
+  {XHC_PORTSC_OCA,   USB_PORT_STAT_OVERCURRENT},
+  {XHC_PORTSC_RESET, USB_PORT_STAT_RESET}
+};
+
+USB_PORT_STATE_MAP  mUsbPortChangeMap[] = {
+  {XHC_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION},
+  {XHC_PORTSC_PEC, USB_PORT_STAT_C_ENABLE},
+  {XHC_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT},
+  {XHC_PORTSC_PRC, USB_PORT_STAT_C_RESET}
+};
+
+USB_CLEAR_PORT_MAP mUsbClearPortChangeMap[] = {
+  {XHC_PORTSC_CSC, EfiUsbPortConnectChange},
+  {XHC_PORTSC_PEC, EfiUsbPortEnableChange},
+  {XHC_PORTSC_OCC, EfiUsbPortOverCurrentChange},
+  {XHC_PORTSC_PRC, EfiUsbPortResetChange}
+};
+
+USB_PORT_STATE_MAP  mUsbHubPortStateMap[] = {
+  {XHC_HUB_PORTSC_CCS,   USB_PORT_STAT_CONNECTION},
+  {XHC_HUB_PORTSC_PED,   USB_PORT_STAT_ENABLE},
+  {XHC_HUB_PORTSC_OCA,   USB_PORT_STAT_OVERCURRENT},
+  {XHC_HUB_PORTSC_RESET, USB_PORT_STAT_RESET}
+};
+
+USB_PORT_STATE_MAP  mUsbHubPortChangeMap[] = {
+  {XHC_HUB_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION},
+  {XHC_HUB_PORTSC_PEC, USB_PORT_STAT_C_ENABLE},
+  {XHC_HUB_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT},
+  {XHC_HUB_PORTSC_PRC, USB_PORT_STAT_C_RESET}
+};
+
+USB_CLEAR_PORT_MAP mUsbHubClearPortChangeMap[] = {
+  {XHC_HUB_PORTSC_CSC, EfiUsbPortConnectChange},
+  {XHC_HUB_PORTSC_PEC, EfiUsbPortEnableChange},
+  {XHC_HUB_PORTSC_OCC, EfiUsbPortOverCurrentChange},
+  {XHC_HUB_PORTSC_PRC, EfiUsbPortResetChange},
+  {XHC_HUB_PORTSC_BHRC, Usb3PortBHPortResetChange}
+};
+
+EFI_DRIVER_BINDING_PROTOCOL  gXhciDriverBinding = {
+  XhcDriverBindingSupported,
+  XhcDriverBindingStart,
+  XhcDriverBindingStop,
+  0x30,
+  NULL,
+  NULL
+};
+
+//
+// Template for Xhci's Usb2 Host Controller Protocol Instance.
+//
+EFI_USB2_HC_PROTOCOL gXhciUsb2HcTemplate = {
+  XhcGetCapability,
+  XhcReset,
+  XhcGetState,
+  XhcSetState,
+  XhcControlTransfer,
+  XhcBulkTransfer,
+  XhcAsyncInterruptTransfer,
+  XhcSyncInterruptTransfer,
+  XhcIsochronousTransfer,
+  XhcAsyncIsochronousTransfer,
+  XhcGetRootHubPortStatus,
+  XhcSetRootHubPortFeature,
+  XhcClearRootHubPortFeature,
+  0x3,
+  0x0
+};
+
+/**
+  Retrieves the capability of root hub ports.
+
+  @param  This                  The EFI_USB2_HC_PROTOCOL instance.
+  @param  MaxSpeed              Max speed supported by the controller.
+  @param  PortNumber            Number of the root hub ports.
+  @param  Is64BitCapable        Whether the controller supports 64-bit memory
+                                addressing.
+
+  @retval EFI_SUCCESS           Host controller capability were retrieved 
successfully.
+  @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcGetCapability (
+  IN  EFI_USB2_HC_PROTOCOL  *This,
+  OUT UINT8                 *MaxSpeed,
+  OUT UINT8                 *PortNumber,
+  OUT UINT8                 *Is64BitCapable
+  )
+{
+  USB_XHCI_INSTANCE  *Xhc;
+  EFI_TPL            OldTpl;
+
+  if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl          = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc             = XHC_FROM_THIS (This);
+  *MaxSpeed       = EFI_USB_SPEED_SUPER;
+  *PortNumber     = (UINT8) (Xhc->HcSParams1.Data.MaxPorts);
+  *Is64BitCapable = (UINT8) (Xhc->HcCParams.Data.Ac64);
+  DEBUG ((EFI_D_INFO, "XhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, 
*Is64BitCapable));
+
+  gBS->RestoreTPL (OldTpl);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Provides software reset for the USB host controller.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  Attributes            A bit mask of the reset operation to perform.
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
+                                not currently supported by the host controller.
+  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcReset (
+  IN EFI_USB2_HC_PROTOCOL  *This,
+  IN UINT16                Attributes
+  )
+{
+  USB_XHCI_INSTANCE  *Xhc;
+  EFI_STATUS         Status;
+  EFI_TPL            OldTpl;
+
+  Xhc = XHC_FROM_THIS (This);
+  
+  if (Xhc->DevicePath != NULL) {
+    //
+    // Report Status Code to indicate reset happens
+    //
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+      EFI_PROGRESS_CODE,
+      (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
+      Xhc->DevicePath
+      );
+  }  
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  switch (Attributes) {
+  case EFI_USB_HC_RESET_GLOBAL:
+  //
+  // Flow through, same behavior as Host Controller Reset
+  //
+  case EFI_USB_HC_RESET_HOST_CONTROLLER:
+    if ((Xhc->DebugCapSupOffset != 0xFFFFFFFF) && ((XhcReadExtCapReg (Xhc, 
Xhc->DebugCapSupOffset) & 0xFF) == XHC_CAP_USB_DEBUG) &&
+        ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & 
BIT0) != 0)) {
+      Status = EFI_SUCCESS;
+      goto ON_EXIT;
+    }
+    //
+    // Host Controller must be Halt when Reset it
+    //
+    if (!XhcIsHalt (Xhc)) {
+      Status = XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
+
+      if (EFI_ERROR (Status)) {
+        Status = EFI_DEVICE_ERROR;
+        goto ON_EXIT;
+      }
+    }
+
+    Status = XhcResetHC (Xhc, XHC_RESET_TIMEOUT);
+    ASSERT (!(XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_CNR)));
+
+    if (EFI_ERROR (Status)) {
+      goto ON_EXIT;
+    }
+    //
+    // Clean up the asynchronous transfers, currently only
+    // interrupt supports asynchronous operation.
+    //
+    XhciDelAllAsyncIntTransfers (Xhc);
+    XhcFreeSched (Xhc);
+
+    XhcInitSched (Xhc);
+    break;
+
+  case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:
+  case EFI_USB_HC_RESET_HOST_WITH_DEBUG:
+    Status = EFI_UNSUPPORTED;
+    break;
+
+  default:
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+ON_EXIT:
+  DEBUG ((EFI_D_INFO, "XhcReset: status %r\n", Status));
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Retrieve the current state of the USB host controller.
+
+  @param  This                   This EFI_USB2_HC_PROTOCOL instance.
+  @param  State                  Variable to return the current host controller
+                                 state.
+
+  @retval EFI_SUCCESS            Host controller state was returned in State.
+  @retval EFI_INVALID_PARAMETER  State is NULL.
+  @retval EFI_DEVICE_ERROR       An error was encountered while attempting to
+                                 retrieve the host controller's current state.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcGetState (
+  IN  EFI_USB2_HC_PROTOCOL  *This,
+  OUT EFI_USB_HC_STATE      *State
+  )
+{
+  USB_XHCI_INSTANCE  *Xhc;
+  EFI_TPL            OldTpl;
+
+  if (State == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc    = XHC_FROM_THIS (This);
+
+  if (XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {
+    *State = EfiUsbHcStateHalt;
+  } else {
+    *State = EfiUsbHcStateOperational;
+  }
+
+  DEBUG ((EFI_D_INFO, "XhcGetState: current state %d\n", *State));
+  gBS->RestoreTPL (OldTpl);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Sets the USB host controller to a specific state.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  State                 The state of the host controller that will be 
set.
+
+  @retval EFI_SUCCESS           The USB host controller was successfully placed
+                                in the state specified by State.
+  @retval EFI_INVALID_PARAMETER State is invalid.
+  @retval EFI_DEVICE_ERROR      Failed to set the state due to device error.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcSetState (
+  IN EFI_USB2_HC_PROTOCOL  *This,
+  IN EFI_USB_HC_STATE      State
+  )
+{
+  USB_XHCI_INSTANCE   *Xhc;
+  EFI_STATUS          Status;
+  EFI_USB_HC_STATE    CurState;
+  EFI_TPL             OldTpl;
+
+  Status = XhcGetState (This, &CurState);
+
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (CurState == State) {
+    return EFI_SUCCESS;
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc    = XHC_FROM_THIS (This);
+
+  switch (State) {
+  case EfiUsbHcStateHalt:
+    Status = XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
+    break;
+
+  case EfiUsbHcStateOperational:
+    if (XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE)) {
+      Status = EFI_DEVICE_ERROR;
+      break;
+    }
+
+    //
+    // Software must not write a one to this field unless the host controller
+    // is in the Halted state. Doing so will yield undefined results.
+    // refers to Spec[XHCI1.0-2.3.1]
+    //
+    if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {
+      Status = EFI_DEVICE_ERROR;
+      break;
+    }
+
+    Status = XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT);
+    break;
+
+  case EfiUsbHcStateSuspend:
+    Status = EFI_UNSUPPORTED;
+    break;
+
+  default:
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((EFI_D_INFO, "XhcSetState: status %r\n", Status));
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+/**
+  Retrieves the current status of a USB root hub port.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  PortNumber            The root hub port to retrieve the state from.
+                                This value is zero-based.
+  @param  PortStatus            Variable to receive the port state.
+
+  @retval EFI_SUCCESS           The status of the USB root hub port specified.
+                                by PortNumber was returned in PortStatus.
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid.
+  @retval EFI_DEVICE_ERROR      Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcGetRootHubPortStatus (
+  IN  EFI_USB2_HC_PROTOCOL  *This,
+  IN  UINT8                 PortNumber,
+  OUT EFI_USB_PORT_STATUS   *PortStatus
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  UINT32                  Offset;
+  UINT32                  State;
+  UINT32                  TotalPort;
+  UINTN                   Index;
+  UINTN                   MapSize;
+  EFI_STATUS              Status;
+  USB_DEV_ROUTE           ParentRouteChart;
+  EFI_TPL                 OldTpl;
+
+  if (PortStatus == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc       = XHC_FROM_THIS (This);
+  Status    = EFI_SUCCESS;
+
+  TotalPort = Xhc->HcSParams1.Data.MaxPorts;
+
+  if (PortNumber >= TotalPort) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ON_EXIT;
+  }
+
+  Offset                       = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * 
PortNumber));
+  PortStatus->PortStatus       = 0;
+  PortStatus->PortChangeStatus = 0;
+
+  State = XhcReadOpReg (Xhc, Offset);
+
+  //
+  // According to XHCI 1.0 spec, bit 10~13 of the root port status register 
identifies the speed of the attached device.
+  //
+  switch ((State & XHC_PORTSC_PS) >> 10) {
+  case 2:
+    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
+    break;
+
+  case 3:
+    PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;
+    break;
+
+  case 4:
+    PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED;
+    break;
+
+  default:
+    break;
+  }
+
+  //
+  // Convert the XHCI port/port change state to UEFI status
+  //
+  MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP);
+
+  for (Index = 0; Index < MapSize; Index++) {
+    if (XHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {
+      PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | 
mUsbPortStateMap[Index].UefiState);
+    }
+  }
+  //
+  // Bit5~8 reflects its current link state.
+  //
+  if ((State & XHC_PORTSC_PLS) >> 5 == 3) {
+    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+  }
+
+  MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP);
+
+  for (Index = 0; Index < MapSize; Index++) {
+    if (XHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {
+      PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | 
mUsbPortChangeMap[Index].UefiState);
+    }
+  }
+
+  MapSize = sizeof (mUsbClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);
+
+  for (Index = 0; Index < MapSize; Index++) {
+    if (XHC_BIT_IS_SET (State, mUsbClearPortChangeMap[Index].HwState)) {
+      XhcClearRootHubPortFeature (This, PortNumber, 
(EFI_USB_PORT_FEATURE)mUsbClearPortChangeMap[Index].Selector);
+    }
+  }
+
+  //
+  // Poll the root port status register to enable/disable corresponding device 
slot if there is a device attached/detached.
+  // For those devices behind hub, we get its attach/detach event by hooking 
Get_Port_Status request at control transfer for those hub.
+  //
+  ParentRouteChart.Dword = 0;
+  XhcPollPortStatusChange (Xhc, ParentRouteChart, PortNumber, PortStatus);
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+
+/**
+  Sets a feature for the specified root hub port.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  PortNumber            Root hub port to set.
+  @param  PortFeature           Feature to set.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was set.
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is 
invalid.
+  @retval EFI_DEVICE_ERROR      Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcSetRootHubPortFeature (
+  IN EFI_USB2_HC_PROTOCOL  *This,
+  IN UINT8                 PortNumber,
+  IN EFI_USB_PORT_FEATURE  PortFeature
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  UINT32                  Offset;
+  UINT32                  State;
+  UINT32                  TotalPort;
+  EFI_STATUS              Status;
+  EFI_TPL                 OldTpl;
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc    = XHC_FROM_THIS (This);
+  Status = EFI_SUCCESS;
+
+  TotalPort = (Xhc->HcSParams1.Data.MaxPorts);
+
+  if (PortNumber >= TotalPort) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ON_EXIT;
+  }
+
+  Offset = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * PortNumber));
+  State  = XhcReadOpReg (Xhc, Offset);
+
+  //
+  // Mask off the port status change bits, these bits are
+  // write clean bit
+  //
+  State &= ~ (BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23);
+
+  switch (PortFeature) {
+  case EfiUsbPortEnable:
+    //
+    // Ports may only be enabled by the xHC. Software cannot enable a port by 
writing a '1' to this flag.
+    // A port may be disabled by software writing a '1' to this flag.
+    //
+    Status = EFI_SUCCESS;
+    break;
+
+  case EfiUsbPortSuspend:
+    State |= XHC_PORTSC_LWS;
+    XhcWriteOpReg (Xhc, Offset, State);
+    State &= ~XHC_PORTSC_PLS;
+    State |= (3 << 5) ;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortReset:
+    DEBUG ((EFI_D_INFO, "XhcUsbPortReset!\n"));
+    //
+    // Make sure Host Controller not halt before reset it
+    //
+    if (XhcIsHalt (Xhc)) {
+      Status = XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT);
+
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_INFO, "XhcSetRootHubPortFeature :failed to start HC - 
%r\n", Status));
+        break;
+      }
+    }
+
+    //
+    // 4.3.1 Resetting a Root Hub Port
+    // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'.
+    //
+    State |= XHC_PORTSC_RESET;
+    XhcWriteOpReg (Xhc, Offset, State);
+    XhcWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT);
+    break;
+
+  case EfiUsbPortPower:
+    //
+    // Not supported, ignore the operation
+    //
+    Status = EFI_SUCCESS;
+    break;
+
+  case EfiUsbPortOwner:
+    //
+    // XHCI root hub port don't has the owner bit, ignore the operation
+    //
+    Status = EFI_SUCCESS;
+    break;
+
+  default:
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+ON_EXIT:
+  DEBUG ((EFI_D_INFO, "XhcSetRootHubPortFeature: status %r\n", Status));
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Clears a feature for the specified root hub port.
+
+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
+  @param  PortNumber            Specifies the root hub port whose feature is
+                                requested to be cleared.
+  @param  PortFeature           Indicates the feature selector associated with 
the
+                                feature clear request.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was 
cleared
+                                for the USB root hub port specified by 
PortNumber.
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is 
invalid.
+  @retval EFI_DEVICE_ERROR      Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcClearRootHubPortFeature (
+  IN EFI_USB2_HC_PROTOCOL  *This,
+  IN UINT8                 PortNumber,
+  IN EFI_USB_PORT_FEATURE  PortFeature
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  UINT32                  Offset;
+  UINT32                  State;
+  UINT32                  TotalPort;
+  EFI_STATUS              Status;
+  EFI_TPL                 OldTpl;
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc       = XHC_FROM_THIS (This);
+  Status    = EFI_SUCCESS;
+
+  TotalPort = (Xhc->HcSParams1.Data.MaxPorts);
+
+  if (PortNumber >= TotalPort) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ON_EXIT;
+  }
+
+  Offset = XHC_PORTSC_OFFSET + (0x10 * PortNumber);
+
+  //
+  // Mask off the port status change bits, these bits are
+  // write clean bit
+  //
+  State  = XhcReadOpReg (Xhc, Offset);
+  State &= ~ (BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23);
+
+  switch (PortFeature) {
+  case EfiUsbPortEnable:
+    //
+    // Ports may only be enabled by the xHC. Software cannot enable a port by 
writing a '1' to this flag.
+    // A port may be disabled by software writing a '1' to this flag.
+    //
+    State |= XHC_PORTSC_PED;
+    State &= ~XHC_PORTSC_RESET;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortSuspend:
+    State |= XHC_PORTSC_LWS;
+    XhcWriteOpReg (Xhc, Offset, State);
+    State &= ~XHC_PORTSC_PLS;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortReset:
+    //
+    // PORTSC_RESET BIT(4) bit is RW1S attribute, which means Write-1-to-set 
status:
+    // Register bits indicate status when read, a clear bit may be set by
+    // writing a '1'. Writing a '0' to RW1S bits has no effect.
+    //
+    break;
+
+  case EfiUsbPortOwner:
+    //
+    // XHCI root hub port don't has the owner bit, ignore the operation
+    //
+    break;
+
+  case EfiUsbPortConnectChange:
+    //
+    // Clear connect status change
+    //
+    State |= XHC_PORTSC_CSC;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortEnableChange:
+    //
+    // Clear enable status change
+    //
+    State |= XHC_PORTSC_PEC;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortOverCurrentChange:
+    //
+    // Clear PortOverCurrent change
+    //
+    State |= XHC_PORTSC_OCC;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortResetChange:
+    //
+    // Clear Port Reset change
+    //
+    State |= XHC_PORTSC_PRC;
+    XhcWriteOpReg (Xhc, Offset, State);
+    break;
+
+  case EfiUsbPortPower:
+  case EfiUsbPortSuspendChange:
+    //
+    // Not supported or not related operation
+    //
+    break;
+
+  default:
+    Status = EFI_INVALID_PARAMETER;
+    break;
+  }
+
+ON_EXIT:
+  DEBUG ((EFI_D_INFO, "XhcClearRootHubPortFeature: status %r\n", Status));
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Submits control transfer to a target USB device.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  DeviceAddress         The target device address.
+  @param  DeviceSpeed           Target device speed.
+  @param  MaximumPacketLength   Maximum packet size the default control 
transfer
+                                endpoint is capable of sending or receiving.
+  @param  Request               USB device request to send.
+  @param  TransferDirection     Specifies the data direction for the data stage
+  @param  Data                  Data buffer to be transmitted or received from 
USB
+                                device.
+  @param  DataLength            The size (in bytes) of the data buffer.
+  @param  Timeout               Indicates the maximum timeout, in millisecond.
+  @param  Translator            Transaction translator to be used by this 
device.
+  @param  TransferResult        Return the result of this control transfer.
+
+  @retval EFI_SUCCESS           Transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resources.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_TIMEOUT           Transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      Transfer failed due to host controller or 
device error.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcControlTransfer (
+  IN     EFI_USB2_HC_PROTOCOL                *This,
+  IN     UINT8                               DeviceAddress,
+  IN     UINT8                               DeviceSpeed,
+  IN     UINTN                               MaximumPacketLength,
+  IN     EFI_USB_DEVICE_REQUEST              *Request,
+  IN     EFI_USB_DATA_DIRECTION              TransferDirection,
+  IN OUT VOID                                *Data,
+  IN OUT UINTN                               *DataLength,
+  IN     UINTN                               Timeout,
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
+  OUT    UINT32                              *TransferResult
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
+  UINT8                   Endpoint;
+  UINT8                   Index;
+  UINT8                   DescriptorType;
+  UINT8                   SlotId;
+  UINT8                   TTT;
+  UINT8                   MTT;
+  UINT32                  MaxPacket0;
+  EFI_USB_HUB_DESCRIPTOR  *HubDesc;
+  EFI_TPL                 OldTpl;
+  EFI_STATUS              Status;
+  EFI_STATUS              RecoveryStatus;
+  UINTN                   MapSize;
+  EFI_USB_PORT_STATUS     PortStatus;
+  UINT32                  State;
+  EFI_USB_DEVICE_REQUEST  ClearPortRequest;
+  UINTN                   Len;
+
+  //
+  // Validate parameters
+  //
+  if ((Request == NULL) || (TransferResult == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((TransferDirection != EfiUsbDataIn) &&
+      (TransferDirection != EfiUsbDataOut) &&
+      (TransferDirection != EfiUsbNoData)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((TransferDirection == EfiUsbNoData) &&
+      ((Data != NULL) || (*DataLength != 0))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((TransferDirection != EfiUsbNoData) &&
+     ((Data == NULL) || (*DataLength == 0))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((MaximumPacketLength != 8)  && (MaximumPacketLength != 16) &&
+      (MaximumPacketLength != 32) && (MaximumPacketLength != 64) &&
+      (MaximumPacketLength != 512)
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((DeviceSpeed == EFI_USB_SPEED_SUPER) && (MaximumPacketLength != 512)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc             = XHC_FROM_THIS (This);
+
+  Status          = EFI_DEVICE_ERROR;
+  *TransferResult = EFI_USB_ERR_SYSTEM;
+  Len             = 0;
+
+  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
+    DEBUG ((EFI_D_ERROR, "XhcControlTransfer: HC halted at entrance\n"));
+    goto ON_EXIT;
+  }
+
+  //
+  // Check if the device is still enabled before every transaction.
+  //
+  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
+  if (SlotId == 0) {
+    goto ON_EXIT;
+  }
+
+  //
+  // Hook the Set_Address request from UsbBus.
+  // According to XHCI 1.0 spec, the Set_Address request is replaced by XHCI's 
Address_Device cmd.
+  //
+  if ((Request->Request     == USB_REQ_SET_ADDRESS) &&
+      (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, 
USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) {
+    //
+    // Reset the BusDevAddr field of all disabled entries in UsbDevContext 
array firstly.
+    // This way is used to clean the history to avoid using wrong device 
address by XhcAsyncInterruptTransfer().
+    //
+    for (Index = 0; Index < 255; Index++) {
+      if (!Xhc->UsbDevContext[Index + 1].Enabled &&
+          (Xhc->UsbDevContext[Index + 1].SlotId == 0) &&
+          (Xhc->UsbDevContext[Index + 1].BusDevAddr == (UINT8)Request->Value)) 
{
+        Xhc->UsbDevContext[Index + 1].BusDevAddr = 0;
+      }
+    }
+
+    if (Xhc->UsbDevContext[SlotId].XhciDevAddr == 0) {
+      Status = EFI_DEVICE_ERROR;
+      goto ON_EXIT;
+    }
+    //
+    // The actual device address has been assigned by XHCI during initializing 
the device slot.
+    // So we just need establish the mapping relationship between the device 
address requested from UsbBus
+    // and the actual device address assigned by XHCI. The the following 
invocations through EFI_USB2_HC_PROTOCOL interface
+    // can find out the actual device address by it.
+    //
+    Xhc->UsbDevContext[SlotId].BusDevAddr = (UINT8)Request->Value;
+    Status = EFI_SUCCESS;
+    goto ON_EXIT;
+  }
+
+  //
+  // Create a new URB, insert it into the asynchronous
+  // schedule list, then poll the execution status.
+  // Note that we encode the direction in address although default control
+  // endpoint is bidirectional. XhcCreateUrb expects this
+  // combination of Ep addr and its direction.
+  //
+  Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          Endpoint,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_CTRL_TRANSFER,
+          Request,
+          Data,
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((EFI_D_ERROR, "XhcControlTransfer: failed to create URB"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  //
+  // Get the status from URB. The result is updated in XhcCheckUrbResult
+  // which is called by XhcExecTransfer
+  //
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if ((*TransferResult == EFI_USB_ERR_STALL) || (*TransferResult == 
EFI_USB_ERR_BABBLE)) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_ERROR, "XhcControlTransfer: XhcRecoverHaltedEndpoint 
failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+    goto FREE_URB;
+  } else {
+    goto FREE_URB;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  
+  if (Urb->DataMap != NULL) {
+    Status = Xhc->PciIo->Unmap (Xhc->PciIo, Urb->DataMap);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto FREE_URB;
+    }  
+  }
+
+  //
+  // Hook Get_Descriptor request from UsbBus as we need evaluate context and 
configure endpoint.
+  // Hook Get_Status request form UsbBus as we need trace device attach/detach 
event happened at hub.
+  // Hook Set_Config request from UsbBus as we need configure device endpoint.
+  //
+  if ((Request->Request     == USB_REQ_GET_DESCRIPTOR) &&
+      ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, 
USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE)) || 
+      ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, 
USB_REQ_TYPE_CLASS, USB_TARGET_DEVICE))))) {
+    DescriptorType = (UINT8)(Request->Value >> 8);
+    if ((DescriptorType == USB_DESC_TYPE_DEVICE) && ((*DataLength == sizeof 
(EFI_USB_DEVICE_DESCRIPTOR)) || ((DeviceSpeed == EFI_USB_SPEED_FULL) && 
(*DataLength == 8)))) {
+        ASSERT (Data != NULL);
+        //
+        // Store a copy of device scriptor as hub device need this info to 
configure endpoint.
+        //
+        CopyMem (&Xhc->UsbDevContext[SlotId].DevDesc, Data, *DataLength);
+        if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB == 0x0300) {
+          //
+          // If it's a usb3.0 device, then its max packet size is a 2^n.
+          //
+          MaxPacket0 = 1 << Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
+        } else {
+          MaxPacket0 = Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0;
+        }
+        Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool 
(Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof 
(EFI_USB_CONFIG_DESCRIPTOR *));
+        if (Xhc->HcCParams.Data.Csz == 0) {
+          Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
+        } else {
+          Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0);
+        }
+    } else if (DescriptorType == USB_DESC_TYPE_CONFIG) {
+      ASSERT (Data != NULL);
+      if (*DataLength == ((UINT16 *)Data)[1]) {
+        //
+        // Get configuration value from request, Store the configuration 
descriptor for Configure_Endpoint cmd.
+        //
+        Index = (UINT8)Request->Value;
+        ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);
+        Xhc->UsbDevContext[SlotId].ConfDesc[Index] = 
AllocateZeroPool(*DataLength);
+        CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, 
*DataLength);
+        //
+        // Default to use AlternateSetting 0 for all interfaces.
+        //
+        Xhc->UsbDevContext[SlotId].ActiveAlternateSetting = AllocateZeroPool 
(Xhc->UsbDevContext[SlotId].ConfDesc[Index]->NumInterfaces * sizeof (UINT8));
+      }
+    } else if (((DescriptorType == USB_DESC_TYPE_HUB) ||
+               (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && 
(*DataLength > 2)) {
+      ASSERT (Data != NULL);
+      HubDesc = (EFI_USB_HUB_DESCRIPTOR *)Data;
+      ASSERT (HubDesc->NumPorts <= 15);
+      //
+      // The bit 5,6 of HubCharacter field of Hub Descriptor is TTT.
+      //
+      TTT = (UINT8)((HubDesc->HubCharacter & (BIT5 | BIT6)) >> 5);
+      if (Xhc->UsbDevContext[SlotId].DevDesc.DeviceProtocol == 2) {
+        //
+        // Don't support multi-TT feature for super speed hub now.
+        //
+        MTT = 0;
+        DEBUG ((EFI_D_ERROR, "XHCI: Don't support multi-TT feature for Hub 
now. (force to disable MTT)\n"));
+      } else {
+        MTT = 0;
+      }
+
+      if (Xhc->HcCParams.Data.Csz == 0) {
+        Status = XhcConfigHubContext (Xhc, SlotId, HubDesc->NumPorts, TTT, 
MTT);
+      } else {
+        Status = XhcConfigHubContext64 (Xhc, SlotId, HubDesc->NumPorts, TTT, 
MTT);
+      }
+    }
+  } else if ((Request->Request     == USB_REQ_SET_CONFIG) &&
+             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, 
USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) {
+    //
+    // Hook Set_Config request from UsbBus as we need configure device 
endpoint.
+    //
+    for (Index = 0; Index < 
Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
+      if (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->ConfigurationValue == 
(UINT8)Request->Value) {
+        if (Xhc->HcCParams.Data.Csz == 0) {
+          Status = XhcSetConfigCmd (Xhc, SlotId, DeviceSpeed, 
Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
+        } else {
+          Status = XhcSetConfigCmd64 (Xhc, SlotId, DeviceSpeed, 
Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
+        }
+        break;
+      }
+    }
+  } else if ((Request->Request     == USB_REQ_SET_INTERFACE) &&
+             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, 
USB_REQ_TYPE_STANDARD, USB_TARGET_INTERFACE))) {
+    //
+    // Hook Set_Interface request from UsbBus as we need configure interface 
setting.
+    // Request->Value indicates AlterlateSetting to set
+    // Request->Index indicates Interface to set
+    //
+    if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) 
Request->Index] != (UINT8) Request->Value) {
+      if (Xhc->HcCParams.Data.Csz == 0) {
+        Status = XhcSetInterface (Xhc, SlotId, DeviceSpeed, 
Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration
 - 1], Request);
+      } else {
+        Status = XhcSetInterface64 (Xhc, SlotId, DeviceSpeed, 
Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration
 - 1], Request);
+      }
+    }
+  } else if ((Request->Request     == USB_REQ_GET_STATUS) &&
+             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, 
USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) {
+    ASSERT (Data != NULL);
+    //
+    // Hook Get_Status request from UsbBus to keep track of the port status 
change.
+    //
+    State                       = *(UINT32 *)Data;
+    PortStatus.PortStatus       = 0;
+    PortStatus.PortChangeStatus = 0;
+
+    if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
+      //
+      // For super speed hub, its bit10~12 presents the attached device speed.
+      //
+      if ((State & XHC_PORTSC_PS) >> 10 == 0) {
+        PortStatus.PortStatus |= USB_PORT_STAT_SUPER_SPEED;
+      }
+    } else {
+      //
+      // For high or full/low speed hub, its bit9~10 presents the attached 
device speed.
+      //
+      if (XHC_BIT_IS_SET (State, BIT9)) {
+        PortStatus.PortStatus |= USB_PORT_STAT_LOW_SPEED;
+      } else if (XHC_BIT_IS_SET (State, BIT10)) {
+        PortStatus.PortStatus |= USB_PORT_STAT_HIGH_SPEED;
+      }
+    }
+
+    //
+    // Convert the XHCI port/port change state to UEFI status
+    //
+    MapSize = sizeof (mUsbHubPortStateMap) / sizeof (USB_PORT_STATE_MAP);
+    for (Index = 0; Index < MapSize; Index++) {
+      if (XHC_BIT_IS_SET (State, mUsbHubPortStateMap[Index].HwState)) {
+        PortStatus.PortStatus = (UINT16) (PortStatus.PortStatus | 
mUsbHubPortStateMap[Index].UefiState);
+      }
+    }
+
+    MapSize = sizeof (mUsbHubPortChangeMap) / sizeof (USB_PORT_STATE_MAP);
+    for (Index = 0; Index < MapSize; Index++) {
+      if (XHC_BIT_IS_SET (State, mUsbHubPortChangeMap[Index].HwState)) {
+        PortStatus.PortChangeStatus = (UINT16) (PortStatus.PortChangeStatus | 
mUsbHubPortChangeMap[Index].UefiState);
+      }
+    }
+
+    MapSize = sizeof (mUsbHubClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);
+
+    for (Index = 0; Index < MapSize; Index++) {
+      if (XHC_BIT_IS_SET (State, mUsbHubClearPortChangeMap[Index].HwState)) {
+        ZeroMem (&ClearPortRequest, sizeof (EFI_USB_DEVICE_REQUEST));
+        ClearPortRequest.RequestType  = USB_REQUEST_TYPE (EfiUsbNoData, 
USB_REQ_TYPE_CLASS, USB_TARGET_OTHER);
+        ClearPortRequest.Request      = (UINT8) USB_REQ_CLEAR_FEATURE;
+        ClearPortRequest.Value        = 
mUsbHubClearPortChangeMap[Index].Selector;
+        ClearPortRequest.Index        = Request->Index;
+        ClearPortRequest.Length       = 0;
+
+        XhcControlTransfer (
+          This, 
+          DeviceAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          &ClearPortRequest,
+          EfiUsbNoData,
+          NULL,
+          &Len,
+          Timeout,
+          Translator,
+          TransferResult
+          );
+      }
+    }
+
+    XhcPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, 
(UINT8)Request->Index, &PortStatus);
+
+    *(UINT32 *)Data = *(UINT32*)&PortStatus;
+  }
+
+FREE_URB:
+  FreePool (Urb);
+
+ON_EXIT:
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "XhcControlTransfer: error - %r, transfer - %x\n", 
Status, *TransferResult));
+  }
+
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Submits bulk transfer to a bulk endpoint of a USB device.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  DeviceAddress         Target device address.
+  @param  EndPointAddress       Endpoint number and its direction in bit 7.
+  @param  DeviceSpeed           Device speed, Low speed device doesn't support 
bulk
+                                transfer.
+  @param  MaximumPacketLength   Maximum packet size the endpoint is capable of
+                                sending or receiving.
+  @param  DataBuffersNumber     Number of data buffers prepared for the 
transfer.
+  @param  Data                  Array of pointers to the buffers of data to 
transmit
+                                from or receive into.
+  @param  DataLength            The lenght of the data buffer.
+  @param  DataToggle            On input, the initial data toggle for the 
transfer;
+                                On output, it is updated to to next data 
toggle to
+                                use of the subsequent bulk transfer.
+  @param  Timeout               Indicates the maximum time, in millisecond, 
which
+                                the transfer is allowed to complete.
+  @param  Translator            A pointr to the transaction translator data.
+  @param  TransferResult        A pointer to the detailed result information 
of the
+                                bulk transfer.
+
+  @retval EFI_SUCCESS           The transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_TIMEOUT           The transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller 
error.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcBulkTransfer (
+  IN     EFI_USB2_HC_PROTOCOL                *This,
+  IN     UINT8                               DeviceAddress,
+  IN     UINT8                               EndPointAddress,
+  IN     UINT8                               DeviceSpeed,
+  IN     UINTN                               MaximumPacketLength,
+  IN     UINT8                               DataBuffersNumber,
+  IN OUT VOID                                
*Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+  IN OUT UINTN                               *DataLength,
+  IN OUT UINT8                               *DataToggle,
+  IN     UINTN                               Timeout,
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
+  OUT    UINT32                              *TransferResult
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
+  UINT8                   SlotId;
+  EFI_STATUS              Status;
+  EFI_STATUS              RecoveryStatus;
+  EFI_TPL                 OldTpl;
+
+  //
+  // Validate the parameters
+  //
+  if ((DataLength == NULL) || (*DataLength == 0) ||
+      (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((*DataToggle != 0) && (*DataToggle != 1)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||
+      ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||
+      ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512)) ||
+      ((EFI_USB_SPEED_SUPER == DeviceSpeed) && (MaximumPacketLength > 1024))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc             = XHC_FROM_THIS (This);
+
+  *TransferResult = EFI_USB_ERR_SYSTEM;
+  Status          = EFI_DEVICE_ERROR;
+
+  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
+    DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: HC is halted\n"));
+    goto ON_EXIT;
+  }
+
+  //
+  // Check if the device is still enabled before every transaction.
+  //
+  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
+  if (SlotId == 0) {
+    goto ON_EXIT;
+  }
+
+  //
+  // Create a new URB, insert it into the asynchronous
+  // schedule list, then poll the execution status.
+  //
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_BULK_TRANSFER,
+          NULL,
+          Data[0],
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: failed to create URB\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: XhcRecoverHaltedEndpoint 
failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
+
+ON_EXIT:
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: error - %r, transfer - %x\n", 
Status, *TransferResult));
+  }
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+/**
+  Submits an asynchronous interrupt transfer to an
+  interrupt endpoint of a USB device.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  DeviceAddress         Target device address.
+  @param  EndPointAddress       Endpoint number and its direction encoded in 
bit 7
+  @param  DeviceSpeed           Indicates device speed.
+  @param  MaximumPacketLength   Maximum packet size the target endpoint is 
capable
+  @param  IsNewTransfer         If TRUE, to submit an new asynchronous 
interrupt
+                                transfer If FALSE, to remove the specified
+                                asynchronous interrupt.
+  @param  DataToggle            On input, the initial data toggle to use; on 
output,
+                                it is updated to indicate the next data toggle.
+  @param  PollingInterval       The he interval, in milliseconds, that the 
transfer
+                                is polled.
+  @param  DataLength            The length of data to receive at the rate 
specified
+                                by  PollingInterval.
+  @param  Translator            Transaction translator to use.
+  @param  CallBackFunction      Function to call at the rate specified by
+                                PollingInterval.
+  @param  Context               Context to CallBackFunction.
+
+  @retval EFI_SUCCESS           The request has been successfully submitted or 
canceled.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The request failed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller 
error.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcAsyncInterruptTransfer (
+  IN     EFI_USB2_HC_PROTOCOL                *This,
+  IN     UINT8                               DeviceAddress,
+  IN     UINT8                               EndPointAddress,
+  IN     UINT8                               DeviceSpeed,
+  IN     UINTN                               MaximumPacketLength,
+  IN     BOOLEAN                             IsNewTransfer,
+  IN OUT UINT8                               *DataToggle,
+  IN     UINTN                               PollingInterval,
+  IN     UINTN                               DataLength,
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction,
+  IN     VOID                                *Context OPTIONAL
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
+  EFI_STATUS              Status;
+  UINT8                   SlotId;
+  UINT8                   Index;
+  UINT8                   *Data;
+  EFI_TPL                 OldTpl;
+
+  //
+  // Validate parameters
+  //
+  if (!XHCI_IS_DATAIN (EndPointAddress)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IsNewTransfer) {
+    if (DataLength == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if ((*DataToggle != 1) && (*DataToggle != 0)) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if ((PollingInterval > 255) || (PollingInterval < 1)) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc    = XHC_FROM_THIS (This);
+
+  //
+  // Delete Async interrupt transfer request.
+  //
+  if (!IsNewTransfer) {
+    //
+    // The delete request may happen after device is detached.
+    //
+    for (Index = 0; Index < 255; Index++) {
+      if (Xhc->UsbDevContext[Index + 1].BusDevAddr == DeviceAddress) {
+        break;
+      }
+    }
+
+    if (Index == 255) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = XhciDelAsyncIntTransfer (Xhc, DeviceAddress, EndPointAddress);
+    DEBUG ((EFI_D_INFO, "XhcAsyncInterruptTransfer: remove old transfer for 
addr %d, Status = %r\n", DeviceAddress, Status));
+    goto ON_EXIT;
+  }
+
+  Status = EFI_SUCCESS;
+
+  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
+    DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: HC is halt\n"));
+    Status = EFI_DEVICE_ERROR;
+    goto ON_EXIT;
+  }
+
+  //
+  // Check if the device is still enabled before every transaction.
+  //
+  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
+  if (SlotId == 0) {
+    goto ON_EXIT;
+  }
+
+  Data = AllocateZeroPool (DataLength);
+
+  if (Data == NULL) {
+    DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: failed to allocate 
buffer\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_INT_TRANSFER_ASYNC,
+          NULL,
+          Data,
+          DataLength,
+          CallBackFunction,
+          Context
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: failed to create URB\n"));
+    FreePool (Data);
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  InsertHeadList (&Xhc->AsyncIntTransfers, &Urb->UrbList);
+  //
+  // Ring the doorbell
+  //
+  Status = RingIntTransferDoorBell (Xhc, Urb);
+
+ON_EXIT:
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Submits synchronous interrupt transfer to an interrupt endpoint
+  of a USB device.
+
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
+  @param  DeviceAddress         Target device address.
+  @param  EndPointAddress       Endpoint number and its direction encoded in 
bit 7
+  @param  DeviceSpeed           Indicates device speed.
+  @param  MaximumPacketLength   Maximum packet size the target endpoint is 
capable
+                                of sending or receiving.
+  @param  Data                  Buffer of data that will be transmitted to  USB
+                                device or received from USB device.
+  @param  DataLength            On input, the size, in bytes, of the data 
buffer; On
+                                output, the number of bytes transferred.
+  @param  DataToggle            On input, the initial data toggle to use; on 
output,
+                                it is updated to indicate the next data toggle.
+  @param  Timeout               Maximum time, in second, to complete.
+  @param  Translator            Transaction translator to use.
+  @param  TransferResult        Variable to receive the transfer result.
+
+  @return EFI_SUCCESS           The transfer was completed successfully.
+  @return EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
+  @return EFI_INVALID_PARAMETER Some parameters are invalid.
+  @return EFI_TIMEOUT           The transfer failed due to timeout.
+  @return EFI_DEVICE_ERROR      The failed due to host controller or device 
error
+
+**/
+EFI_STATUS
+EFIAPI
+XhcSyncInterruptTransfer (
+  IN     EFI_USB2_HC_PROTOCOL                *This,
+  IN     UINT8                               DeviceAddress,
+  IN     UINT8                               EndPointAddress,
+  IN     UINT8                               DeviceSpeed,
+  IN     UINTN                               MaximumPacketLength,
+  IN OUT VOID                                *Data,
+  IN OUT UINTN                               *DataLength,
+  IN OUT UINT8                               *DataToggle,
+  IN     UINTN                               Timeout,
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
+  OUT    UINT32                              *TransferResult
+  )
+{
+  USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
+  UINT8                   SlotId;
+  EFI_STATUS              Status;
+  EFI_STATUS              RecoveryStatus;
+  EFI_TPL                 OldTpl;
+
+  //
+  // Validates parameters
+  //
+  if ((DataLength == NULL) || (*DataLength == 0) ||
+      (Data == NULL) || (TransferResult == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!XHCI_IS_DATAIN (EndPointAddress)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((*DataToggle != 1) && (*DataToggle != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8))  ||
+      ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||
+      ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+  Xhc     = XHC_FROM_THIS (This);
+
+  *TransferResult = EFI_USB_ERR_SYSTEM;
+  Status          = EFI_DEVICE_ERROR;
+
+  if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
+    DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));
+    goto ON_EXIT;
+  }
+
+  //
+  // Check if the device is still enabled before every transaction.
+  //
+  SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress);
+  if (SlotId == 0) {
+    goto ON_EXIT;
+  }
+
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_INT_TRANSFER_SYNC,
+          NULL,
+          Data,
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: failed to create URB\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: XhcRecoverHaltedEndpoint 
failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
+
+ON_EXIT:
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: error - %r, transfer - 
%x\n", Status, *TransferResult));
+  }
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Submits isochronous transfer to a target USB device.
+
+  @param  This                 This EFI_USB2_HC_PROTOCOL instance.
+  @param  DeviceAddress        Target device address.
+  @param  EndPointAddress      End point address with its direction.
+  @param  DeviceSpeed          Device speed, Low speed device doesn't support 
this
+                               type.
+  @param  MaximumPacketLength  Maximum packet size that the endpoint is 
capable of
+                               sending or receiving.
+  @param  DataBuffersNumber    Number of data buffers prepared for the 
transfer.
+  @param  Data                 Array of pointers to the buffers of data that 
will
+                               be transmitted to USB device or received from 
USB
+                               device.
+  @param  DataLength           The size, in bytes, of the data buffer.
+  @param  Translator           Transaction translator to use.
+  @param  TransferResult       Variable to receive the transfer result.
+
+  @return EFI_UNSUPPORTED      Isochronous transfer is unsupported.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcIsochronousTransfer (
+  IN     EFI_USB2_HC_PROTOCOL                *This,
+  IN     UINT8                               DeviceAddress,
+  IN     UINT8                               EndPointAddress,
+  IN     UINT8                               DeviceSpeed,
+  IN     UINTN                               MaximumPacketLength,
+  IN     UINT8                               DataBuffersNumber,
+  IN OUT VOID                                *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+  IN     UINTN                               DataLength,
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
+  OUT    UINT32                              *TransferResult
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Submits Async isochronous transfer to a target USB device.
+
+  @param  This                 This EFI_USB2_HC_PROTOCOL instance.
+  @param  DeviceAddress        Target device address.
+  @param  EndPointAddress      End point address with its direction.
+  @param  DeviceSpeed          Device speed, Low speed device doesn't support 
this
+                               type.
+  @param  MaximumPacketLength  Maximum packet size that the endpoint is 
capable of
+                               sending or receiving.
+  @param  DataBuffersNumber    Number of data buffers prepared for the 
transfer.
+  @param  Data                 Array of pointers to the buffers of data that 
will
+                               be transmitted to USB device or received from 
USB
+                               device.
+  @param  DataLength           The size, in bytes, of the data buffer.
+  @param  Translator           Transaction translator to use.
+  @param  IsochronousCallBack  Function to be called when the transfer 
complete.
+  @param  Context              Context passed to the call back function as
+                               parameter.
+
+  @return EFI_UNSUPPORTED      Isochronous transfer isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcAsyncIsochronousTransfer (
+  IN     EFI_USB2_HC_PROTOCOL                *This,
+  IN     UINT8                               DeviceAddress,
+  IN     UINT8                               EndPointAddress,
+  IN     UINT8                               DeviceSpeed,
+  IN     UINTN                               MaximumPacketLength,
+  IN     UINT8                               DataBuffersNumber,
+  IN OUT VOID                                *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+  IN     UINTN                               DataLength,
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,
+  IN     VOID                                *Context
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Entry point for EFI drivers.
+
+  @param  ImageHandle       EFI_HANDLE.
+  @param  SystemTable       EFI_SYSTEM_TABLE.
+
+  @retval EFI_SUCCESS       Success.
+  @retval Others            Fail.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcDriverEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &gXhciDriverBinding,
+           ImageHandle,
+           &gXhciComponentName,
+           &gXhciComponentName2
+           );
+}
+
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has Usb2HcProtocol installed will
+  be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+XhcDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,
+  IN EFI_HANDLE                  Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  USB_CLASSC              UsbClassCReg;
+
+  //
+  // Test whether there is PCI IO Protocol attached on the controller handle.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_CLASSCODE_OFFSET,
+                        sizeof (USB_CLASSC) / sizeof (UINT8),
+                        &UsbClassCReg
+                        );
+
+  if (EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
+
+  //
+  // Test whether the controller belongs to Xhci type
+  //
+  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
+      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
+      (UsbClassCReg.ProgInterface != PCI_IF_XHCI)) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return Status;
+}
+
+/**
+  Create and initialize a USB_XHCI_INSTANCE structure.
+
+  @param  PciIo                  The PciIo on this device.
+  @param  DevicePath             The device path of host controller.
+  @param  OriginalPciAttributes  Original PCI attributes.
+
+  @return The allocated and initialized USB_XHCI_INSTANCE structure if created,
+          otherwise NULL.
+
+**/

@@ Diff output truncated at 100000 characters. @@

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to