]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
Retiring the ANT/JAVA build and removing the older EDK II packages that required...
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / Uhci / Dxe / uhchlp.c
diff --git a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
deleted file mode 100644 (file)
index 2abc410..0000000
+++ /dev/null
@@ -1,4206 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-    UhcHlp.c\r
-    \r
-Abstract: \r
-    \r
-\r
-Revision History\r
---*/\r
-\r
-#include "uhci.h"\r
-\r
-STATIC\r
-EFI_STATUS\r
-USBReadPortW (\r
-  IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN       UINT32                  PortOffset,\r
-  IN OUT   UINT16                  *Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  USBReadPort Word\r
-\r
-Arguments:\r
-\r
-  PciIo       - EFI_PCI_IO_PROTOCOL\r
-  PortOffset  - Port offset\r
-  Data        - Data to reutrn\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Perform 16bit Read in PCI IO Space\r
-  //\r
-  return PciIo->Io.Read (\r
-                     PciIo,\r
-                     EfiPciIoWidthUint16,\r
-                     USB_BAR_INDEX,\r
-                     (UINT64) PortOffset,\r
-                     1,\r
-                     Data\r
-                     );\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-USBWritePortW (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  PortOffset,\r
-  IN UINT16                  Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  USB Write Port Word\r
-\r
-Arguments:\r
-\r
-  PciIo       - EFI_PCI_IO_PROTOCOL\r
-  PortOffset  - Port offset\r
-  Data        - Data to write\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Perform 16bit Write in PCI IO Space\r
-  //\r
-  return PciIo->Io.Write (\r
-                     PciIo,\r
-                     EfiPciIoWidthUint16,\r
-                     USB_BAR_INDEX,\r
-                     (UINT64) PortOffset,\r
-                     1,\r
-                     &Data\r
-                     );\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-USBWritePortDW (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  PortOffset,\r
-  IN UINT32                  Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  USB Write Port DWord\r
-\r
-Arguments:\r
-\r
-  PciIo       - EFI_PCI_IO_PROTOCOL\r
-  PortOffset  - Port offset\r
-  Data        - Data to write\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Perform 32bit Write in PCI IO Space\r
-  //\r
-  return PciIo->Io.Write (\r
-                     PciIo,\r
-                     EfiPciIoWidthUint32,\r
-                     USB_BAR_INDEX,\r
-                     (UINT64) PortOffset,\r
-                     1,\r
-                     &Data\r
-                     );\r
-}\r
-//\r
-//  USB register-base helper functions\r
-//\r
-EFI_STATUS\r
-WriteUHCCommandReg (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  CmdAddrOffset,\r
-  IN UINT16                  UsbCmd\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Write UHCI Command Register\r
-\r
-Arguments:\r
-\r
-  PciIo         - EFI_PCI_IO_PROTOCOL\r
-  CmdAddrOffset - Command address offset\r
-  UsbCmd        - Data to write\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Write to UHC's Command Register\r
-  //\r
-  return USBWritePortW (PciIo, CmdAddrOffset, UsbCmd);\r
-}\r
-\r
-EFI_STATUS\r
-ReadUHCCommandReg (\r
-  IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN       UINT32                  CmdAddrOffset,\r
-  IN OUT   UINT16                  *Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read UHCI Command Register\r
-\r
-Arguments:\r
-\r
-  PciIo         - EFI_PCI_IO_PROTOCOL\r
-  CmdAddrOffset - Command address offset\r
-  Data          - Data to return\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Read from UHC's Command Register\r
-  //\r
-  return USBReadPortW (PciIo, CmdAddrOffset, Data);\r
-}\r
-\r
-EFI_STATUS\r
-WriteUHCStatusReg (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  StatusAddrOffset,\r
-  IN UINT16                  UsbSts\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Write UHCI Staus Register\r
-\r
-Arguments:\r
-\r
-  PciIo            - EFI_PCI_IO_PROTOCOL\r
-  StatusAddrOffset - Status address offset\r
-  UsbSts           - Data to write\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Write to UHC's Status Register\r
-  //\r
-  return USBWritePortW (PciIo, StatusAddrOffset, UsbSts);\r
-}\r
-\r
-EFI_STATUS\r
-ReadUHCStatusReg (\r
-  IN     EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN     UINT32                  StatusAddrOffset,\r
-  IN OUT UINT16                  *Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read UHCI Staus Register\r
-\r
-Arguments:\r
-\r
-  PciIo            - EFI_PCI_IO_PROTOCOL\r
-  StatusAddrOffset - Status address offset\r
-  UsbSts           - Data to return\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Read from UHC's Status Register\r
-  //\r
-  return USBReadPortW (PciIo, StatusAddrOffset, Data);\r
-}\r
-\r
-\r
-EFI_STATUS\r
-ClearStatusReg (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  StatusAddrOffset\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Clear the content of UHC's Status Register\r
-\r
-Arguments:\r
-\r
-  PciIo             - EFI_PCI_IO_PROTOCOL\r
-  StatusAddrOffset  - Status address offset\r
-  \r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
\r
-  return WriteUHCStatusReg (PciIo, StatusAddrOffset, 0x003F);\r
-}\r
-\r
-EFI_STATUS\r
-ReadUHCFrameNumberReg (\r
-  IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN       UINT32                  FrameNumAddrOffset,\r
-  IN OUT   UINT16                  *Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read from UHC's Frame Number Register\r
-\r
-Arguments:\r
-\r
-  PciIo              - EFI_PCI_IO_PROTOCOL\r
-  FrameNumAddrOffset - Frame number register offset\r
-  Data               - Data to return \r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  \r
-  return USBReadPortW (PciIo, FrameNumAddrOffset, Data);\r
-}\r
-\r
-EFI_STATUS\r
-WriteUHCFrameListBaseReg (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  FlBaseAddrOffset,\r
-  IN UINT32                  UsbFrameListBaseAddr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Write to UHC's Frame List Base Register\r
-\r
-Arguments:\r
-\r
-  PciIo                - EFI_PCI_IO_PROTOCOL\r
-  FlBaseAddrOffset     - Frame Base address register\r
-  UsbFrameListBaseAddr - Address to write\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  \r
-  return USBWritePortDW (PciIo, FlBaseAddrOffset, UsbFrameListBaseAddr);\r
-}\r
-\r
-EFI_STATUS\r
-ReadRootPortReg (\r
-  IN     EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN     UINT32                  PortAddrOffset,\r
-  IN OUT UINT16                  *Data\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Read from UHC's Root Port Register\r
-\r
-Arguments:\r
-\r
-  PciIo           - EFI_PCI_IO_PROTOCOL\r
-  PortAddrOffset  - Port Addrress Offset,\r
-  Data            - Data to return\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
\r
-  return USBReadPortW (PciIo, PortAddrOffset, Data);\r
-}\r
-\r
-EFI_STATUS\r
-WriteRootPortReg (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  PortAddrOffset,\r
-  IN UINT16                  ControlBits\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-   Write to UHC's Root Port Register\r
-\r
-Arguments:\r
-\r
-  PciIo           - EFI_PCI_IO_PROTOCOL\r
-  PortAddrOffset  - Port Addrress Offset,\r
-  ControlBits     - Data to write\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
\r
-  return USBWritePortW (PciIo, PortAddrOffset, ControlBits);\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-WaitForUHCHalt (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  StatusRegAddr,\r
-  IN UINTN                   Timeout\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Wait until UHCI halt or timeout\r
-\r
-Arguments:\r
-\r
-  PciIo         - EFI_PCI_IO_PROTOCOL\r
-  StatusRegAddr - Status Register Address\r
-  Timeout       - Time out value in us\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - Unable to read the status register\r
-  EFI_TIMEOUT      - Time out\r
-  EFI_SUCCESS      - Success\r
-\r
---*/\r
-{\r
-  UINTN       Delay;\r
-  EFI_STATUS  Status;\r
-  UINT16      HcStatus;\r
-\r
-  //\r
-  // Timeout is in us unit\r
-  //\r
-  Delay = (Timeout / 50) + 1;\r
-  do {\r
-    Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-\r
-    if ((HcStatus & USBSTS_HCH) == USBSTS_HCH) {\r
-      break;\r
-    }\r
-    //\r
-    // Stall for 50 us\r
-    //\r
-    gBS->Stall (50);\r
-\r
-  } while (Delay--);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-IsStatusOK (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  StatusRegAddr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Judge whether the host controller operates well\r
-\r
-Arguments:\r
-\r
-  PciIo         - EFI_PCI_IO_PROTOCOL\r
-  StatusRegAddr - Status register address\r
-\r
-Returns:\r
-\r
-   TRUE  -  Status is good\r
-   FALSE -  Status is bad\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT16      HcStatus;\r
-  //\r
-  // Detect whether the interrupt is caused by fatal error.\r
-  // see "UHCI Design Guid".\r
-  //\r
-  Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);\r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (HcStatus & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) {\r
-    return FALSE;\r
-  } else {\r
-    return TRUE;\r
-  }\r
-\r
-}\r
-\r
-\r
-BOOLEAN \r
-IsHostSysOrProcessErr (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  StatusRegAddr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Judge the status is HostSys,ProcessErr error or good\r
-\r
-Arguments:\r
-\r
-  PciIo         - EFI_PCI_IO_PROTOCOL\r
-  StatusRegAddr - Status register address\r
-\r
-Returns:\r
-\r
-   TRUE  -  Status is good\r
-   FALSE -  Status is bad\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT16      HcStatus;\r
-  //\r
-  // Detect whether the interrupt is caused by serious error.\r
-  // see "UHCI Design Guid".\r
-  //\r
-  Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);\r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (HcStatus & (USBSTS_HSE | USBSTS_HCPE)) {\r
-    return TRUE;\r
-  } else {\r
-    return FALSE;\r
-  }\r
-}\r
-\r
-\r
-UINT16\r
-GetCurrentFrameNumber (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  FrameNumAddrOffset\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get Current Frame Number\r
-\r
-Arguments:\r
-\r
-  PciIo               - EFI_PCI_IO_PROTOCOL\r
-  FrameNumAddrOffset  - FrameNum register AddrOffset\r
-\r
-Returns:\r
-\r
-  Frame number \r
-\r
---*/\r
-{\r
-  //\r
-  // Gets value in the USB frame number register.\r
-  //\r
-  UINT16  FrameNumber;\r
-\r
-  ReadUHCFrameNumberReg (PciIo, FrameNumAddrOffset, &FrameNumber);\r
-\r
-  return (UINT16) (FrameNumber & 0x03FF);\r
-}\r
-\r
-EFI_STATUS\r
-SetFrameListBaseAddress (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  FlBaseAddrReg,\r
-  IN UINT32                  Addr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set FrameListBase Address\r
-\r
-Arguments:\r
-\r
-  PciIo         - EFI_PCI_IO_PROTOCOL\r
-  FlBaseAddrReg - FrameListBase register\r
-  Addr          - Address to set\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  //\r
-  // Sets value in the USB Frame List Base Address register.\r
-  //\r
-  return WriteUHCFrameListBaseReg (PciIo, FlBaseAddrReg, (UINT32) (Addr & 0xFFFFF000));\r
-}\r
-\r
-VOID\r
-EnableMaxPacketSize (\r
-  IN USB_HC_DEV     *HcDev\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Enable Max Packet Size\r
-\r
-Arguments:\r
-\r
-  HcDev - USB_HC_DEV\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  UINT16      CommandContent;\r
-\r
-  ReadUHCCommandReg (\r
-    HcDev->PciIo,\r
-    (UINT32) (USBCMD),\r
-    &CommandContent\r
-    );\r
-\r
-  if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {\r
-    CommandContent |= USBCMD_MAXP;\r
-    WriteUHCCommandReg (\r
-      HcDev->PciIo,\r
-      (UINT32) (USBCMD),\r
-      CommandContent\r
-      );\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-EFI_STATUS\r
-CreateFrameList (\r
-  IN USB_HC_DEV     *HcDev,\r
-  IN UINT32         FlBaseAddrReg\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  CreateFrameList\r
-\r
-Arguments:\r
-\r
-  HcDev         - USB_HC_DEV\r
-  FlBaseAddrReg - Frame List register\r
-\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES - Can't allocate memory resources\r
-  EFI_UNSUPPORTED      - Map memory fail\r
-  EFI_SUCCESS          - Success\r
-\r
---*/\r
-{\r
-  EFI_STATUS            Status;\r
-  VOID                  *CommonBuffer;\r
-  EFI_PHYSICAL_ADDRESS  MappedAddress;\r
-  VOID                  *Mapping;\r
-  UINTN                 BufferSizeInPages;\r
-  UINTN                 BufferSizeInBytes;\r
-\r
-  //\r
-  // The Frame List is a common buffer that will be\r
-  // accessed by both the cpu and the usb bus master\r
-  // at the same time.\r
-  // The Frame List ocupies 4K bytes,\r
-  // and must be aligned on 4-Kbyte boundaries.\r
-  //\r
-  BufferSizeInBytes = 4096;\r
-  BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);\r
-  Status = HcDev->PciIo->AllocateBuffer (\r
-                           HcDev->PciIo,\r
-                           AllocateAnyPages,\r
-                           EfiBootServicesData,\r
-                           BufferSizeInPages,\r
-                           &CommonBuffer,\r
-                           0\r
-                           );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = HcDev->PciIo->Map (\r
-                           HcDev->PciIo,\r
-                           EfiPciIoOperationBusMasterCommonBuffer,\r
-                           CommonBuffer,\r
-                           &BufferSizeInBytes,\r
-                           &MappedAddress,\r
-                           &Mapping\r
-                           );\r
-  if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {\r
-    HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  HcDev->FrameListEntry   = (FRAMELIST_ENTRY *) ((UINTN) MappedAddress);\r
-\r
-  HcDev->FrameListMapping = Mapping;\r
-\r
-  InitFrameList (HcDev);\r
-\r
-  //\r
-  // Tell the Host Controller where the Frame List lies,\r
-  // by set the Frame List Base Address Register.\r
-  //\r
-  SetFrameListBaseAddress (\r
-    HcDev->PciIo,\r
-    FlBaseAddrReg,\r
-    (UINT32) ((UINTN) HcDev->FrameListEntry)\r
-    );\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FreeFrameListEntry (\r
-  IN USB_HC_DEV     *HcDev\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Free FrameList buffer\r
-\r
-Arguments:\r
-\r
-  HcDev - USB_HC_DEV\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - success\r
-\r
---*/\r
-{\r
-  //\r
-  // Unmap the common buffer for framelist entry,\r
-  // and free the common buffer.\r
-  // Uhci's frame list occupy 4k memory.\r
-  //\r
-  HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->FrameListMapping);\r
-  HcDev->PciIo->FreeBuffer (\r
-                  HcDev->PciIo,\r
-                  EFI_SIZE_TO_PAGES (4096),\r
-                  (VOID *) (HcDev->FrameListEntry)\r
-                  );\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-InitFrameList (\r
-  IN USB_HC_DEV     *HcDev\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Initialize FrameList\r
-\r
-Arguments:\r
-\r
-  HcDev - USB_HC_DEV\r
-\r
-Returns:\r
-   VOID\r
-\r
---*/  \r
-{\r
-  FRAMELIST_ENTRY *FrameListPtr;\r
-  UINTN           Index;\r
-\r
-  //\r
-  // Validate each Frame List Entry\r
-  //\r
-  FrameListPtr = HcDev->FrameListEntry;\r
-  for (Index = 0; Index < 1024; Index++) {\r
-    FrameListPtr->FrameListPtrTerminate = 1;\r
-    FrameListPtr->FrameListPtr          = 0;\r
-    FrameListPtr->FrameListPtrQSelect   = 0;\r
-    FrameListPtr->FrameListRsvd         = 0;\r
-    FrameListPtr++;\r
-  }\r
-}\r
-//\r
-// //////////////////////////////////////////////////////////////\r
-//\r
-// QH TD related Helper Functions\r
-//\r
-////////////////////////////////////////////////////////////////\r
-//\r
-// functions for QH\r
-//\r
-STATIC\r
-EFI_STATUS\r
-AllocateQHStruct (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT QH_STRUCT      **ppQHStruct\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Allocate QH Struct\r
-\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  ppQHStruct  - QH_STRUCT content to return\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  *ppQHStruct = NULL;\r
-\r
-  //\r
-  // QH must align on 16 bytes alignment,\r
-  // since the memory allocated by UhciAllocatePool ()\r
-  // is aligned on 32 bytes, it is no need to adjust\r
-  // the allocated memory returned.\r
-  //\r
-  return UhciAllocatePool (HcDev, (UINT8 **) ppQHStruct, sizeof (QH_STRUCT));\r
-}\r
-\r
-\r
-EFI_STATUS\r
-CreateQH (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT QH_STRUCT      **pptrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  CreateQH\r
-\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  ppQHStruct  - QH_STRUCT content to return\r
-Returns:\r
-\r
-  EFI_SUCCESS          - Success\r
-  EFI_OUT_OF_RESOURCES - Can't allocate memory\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  //\r
-  // allocate align memory for QH_STRUCT\r
-  //\r
-  Status = AllocateQHStruct (HcDev, pptrQH);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // init each field of the QH_STRUCT\r
-  //\r
-  //\r
-  // Make QH ready\r
-  //\r
-  SetQHHorizontalValidorInvalid (*pptrQH, FALSE);\r
-  SetQHVerticalValidorInvalid   (*pptrQH, FALSE);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-SetQHHorizontalLinkPtr (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN VOID          *ptrNext\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set QH Horizontal Link Pointer\r
-\r
-Arguments:\r
-\r
-  PtrQH   - QH_STRUCT\r
-  ptrNext - Data to write \r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Since the QH_STRUCT is aligned on 16-byte boundaries,\r
-  // Only the highest 28bit of the address is valid\r
-  // (take 32bit address as an example).\r
-  //\r
-  PtrQH->QH.QHHorizontalPtr = (UINT32) ((UINTN) ptrNext >> 4);\r
-}\r
-\r
-VOID *\r
-GetQHHorizontalLinkPtr (\r
-  IN QH_STRUCT     *PtrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get QH Horizontal Link Pointer\r
-\r
-Arguments:\r
-\r
-  PtrQH   - QH_STRUCT\r
-  \r
-\r
-Returns:\r
-\r
-  Data to return \r
-\r
---*/\r
-{\r
-  //\r
-  // Restore the 28bit address to 32bit address\r
-  // (take 32bit address as an example)\r
-  //\r
-  return (VOID *) ((UINTN) (PtrQH->QH.QHHorizontalPtr << 4));\r
-}\r
-\r
-VOID\r
-SetQHHorizontalQHorTDSelect (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN BOOLEAN       bQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set QH Horizontal QH or TD \r
-\r
-Arguments:\r
-\r
-  PtrQH - QH_STRUCT\r
-  bQH   - TRUE is QH FALSE is TD\r
-\r
-Returns:\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // if QH is connected, the specified bit is set,\r
-  // if TD is connected, the specified bit is cleared.\r
-  //\r
-  PtrQH->QH.QHHorizontalQSelect = bQH ? 1 : 0;\r
-}\r
-\r
-\r
-VOID\r
-SetQHHorizontalValidorInvalid (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN BOOLEAN       bValid\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set QH Horizontal Valid or Invalid\r
-\r
-Arguments:\r
-\r
-  PtrQH  - QH_STRUCT\r
-  bValid - TRUE is Valid FALSE is Invalid\r
-\r
-Returns:\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Valid means the horizontal link pointer is valid,\r
-  // else, it's invalid.\r
-  //\r
-  PtrQH->QH.QHHorizontalTerminate = bValid ? 0 : 1;\r
-}\r
-\r
-VOID\r
-SetQHVerticalLinkPtr (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN VOID          *ptrNext\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set QH Vertical Link Pointer\r
-  \r
-Arguments:\r
-\r
-  PtrQH   - QH_STRUCT\r
-  ptrNext - Data to write\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Since the QH_STRUCT is aligned on 16-byte boundaries,\r
-  // Only the highest 28bit of the address is valid\r
-  // (take 32bit address as an example).\r
-  //\r
-  PtrQH->QH.QHVerticalPtr = (UINT32) ((UINTN) ptrNext >> 4);\r
-}\r
-\r
-VOID *\r
-GetQHVerticalLinkPtr (\r
-  IN QH_STRUCT     *PtrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get QH Vertical Link Pointer\r
-  \r
-Arguments:\r
-\r
-  PtrQH   - QH_STRUCT\r
\r
-Returns:\r
-\r
-   Data to return\r
-\r
---*/\r
-{\r
-  //\r
-  // Restore the 28bit address to 32bit address\r
-  // (take 32bit address as an example)\r
-  //\r
-  return (VOID *) ((UINTN) (PtrQH->QH.QHVerticalPtr << 4));\r
-}\r
-\r
-VOID\r
-SetQHVerticalQHorTDSelect (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN BOOLEAN       bQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set QH Vertical QH or TD\r
-\r
-Arguments:\r
-\r
-  PtrQH - QH_STRUCT\r
-  bQH   - TRUE is QH FALSE is TD\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Set the specified bit if the Vertical Link Pointer pointing to a QH,\r
-  // Clear the specified bit if the Vertical Link Pointer pointing to a TD.\r
-  //\r
-  PtrQH->QH.QHVerticalQSelect = bQH ? 1 : 0;\r
-}\r
-\r
-BOOLEAN\r
-IsQHHorizontalQHSelect (\r
-  IN QH_STRUCT     *PtrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Is QH Horizontal QH Select\r
-\r
-Arguments:\r
-\r
-  PtrQH - QH_STRUCT\r
\r
-Returns:\r
-\r
-  TRUE  - QH\r
-  FALSE - TD\r
-\r
---*/\r
-{\r
-  //\r
-  // Retrieve the information about whether the Horizontal Link Pointer\r
-  // pointing to a QH or TD.\r
-  //\r
-  return (BOOLEAN) (PtrQH->QH.QHHorizontalQSelect ? TRUE : FALSE);\r
-}\r
-\r
-VOID\r
-SetQHVerticalValidorInvalid (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN BOOLEAN       IsValid\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set QH Vertical Valid or Invalid\r
-\r
-Arguments:\r
-\r
-  PtrQH   - QH_STRUCT\r
-  IsValid - TRUE is valid FALSE is invalid\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // If TRUE, indicates the Vertical Link Pointer field is valid,\r
-  // else, the field is invalid.\r
-  //\r
-  PtrQH->QH.QHVerticalTerminate = IsValid ? 0 : 1;\r
-}\r
-\r
-\r
-BOOLEAN\r
-GetQHVerticalValidorInvalid (\r
-  IN QH_STRUCT     *PtrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get QH Vertical Valid or Invalid\r
-\r
-Arguments:\r
-\r
-  PtrQH - QH_STRUCT\r
-\r
-Returns:\r
-\r
-  TRUE  - Valid\r
-  FALSE - Invalid\r
-\r
---*/\r
-{\r
-  //\r
-  // If TRUE, indicates the Vertical Link Pointer field is valid,\r
-  // else, the field is invalid.\r
-  //\r
-  return (BOOLEAN) (!(PtrQH->QH.QHVerticalTerminate));\r
-}\r
-\r
-STATIC\r
-BOOLEAN\r
-GetQHHorizontalValidorInvalid (\r
-  IN QH_STRUCT     *PtrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get QH Horizontal Valid or Invalid\r
-\r
-Arguments:\r
-\r
-  PtrQH - QH_STRUCT\r
-\r
-Returns:\r
-\r
-  TRUE  - Valid\r
-  FALSE - Invalid\r
-\r
---*/\r
-{\r
-  //\r
-  // If TRUE, meaning the Horizontal Link Pointer field is valid,\r
-  // else, the field is invalid.\r
-  //\r
-  return (BOOLEAN) (!(PtrQH->QH.QHHorizontalTerminate));\r
-}\r
-//\r
-// functions for TD\r
-//\r
-EFI_STATUS\r
-AllocateTDStruct (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT TD_STRUCT      **ppTDStruct\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Allocate TD Struct\r
-\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  ppTDStruct  - place to store TD_STRUCT pointer\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  *ppTDStruct = NULL;\r
-\r
-  //\r
-  // TD must align on 16 bytes alignment,\r
-  // since the memory allocated by UhciAllocatePool ()\r
-  // is aligned on 32 bytes, it is no need to adjust\r
-  // the allocated memory returned.\r
-  //\r
-  return UhciAllocatePool (\r
-          HcDev,\r
-          (UINT8 **) ppTDStruct,\r
-          sizeof (TD_STRUCT)\r
-          );\r
-}\r
-\r
-EFI_STATUS\r
-CreateTD (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT TD_STRUCT      **pptrTD\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Create TD\r
-\r
-Arguments:\r
-\r
-  HcDev   - USB_HC_DEV\r
-  pptrTD  - TD_STRUCT pointer to store\r
-\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES - Can't allocate resources\r
-  EFI_SUCCESS          - Success\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-  //\r
-  // create memory for TD_STRUCT, and align the memory.\r
-  //\r
-  Status = AllocateTDStruct (HcDev, pptrTD);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Make TD ready.\r
-  //\r
-  SetTDLinkPtrValidorInvalid (*pptrTD, FALSE);\r
-\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GenSetupStageTD (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  UINT8          DevAddr,\r
-  IN  UINT8          Endpoint,\r
-  IN  BOOLEAN        bSlow,\r
-  IN  UINT8          *pDevReq,\r
-  IN  UINT8          RequestLen,\r
-  OUT TD_STRUCT      **ppTD\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Generate Setup Stage TD\r
-\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  DevAddr     - Device address\r
-  Endpoint    - Endpoint number \r
-  bSlow       - Full speed or low speed\r
-  pDevReq     - Device request\r
-  RequestLen  - Request length\r
-  ppTD        - TD_STRUCT to return\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES - Can't allocate memory\r
-  EFI_SUCCESS          - Success\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-  TD_STRUCT   *pTDStruct;\r
-\r
-  Status = CreateTD (HcDev, &pTDStruct);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  SetTDLinkPtr (pTDStruct, NULL);\r
-\r
-  //\r
-  // Depth first fashion\r
-  //\r
-  SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);\r
-\r
-  //\r
-  // initialize as the last TD in the QH context,\r
-  // this field will be updated in the TD linkage process.\r
-  //\r
-  SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Disable Short Packet Detection by default\r
-  //\r
-  EnableorDisableTDShortPacket (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Max error counter is 3, retry 3 times when error encountered.\r
-  //\r
-  SetTDControlErrorCounter (pTDStruct, 3);\r
-\r
-  //\r
-  // set device speed attribute\r
-  // (TRUE - Slow Device; FALSE - Full Speed Device)\r
-  //\r
-  SetTDLoworFullSpeedDevice (pTDStruct, bSlow);\r
-\r
-  //\r
-  // Non isochronous transfer TD\r
-  //\r
-  SetTDControlIsochronousorNot (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Interrupt On Complete bit be set to zero,\r
-  // Disable IOC interrupt.\r
-  //\r
-  SetorClearTDControlIOC (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Set TD Active bit\r
-  //\r
-  SetTDStatusActiveorInactive (pTDStruct, TRUE);\r
-\r
-  SetTDTokenMaxLength (pTDStruct, RequestLen);\r
-\r
-  SetTDTokenDataToggle0 (pTDStruct);\r
-\r
-  SetTDTokenEndPoint (pTDStruct, Endpoint);\r
-\r
-  SetTDTokenDeviceAddress (pTDStruct, DevAddr);\r
-\r
-  SetTDTokenPacketID (pTDStruct, SETUP_PACKET_ID);\r
-\r
-  pTDStruct->pTDBuffer      = (UINT8 *) pDevReq;\r
-  pTDStruct->TDBufferLength = RequestLen;\r
-  SetTDDataBuffer (pTDStruct);\r
-\r
-  *ppTD = pTDStruct;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GenDataTD (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  UINT8          DevAddr,\r
-  IN  UINT8          Endpoint,\r
-  IN  UINT8          *pData,\r
-  IN  UINT8          Len,\r
-  IN  UINT8          PktID,\r
-  IN  UINT8          Toggle,\r
-  IN  BOOLEAN        bSlow,\r
-  OUT TD_STRUCT      **ppTD\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Generate Data Stage TD\r
-\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  DevAddr     - Device address\r
-  Endpoint    - Endpoint number \r
-  pData       - Data buffer \r
-  Len         - Data length\r
-  PktID       - Packet ID\r
-  Toggle      - Data toggle value\r
-  bSlow       - Full speed or low speed\r
-  ppTD        - TD_STRUCT to return\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES - Can't allocate memory\r
-  EFI_SUCCESS          - Success\r
-\r
---*/\r
-{\r
-  TD_STRUCT   *pTDStruct;\r
-  EFI_STATUS  Status;\r
-\r
-  Status = CreateTD (HcDev, &pTDStruct);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  SetTDLinkPtr (pTDStruct, NULL);\r
-\r
-  //\r
-  // Depth first fashion\r
-  //\r
-  SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);\r
-\r
-  //\r
-  // Link pointer pointing to TD struct\r
-  //\r
-  SetTDLinkPtrQHorTDSelect (pTDStruct, FALSE);\r
-\r
-  //\r
-  // initialize as the last TD in the QH context,\r
-  // this field will be updated in the TD linkage process.\r
-  //\r
-  SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Disable short packet detect\r
-  //\r
-  EnableorDisableTDShortPacket (pTDStruct, FALSE);\r
-  //\r
-  // Max error counter is 3\r
-  //\r
-  SetTDControlErrorCounter (pTDStruct, 3);\r
-\r
-  //\r
-  // set device speed attribute\r
-  // (TRUE - Slow Device; FALSE - Full Speed Device)\r
-  //\r
-  SetTDLoworFullSpeedDevice (pTDStruct, bSlow);\r
-\r
-  //\r
-  // Non isochronous transfer TD\r
-  //\r
-  SetTDControlIsochronousorNot (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Disable Interrupt On Complete\r
-  // Disable IOC interrupt.\r
-  //\r
-  SetorClearTDControlIOC (pTDStruct, FALSE);\r
-\r
-  //\r
-  // Set Active bit\r
-  //\r
-  SetTDStatusActiveorInactive (pTDStruct, TRUE);\r
-\r
-  SetTDTokenMaxLength (pTDStruct, Len);\r
-\r
-  if (Toggle) {\r
-    SetTDTokenDataToggle1 (pTDStruct);\r
-  } else {\r
-    SetTDTokenDataToggle0 (pTDStruct);\r
-  }\r
-\r
-  SetTDTokenEndPoint (pTDStruct, Endpoint);\r
-\r
-  SetTDTokenDeviceAddress (pTDStruct, DevAddr);\r
-\r
-  SetTDTokenPacketID (pTDStruct, PktID);\r
-\r
-  pTDStruct->pTDBuffer      = (UINT8 *) pData;\r
-  pTDStruct->TDBufferLength = Len;\r
-  SetTDDataBuffer (pTDStruct);\r
-  *ppTD = pTDStruct;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-CreateStatusTD (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  UINT8          DevAddr,\r
-  IN  UINT8          Endpoint,\r
-  IN  UINT8          PktID,\r
-  IN  BOOLEAN        bSlow,\r
-  OUT TD_STRUCT      **ppTD\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Generate Status Stage TD\r
-\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  DevAddr     - Device address\r
-  Endpoint    - Endpoint number \r
-  PktID       - Packet ID\r
-  bSlow       - Full speed or low speed\r
-  ppTD        - TD_STRUCT to return\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES - Can't allocate memory\r
-  EFI_SUCCESS          - Success\r
-\r
---*/\r
-{\r
-  TD_STRUCT   *ptrTDStruct;\r
-  EFI_STATUS  Status;\r
-\r
-  Status = CreateTD (HcDev, &ptrTDStruct);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  SetTDLinkPtr (ptrTDStruct, NULL);\r
-\r
-  //\r
-  // Depth first fashion\r
-  //\r
-  SetTDLinkPtrDepthorBreadth (ptrTDStruct, TRUE);\r
-\r
-  //\r
-  // initialize as the last TD in the QH context,\r
-  // this field will be updated in the TD linkage process.\r
-  //\r
-  SetTDLinkPtrValidorInvalid (ptrTDStruct, FALSE);\r
-\r
-  //\r
-  // Disable short packet detect\r
-  //\r
-  EnableorDisableTDShortPacket (ptrTDStruct, FALSE);\r
-\r
-  //\r
-  // Max error counter is 3\r
-  //\r
-  SetTDControlErrorCounter (ptrTDStruct, 3);\r
-\r
-  //\r
-  // set device speed attribute\r
-  // (TRUE - Slow Device; FALSE - Full Speed Device)\r
-  //\r
-  SetTDLoworFullSpeedDevice (ptrTDStruct, bSlow);\r
-\r
-  //\r
-  // Non isochronous transfer TD\r
-  //\r
-  SetTDControlIsochronousorNot (ptrTDStruct, FALSE);\r
-\r
-  //\r
-  // Disable Interrupt On Complete\r
-  // Disable IOC interrupt.\r
-  //\r
-  SetorClearTDControlIOC (ptrTDStruct, FALSE);\r
-\r
-  //\r
-  // Set TD Active bit\r
-  //\r
-  SetTDStatusActiveorInactive (ptrTDStruct, TRUE);\r
-\r
-  SetTDTokenMaxLength (ptrTDStruct, 0);\r
-\r
-  SetTDTokenDataToggle1 (ptrTDStruct);\r
-\r
-  SetTDTokenEndPoint (ptrTDStruct, Endpoint);\r
-\r
-  SetTDTokenDeviceAddress (ptrTDStruct, DevAddr);\r
-\r
-  SetTDTokenPacketID (ptrTDStruct, PktID);\r
-\r
-  ptrTDStruct->pTDBuffer      = NULL;\r
-  ptrTDStruct->TDBufferLength = 0;\r
-  SetTDDataBuffer (ptrTDStruct);\r
-\r
-  *ppTD = ptrTDStruct;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-SetTDLinkPtrValidorInvalid (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       bValid\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set TD Link Pointer Valid or Invalid\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-  bValid      - TRUE is valid FALSE is invalid\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Valid means the link pointer is valid,\r
-  // else, it's invalid.\r
-  //\r
-  ptrTDStruct->TDData.TDLinkPtrTerminate = (bValid ? 0 : 1);\r
-}\r
-\r
-VOID\r
-SetTDLinkPtrQHorTDSelect (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       bQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set TD Link Pointer QH or TD Select\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-  bQH         -  TRUE is QH FALSE is TD\r
-  \r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Indicate whether the Link Pointer pointing to a QH or TD\r
-  //\r
-  ptrTDStruct->TDData.TDLinkPtrQSelect = (bQH ? 1 : 0);\r
-}\r
-\r
-VOID\r
-SetTDLinkPtrDepthorBreadth (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       bDepth\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set TD Link Pointer depth or bread priority\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-  bDepth      -  TRUE is Depth  FALSE is Breadth\r
-  \r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // If TRUE, indicating the host controller should process in depth first\r
-  // fashion,\r
-  // else, the host controller should process in breadth first fashion\r
-  //\r
-  ptrTDStruct->TDData.TDLinkPtrDepthSelect = (bDepth ? 1 : 0);\r
-}\r
-\r
-VOID\r
-SetTDLinkPtr (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN VOID          *ptrNext\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set TD Link Pointer\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-  ptrNext     - Pointer to set\r
-  \r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // Set TD Link Pointer. Since QH,TD align on 16-byte boundaries,\r
-  // only the highest 28 bits are valid. (if take 32bit address as an example)\r
-  //\r
-  ptrTDStruct->TDData.TDLinkPtr = (UINT32) ((UINTN) ptrNext >> 4);\r
-}\r
-\r
-VOID *\r
-GetTDLinkPtr (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get TD Link Pointer\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-   \r
-Returns:\r
-\r
-  Pointer to get\r
-\r
---*/\r
-{\r
-  //\r
-  // Get TD Link Pointer. Restore it back to 32bit\r
-  // (if take 32bit address as an example)\r
-  //\r
-  return (VOID *) ((UINTN) (ptrTDStruct->TDData.TDLinkPtr << 4));\r
-}\r
-\r
-STATIC\r
-BOOLEAN\r
-IsTDLinkPtrQHOrTD (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Is TD Link Pointer is QH Or TD\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  TRUE  - QH\r
-  FALSE - TD \r
-\r
---*/\r
-{\r
-  //\r
-  // Get the information about whether the Link Pointer field pointing to\r
-  // a QH or a TD.\r
-  //\r
-  return (BOOLEAN) (ptrTDStruct->TDData.TDLinkPtrQSelect);\r
-}\r
-\r
-VOID\r
-EnableorDisableTDShortPacket (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       bEnable\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Enable or Disable TD ShortPacket\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-  bEnable     - TRUE is Enanble FALSE is Disable\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // TRUE means enable short packet detection mechanism.\r
-  //\r
-  ptrTDStruct->TDData.TDStatusSPD = (bEnable ? 1 : 0);\r
-}\r
-\r
-VOID\r
-SetTDControlErrorCounter (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN UINT8         nMaxErrors\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Set TD Control ErrorCounter\r
-\r
-Arguments:\r
-\r
-  ptrTDStruct - TD_STRUCT\r
-  nMaxErrors  - Error counter number\r
-  \r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // valid value of nMaxErrors is 0,1,2,3\r
-  //\r
-  if (nMaxErrors > 3) {\r
-    nMaxErrors = 3;\r
-  }\r
-\r
-  ptrTDStruct->TDData.TDStatusErr = nMaxErrors;\r
-}\r
-\r
-\r
-VOID\r
-SetTDLoworFullSpeedDevice (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       bLowSpeedDevice\r
-  )\r
-{\r
-  //\r
-  // TRUE means the TD is targeting at a Low-speed device\r
-  //\r
-  ptrTDStruct->TDData.TDStatusLS = (bLowSpeedDevice ? 1 : 0);\r
-}\r
-\r
-VOID\r
-SetTDControlIsochronousorNot (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       IsIsochronous\r
-  )\r
-{\r
-  //\r
-  // TRUE means the TD belongs to Isochronous transfer type.\r
-  //\r
-  ptrTDStruct->TDData.TDStatusIOS = (IsIsochronous ? 1 : 0);\r
-}\r
-\r
-VOID\r
-SetorClearTDControlIOC (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       IsSet\r
-  )\r
-{\r
-  //\r
-  // If this bit is set, it indicates that the host controller should issue\r
-  // an interrupt on completion of the frame in which this TD is executed.\r
-  //\r
-  ptrTDStruct->TDData.TDStatusIOC = IsSet ? 1 : 0;\r
-}\r
-\r
-VOID\r
-SetTDStatusActiveorInactive (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN BOOLEAN       IsActive\r
-  )\r
-{\r
-  //\r
-  // If this bit is set, it indicates that the TD is active and can be\r
-  // executed.\r
-  //\r
-  if (IsActive) {\r
-    ptrTDStruct->TDData.TDStatus |= 0x80;\r
-  } else {\r
-    ptrTDStruct->TDData.TDStatus &= 0x7F;\r
-  }\r
-}\r
-\r
-UINT16\r
-SetTDTokenMaxLength (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN UINT16        MaximumLength\r
-  )\r
-{\r
-  //\r
-  // Specifies the maximum number of data bytes allowed for the transfer.\r
-  // the legal value extent is 0 ~ 0x500.\r
-  //\r
-  if (MaximumLength > 0x500) {\r
-    MaximumLength = 0x500;\r
-  }\r
-  ptrTDStruct->TDData.TDTokenMaxLen = MaximumLength - 1;\r
-\r
-  return MaximumLength;\r
-}\r
-\r
-VOID\r
-SetTDTokenDataToggle1 (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Set the data toggle bit to DATA1\r
-  //\r
-  ptrTDStruct->TDData.TDTokenDataToggle = 1;\r
-}\r
-\r
-VOID\r
-SetTDTokenDataToggle0 (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Set the data toggle bit to DATA0\r
-  //\r
-  ptrTDStruct->TDData.TDTokenDataToggle = 0;\r
-}\r
-\r
-UINT8\r
-GetTDTokenDataToggle (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Get the data toggle value.\r
-  //\r
-  return (UINT8) (ptrTDStruct->TDData.TDTokenDataToggle);\r
-}\r
-\r
-VOID\r
-SetTDTokenEndPoint (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN UINTN         EndPoint\r
-  )\r
-{\r
-  //\r
-  // Set EndPoint Number the TD is targeting at.\r
-  //\r
-  ptrTDStruct->TDData.TDTokenEndPt = (UINT8) EndPoint;\r
-}\r
-\r
-VOID\r
-SetTDTokenDeviceAddress (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN UINTN         DeviceAddress\r
-  )\r
-{\r
-  //\r
-  // Set Device Address the TD is targeting at.\r
-  //\r
-  ptrTDStruct->TDData.TDTokenDevAddr = (UINT8) DeviceAddress;\r
-}\r
-\r
-VOID\r
-SetTDTokenPacketID (\r
-  IN TD_STRUCT     *ptrTDStruct,\r
-  IN UINT8         PID\r
-  )\r
-{\r
-  //\r
-  // Set the Packet Identification to be used for this transaction.\r
-  //\r
-  ptrTDStruct->TDData.TDTokenPID = PID;\r
-}\r
-\r
-VOID\r
-SetTDDataBuffer (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Set the beginning address of the data buffer that will be used\r
-  // during the transaction.\r
-  //\r
-  ptrTDStruct->TDData.TDBufferPtr = (UINT32) ((UINTN) (ptrTDStruct->pTDBuffer));\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusActive (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-\r
-  //\r
-  // Detect whether the TD is active.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x80);\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusStalled (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-\r
-  //\r
-  // Detect whether the device/endpoint addressed by this TD is stalled.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x40);\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusBufferError (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-  //\r
-  // Detect whether Data Buffer Error is happened.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x20);\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusBabbleError (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-\r
-  //\r
-  // Detect whether Babble Error is happened.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x10);\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusNAKReceived (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-\r
-  //\r
-  // Detect whether NAK is received.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x08);\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusCRCTimeOutError (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-\r
-  //\r
-  // Detect whether CRC/Time Out Error is encountered.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x04);\r
-}\r
-\r
-BOOLEAN\r
-IsTDStatusBitStuffError (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  UINT8 TDStatus;\r
-\r
-  //\r
-  // Detect whether Bitstuff Error is received.\r
-  //\r
-  TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);\r
-  return (BOOLEAN) (TDStatus & 0x02);\r
-}\r
-\r
-UINT16\r
-GetTDStatusActualLength (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the actual number of bytes that were tansferred.\r
-  // the value is encoded as n-1. so return the decoded value.\r
-  //\r
-  return (UINT16) ((ptrTDStruct->TDData.TDStatusActualLength) + 1);\r
-}\r
-\r
-UINT16\r
-GetTDTokenMaxLength (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the maximum number of data bytes allowed for the trnasfer.\r
-  //\r
-  return (UINT16) ((ptrTDStruct->TDData.TDTokenMaxLen) + 1);\r
-}\r
-\r
-UINT8\r
-GetTDTokenEndPoint (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the endpoint number the transaction is targeting at.\r
-  //\r
-  return (UINT8) (ptrTDStruct->TDData.TDTokenEndPt);\r
-}\r
-\r
-UINT8\r
-GetTDTokenDeviceAddress (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the device address the transaction is targeting at.\r
-  //\r
-  return (UINT8) (ptrTDStruct->TDData.TDTokenDevAddr);\r
-}\r
-\r
-UINT8\r
-GetTDTokenPacketID (\r
-  IN  TD_STRUCT *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the Packet Identification information.\r
-  //\r
-  return (UINT8) (ptrTDStruct->TDData.TDTokenPID);\r
-}\r
-\r
-UINT8 *\r
-GetTDDataBuffer (\r
-  IN TD_STRUCT    *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the beginning address of the data buffer\r
-  // that involved in this transaction.\r
-  //\r
-  return ptrTDStruct->pTDBuffer;\r
-}\r
-\r
-BOOLEAN\r
-GetTDLinkPtrValidorInvalid (\r
-  IN TD_STRUCT     *ptrTDStruct\r
-  )\r
-{\r
-  //\r
-  // Retrieve the information of whether the Link Pointer field\r
-  // is valid or not.\r
-  //\r
-  if (ptrTDStruct->TDData.TDLinkPtrTerminate) {\r
-    return FALSE;\r
-  } else {\r
-    return TRUE;\r
-  }\r
-\r
-}\r
-\r
-UINTN\r
-CountTDsNumber (\r
-  IN TD_STRUCT     *PtrFirstTD\r
-  )\r
-{\r
-  UINTN     Number;\r
-  TD_STRUCT *ptr;\r
-  //\r
-  // Count the queued TDs number.\r
-  //\r
-  Number  = 0;\r
-  ptr     = PtrFirstTD;\r
-  while (ptr) {\r
-    ptr = (TD_STRUCT *) ptr->ptrNextTD;\r
-    Number++;\r
-  }\r
-\r
-  return Number;\r
-}\r
-\r
-\r
-\r
-VOID\r
-LinkTDToQH (\r
-  IN QH_STRUCT     *PtrQH,\r
-  IN TD_STRUCT     *PtrTD\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Link TD To QH\r
-\r
-Arguments:\r
-\r
-  PtrQH - QH_STRUCT\r
-  PtrTD - TD_STRUCT\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  if (PtrQH == NULL || PtrTD == NULL) {\r
-    return ;\r
-  }\r
-  //\r
-  //  Validate QH Vertical Ptr field\r
-  //\r
-  SetQHVerticalValidorInvalid (PtrQH, TRUE);\r
-\r
-  //\r
-  //  Vertical Ptr pointing to TD structure\r
-  //\r
-  SetQHVerticalQHorTDSelect (PtrQH, FALSE);\r
-\r
-  SetQHVerticalLinkPtr (PtrQH, (VOID *) PtrTD);\r
-\r
-  PtrQH->ptrDown = (VOID *) PtrTD;\r
-}\r
-\r
-VOID\r
-LinkTDToTD (\r
-  IN TD_STRUCT     *ptrPreTD,\r
-  IN TD_STRUCT     *PtrTD\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Link TD To TD\r
-\r
-Arguments:\r
-\r
-  ptrPreTD - Previous TD_STRUCT to be linked\r
-  PtrTD    - TD_STRUCT to link\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  if (ptrPreTD == NULL || PtrTD == NULL) {\r
-    return ;\r
-  }\r
-  //\r
-  // Depth first fashion\r
-  //\r
-  SetTDLinkPtrDepthorBreadth (ptrPreTD, TRUE);\r
-\r
-  //\r
-  // Link pointer pointing to TD struct\r
-  //\r
-  SetTDLinkPtrQHorTDSelect (ptrPreTD, FALSE);\r
-\r
-  //\r
-  // Validate the link pointer valid bit\r
-  //\r
-  SetTDLinkPtrValidorInvalid (ptrPreTD, TRUE);\r
-\r
-  SetTDLinkPtr (ptrPreTD, PtrTD);\r
-\r
-  ptrPreTD->ptrNextTD = (VOID *) PtrTD;\r
-}\r
-//\r
-// Transfer Schedule related Helper Functions\r
-//\r
-VOID\r
-SetorClearCurFrameListTerminate (\r
-  IN FRAMELIST_ENTRY     *pCurEntry,\r
-  IN BOOLEAN             IsSet\r
-  )\r
-{\r
-  //\r
-  // If TRUE, empty the frame. If FALSE, indicate the Pointer field is valid.\r
-  //\r
-  pCurEntry->FrameListPtrTerminate = (IsSet ? 1 : 0);\r
-}\r
-\r
-VOID\r
-SetCurFrameListQHorTD (\r
-  IN FRAMELIST_ENTRY     *pCurEntry,\r
-  IN BOOLEAN             IsQH\r
-  )\r
-{\r
-  //\r
-  // This bit indicates to the hardware whether the item referenced by the\r
-  // link pointer is a TD or a QH.\r
-  //\r
-  pCurEntry->FrameListPtrQSelect = (IsQH ? 1 : 0);\r
-}\r
-\r
-STATIC\r
-BOOLEAN\r
-IsCurFrameListQHorTD (\r
-  IN FRAMELIST_ENTRY     *pCurEntry\r
-  )\r
-{\r
-  //\r
-  // TRUE is QH\r
-  // FALSE is TD\r
-  //\r
-  return (BOOLEAN) (pCurEntry->FrameListPtrQSelect);\r
-}\r
-\r
-BOOLEAN\r
-GetCurFrameListTerminate (\r
-  IN FRAMELIST_ENTRY     *pCurEntry\r
-  )\r
-{\r
-  //\r
-  // TRUE means the frame is empty,\r
-  // FALSE means the link pointer field is valid.\r
-  //\r
-  return (BOOLEAN) (pCurEntry->FrameListPtrTerminate);\r
-}\r
-\r
-VOID\r
-SetCurFrameListPointer (\r
-  IN FRAMELIST_ENTRY     *pCurEntry,\r
-  IN UINT8               *ptr\r
-  )\r
-{\r
-  //\r
-  // Set the pointer field of the frame.\r
-  //\r
-  pCurEntry->FrameListPtr = (UINT32) ((UINTN) ptr >> 4);\r
-}\r
-\r
-VOID *\r
-GetCurFrameListPointer (\r
-  IN FRAMELIST_ENTRY     *pCurEntry\r
-  )\r
-{\r
-  //\r
-  // Get the link pointer of the frame.\r
-  //\r
-  return (VOID *) ((UINTN) (pCurEntry->FrameListPtr << 4));\r
-\r
-}\r
-\r
-VOID\r
-LinkQHToFrameList (\r
-  IN FRAMELIST_ENTRY     *pEntry,\r
-  IN UINT16              FrameListIndex,\r
-  IN QH_STRUCT           *PtrQH\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Link QH To Frame List\r
-\r
-Arguments:\r
-\r
-  pEntry           - FRAMELIST_ENTRY\r
-  FrameListIndex   - Frame List Index\r
-  PtrQH            - QH to link \r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  FRAMELIST_ENTRY *pCurFrame;\r
-  QH_STRUCT       *TempQH;\r
-  QH_STRUCT       *NextTempQH;\r
-  TD_STRUCT       *TempTD;\r
-  BOOLEAN         LINK;\r
-\r
-  //\r
-  // Get frame list entry that the link process will begin from.\r
-  //\r
-  pCurFrame = pEntry + FrameListIndex;\r
-\r
-  //\r
-  // if current frame is empty\r
-  // then link the specified QH directly to the Frame List.\r
-  //\r
-  if (GetCurFrameListTerminate (pCurFrame)) {\r
-    \r
-    //\r
-    // Link new QH to the frame list entry.\r
-    //\r
-    SetCurFrameListQHorTD (pCurFrame, TRUE);\r
-\r
-    SetCurFrameListPointer (pCurFrame, (UINT8 *) PtrQH);\r
-\r
-    //\r
-    // clear T bit in the Frame List, indicating that the frame list entry\r
-    // is no longer empty.\r
-    //\r
-    SetorClearCurFrameListTerminate (pCurFrame, FALSE);\r
-\r
-    return ;\r
-\r
-  } else {\r
-    //\r
-    // current frame list has link pointer\r
-    //\r
-    if (!IsCurFrameListQHorTD (pCurFrame)) {\r
-      //\r
-      //  a TD is linked to the framelist entry\r
-      //\r
-      TempTD = (TD_STRUCT *) GetCurFrameListPointer (pCurFrame);\r
-\r
-      while (GetTDLinkPtrValidorInvalid (TempTD)) {\r
-\r
-        if (IsTDLinkPtrQHOrTD (TempTD)) {\r
-          //\r
-          // QH linked next to the TD\r
-          //\r
-          break;\r
-        }\r
-\r
-        TempTD = (TD_STRUCT *) GetTDLinkPtr (TempTD);\r
-      }\r
-      \r
-      //\r
-      // either no ptr linked next to the TD or QH is linked next to the TD\r
-      //\r
-      if (!GetTDLinkPtrValidorInvalid (TempTD)) {\r
-        \r
-        //\r
-        // no ptr linked next to the TD\r
-        //\r
-        TempTD->ptrNextQH = PtrQH;\r
-        SetTDLinkPtrQHorTDSelect (TempTD, TRUE);\r
-        SetTDLinkPtr (TempTD, PtrQH);\r
-        SetTDLinkPtrValidorInvalid (TempTD, TRUE);\r
-        return ;\r
-\r
-      } else {\r
-        //\r
-        //  QH is linked next to the TD\r
-        //\r
-        TempQH = (QH_STRUCT *) GetTDLinkPtr (TempTD);\r
-      }\r
-    } else {\r
-      //\r
-      // a QH is linked to the framelist entry\r
-      //\r
-      TempQH = (QH_STRUCT *) GetCurFrameListPointer (pCurFrame);\r
-    }\r
-    \r
-    //\r
-    // Set up Flag\r
-    //\r
-    LINK = TRUE;\r
-\r
-    //\r
-    // Avoid the same qh repeated linking in one frame entry\r
-    //\r
-    if (TempQH == PtrQH) {\r
-      LINK = FALSE;\r
-      return ;\r
-    }\r
-    //\r
-    // if current QH has next QH connected\r
-    //\r
-    while (GetQHHorizontalValidorInvalid (TempQH)) {\r
-      //\r
-      // Get next QH pointer\r
-      //\r
-      NextTempQH = (QH_STRUCT *) GetQHHorizontalLinkPtr (TempQH);\r
-\r
-      //\r
-      // Bulk transfer qh may be self-linked,\r
-      // so, the code below is to aVOID dead-loop when meeting self-linked qh\r
-      //\r
-      if (NextTempQH == TempQH) {\r
-        LINK = FALSE;\r
-        break;\r
-      }\r
-\r
-      TempQH = NextTempQH;\r
-\r
-      //\r
-      // Avoid the same qh repeated linking in one frame entry\r
-      //\r
-      if (TempQH == PtrQH) {\r
-        LINK = FALSE;\r
-      }\r
-    }\r
-\r
-    if (LINK) {\r
-      TempQH->ptrNext = PtrQH;\r
-      SetQHHorizontalQHorTDSelect (TempQH, TRUE);\r
-      SetQHHorizontalLinkPtr (TempQH, PtrQH);\r
-      SetQHHorizontalValidorInvalid (TempQH, TRUE);\r
-    }\r
-\r
-    return ;\r
-  }\r
-}\r
-\r
-EFI_STATUS\r
-ExecuteControlTransfer (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  TD_STRUCT      *PtrTD,\r
-  IN  UINT32         wIndex,\r
-  OUT UINTN          *ActualLen,\r
-  IN  UINTN          TimeOut,\r
-  OUT UINT32         *TransferResult\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Execute Control Transfer\r
-\r
-Arguments:\r
-\r
-  HcDev            - USB_HC_DEV\r
-  PtrTD            - TD_STRUCT\r
-  wIndex           - No use\r
-  ActualLen        - Actual transfered Len \r
-  TimeOut          - TimeOut value in milliseconds\r
-  TransferResult   - Transfer result\r
-Returns:\r
-\r
-  EFI_SUCCESS      - Sucess\r
-  EFI_DEVICE_ERROR - Error\r
-  \r
-\r
---*/\r
-{\r
-  UINTN   ErrTDPos;\r
-  UINTN   Delay;\r
-  UINTN   RequiredLen;\r
-  BOOLEAN TransferFinished;\r
-\r
-  ErrTDPos        = 0;\r
-  *TransferResult = EFI_USB_NOERROR;\r
-  RequiredLen     = *ActualLen;\r
-  *ActualLen      = 0;\r
-\r
-  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;\r
-\r
-  do {\r
-    TransferFinished = CheckTDsResults (\r
-                         PtrTD,\r
-                         RequiredLen,\r
-                         TransferResult,\r
-                         &ErrTDPos,\r
-                         ActualLen\r
-                         );\r
-\r
-    if (TransferFinished) {\r
-      break;\r
-    }\r
-       \r
-    //\r
-    // TD is inactive, which means the control transfer is end.\r
-    //\r
-    if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {\r
-      break;\r
-    } \r
-\r
-    gBS->Stall (50);\r
-\r
-  } while (Delay--);\r
-\r
-  if (*TransferResult != EFI_USB_NOERROR) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ExecBulkorSyncInterruptTransfer (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  TD_STRUCT      *PtrTD,\r
-  IN  UINT32         wIndex,\r
-  OUT UINTN          *ActualLen,\r
-  OUT UINT8          *DataToggle,\r
-  IN  UINTN          TimeOut,\r
-  OUT UINT32         *TransferResult\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Execute Bulk or SyncInterrupt Transfer\r
-\r
-Arguments:\r
-\r
-  HcDev            - USB_HC_DEV\r
-  PtrTD            - TD_STRUCT\r
-  wIndex           - No use\r
-  ActualLen        - Actual transfered Len \r
-  DataToggle       - Data Toggle\r
-  TimeOut          - TimeOut value in milliseconds\r
-  TransferResult   - Transfer result\r
-Returns:\r
-\r
-  EFI_SUCCESS      - Sucess\r
-  EFI_DEVICE_ERROR - Error\r
---*/\r
-{\r
-  UINTN   ErrTDPos;\r
-  UINTN   ScrollNum;\r
-  UINTN   Delay;\r
-  UINTN   RequiredLen;\r
-  BOOLEAN TransferFinished;\r
-\r
-  ErrTDPos        = 0;\r
-  *TransferResult = EFI_USB_NOERROR;\r
-  RequiredLen     = *ActualLen;\r
-  *ActualLen      = 0;\r
-\r
-  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;\r
-\r
-  do {\r
-\r
-    TransferFinished = CheckTDsResults (\r
-                         PtrTD,\r
-                         RequiredLen,\r
-                         TransferResult,\r
-                         &ErrTDPos,\r
-                         ActualLen\r
-                         );\r
-                        \r
-    if (TransferFinished) {\r
-      break;\r
-    }\r
-       \r
-    //\r
-    // TD is inactive, which means bulk or interrupt transfer's end.\r
-    //    \r
-    if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {\r
-      break;\r
-    }\r
-\r
-    gBS->Stall (50);\r
-\r
-  } while (Delay--);\r
-\r
-  //\r
-  // has error\r
-  //\r
-  if (*TransferResult != EFI_USB_NOERROR) {\r
-  \r
-    //\r
-    // scroll the Data Toggle back to the last success TD\r
-    //\r
-    ScrollNum = CountTDsNumber (PtrTD) - ErrTDPos;\r
-    if (ScrollNum & 0x1) {\r
-      *DataToggle ^= 1;\r
-    }\r
-\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-DelLinkSingleQH (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  QH_STRUCT      *PtrQH,\r
-  IN  UINT16         FrameListIndex,\r
-  IN  BOOLEAN        SearchOther,\r
-  IN  BOOLEAN        Delete\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Unlink from frame list and delete single QH\r
-Arguments:\r
-\r
-  HcDev            - USB_HC_DEV\r
-  PtrQH            - QH_STRUCT\r
-  FrameListIndex   - Frame List Index\r
-  SearchOther      - Search Other QH\r
-  Delete           - TRUE is to delete the QH\r
-Returns:\r
-  VOID\r
---*/\r
-{\r
-  FRAMELIST_ENTRY *pCurFrame;\r
-  UINTN           Index;\r
-  UINTN           BeginFrame;\r
-  UINTN           EndFrame;\r
-  QH_STRUCT       *CurrentQH;\r
-  QH_STRUCT       *NextQH;\r
-  TD_STRUCT       *CurrentTD;\r
-  VOID            *PtrPreQH;\r
-  BOOLEAN         Found;\r
-\r
-  NextQH    = NULL;\r
-  PtrPreQH  = NULL;\r
-  Found     = FALSE;\r
-\r
-  if (PtrQH == NULL) {\r
-    return ;\r
-  }\r
-\r
-  if (SearchOther) {\r
-    BeginFrame  = 0;\r
-    EndFrame    = 1024;\r
-  } else {\r
-    BeginFrame  = FrameListIndex;\r
-    EndFrame    = FrameListIndex + 1;\r
-  }\r
-\r
-  for (Index = BeginFrame; Index < EndFrame; Index++) {\r
-\r
-    pCurFrame = HcDev->FrameListEntry + (Index & 0x3FF);\r
-\r
-    if (GetCurFrameListTerminate (pCurFrame)) {\r
-      //\r
-      // current frame list is empty,search next frame list entry\r
-      //\r
-      continue;\r
-    }\r
-\r
-    if (!IsCurFrameListQHorTD (pCurFrame)) {\r
-      //\r
-      // TD linked to current framelist\r
-      //\r
-      CurrentTD = (TD_STRUCT *) GetCurFrameListPointer (pCurFrame);\r
-\r
-      while (GetTDLinkPtrValidorInvalid (CurrentTD)) {\r
-\r
-        if (IsTDLinkPtrQHOrTD (CurrentTD)) {\r
-          //\r
-          // QH linked next to the TD,break while ()\r
-          //\r
-          break;\r
-        }\r
-\r
-        CurrentTD = (TD_STRUCT *) GetTDLinkPtr (CurrentTD);\r
-      }\r
-\r
-      if (!GetTDLinkPtrValidorInvalid (CurrentTD)) {\r
-        //\r
-        // no QH linked next to the last TD,\r
-        // search next frame list\r
-        //\r
-        continue;\r
-      }\r
-      \r
-      //\r
-      // a QH linked next to the last TD\r
-      //\r
-      CurrentQH = (QH_STRUCT *) GetTDLinkPtr (CurrentTD);\r
-\r
-      PtrPreQH  = CurrentTD;\r
-\r
-    } else {\r
-      //\r
-      // a QH linked to current framelist\r
-      //\r
-      CurrentQH = (QH_STRUCT *) GetCurFrameListPointer (pCurFrame);\r
-\r
-      PtrPreQH  = NULL;\r
-    }\r
-\r
-    if (CurrentQH == PtrQH) {\r
-\r
-      if (GetQHHorizontalValidorInvalid (PtrQH)) {\r
-        //\r
-        // there is QH connected after the QH found\r
-        //\r
-        //\r
-        // retrieve nex qh pointer of the qh found.\r
-        //\r
-        NextQH = GetQHHorizontalLinkPtr (PtrQH);\r
-      } else {\r
-        NextQH = NULL;\r
-      }\r
-\r
-      if (PtrPreQH) {\r
-        //\r
-        // QH linked to a TD struct\r
-        //\r
-        CurrentTD = (TD_STRUCT *) PtrPreQH;\r
-\r
-        SetTDLinkPtrValidorInvalid (CurrentTD, (BOOLEAN) ((NextQH == NULL) ? FALSE : TRUE));\r
-        SetTDLinkPtr (CurrentTD, NextQH);\r
-        CurrentTD->ptrNextQH = NextQH;\r
-\r
-      } else {\r
-        //\r
-        // QH linked directly to current framelist entry\r
-        //\r
-        SetorClearCurFrameListTerminate (pCurFrame, (BOOLEAN) ((NextQH == NULL) ? TRUE : FALSE));\r
-        SetCurFrameListPointer (pCurFrame, (UINT8 *) NextQH);\r
-      }\r
-\r
-      Found = TRUE;\r
-      //\r
-      // search next framelist entry\r
-      //\r
-      continue;\r
-    }\r
-\r
-    while (GetQHHorizontalValidorInvalid (CurrentQH)) {\r
-\r
-      PtrPreQH = CurrentQH;\r
-      //\r
-      // Get next horizontal linked QH\r
-      //\r
-      CurrentQH = (QH_STRUCT *) GetQHHorizontalLinkPtr (CurrentQH);\r
-      //\r
-      // the qh is found\r
-      //\r
-      if (CurrentQH == PtrQH) {\r
-        break;\r
-      }\r
-    }\r
-    \r
-    //\r
-    // search next frame list entry\r
-    //\r
-    if (CurrentQH != PtrQH) {\r
-      //\r
-      // Not find the QH\r
-      //\r
-      continue;\r
-    }\r
-    //\r
-    // find the specified qh, then delink it from\r
-    // the horizontal QH list in the frame entry.\r
-    //\r
-    \r
-    if (GetQHHorizontalValidorInvalid (PtrQH)) {\r
-      //\r
-      // there is QH connected after the QH found\r
-      //\r
-      //\r
-      // retrieve nex qh pointer of the qh found.\r
-      //\r
-      NextQH = GetQHHorizontalLinkPtr (PtrQH);\r
-\r
-    } else {\r
-      //\r
-      // NO QH connected after the QH found\r
-      //\r
-      NextQH = NULL;\r
-      //\r
-      // NULL the previous QH's link ptr and set Terminate field.\r
-      //\r
-      SetQHHorizontalValidorInvalid ((QH_STRUCT *) PtrPreQH, FALSE);\r
-    }\r
-\r
-    SetQHHorizontalLinkPtr ((QH_STRUCT *) PtrPreQH, NextQH);\r
-    ((QH_STRUCT *) PtrPreQH)->ptrNext = NextQH;\r
-\r
-    Found = TRUE;\r
-  }\r
-\r
-  if (Found && Delete) {\r
-    //\r
-    // free memory once used by the specific QH\r
-    //\r
-    UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-\r
-VOID\r
-DeleteQueuedTDs (\r
-  IN USB_HC_DEV     *HcDev,\r
-  IN TD_STRUCT      *PtrFirstTD\r
-  )\r
-/*++\r
-Routine Description:\r
-\r
-  Delete Queued TDs\r
-Arguments:\r
-\r
-  HcDev       - USB_HC_DEV\r
-  PtrFirstTD  - TD link list head\r
-\r
-Returns:\r
-  VOID\r
-\r
---*/\r
-{\r
-  TD_STRUCT *Tptr1;\r
-  TD_STRUCT *Tptr2;\r
-\r
-  Tptr1 = PtrFirstTD;\r
-  //\r
-  // Delete all the TDs in a queue.\r
-  //\r
-  while (Tptr1) {\r
-\r
-    Tptr2 = Tptr1;\r
-\r
-    if (!GetTDLinkPtrValidorInvalid (Tptr2)) {\r
-      Tptr1 = NULL;\r
-    } else {\r
-\r
-      Tptr1 = GetTDLinkPtr (Tptr2);\r
-\r
-      //\r
-      // TD link to itself\r
-      //\r
-      if (Tptr1 == Tptr2) {\r
-        Tptr1 = NULL;\r
-      }\r
-    }\r
-\r
-    UhciFreePool (HcDev, (UINT8 *) Tptr2, sizeof (TD_STRUCT));\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-VOID\r
-InsertQHTDToINTList (\r
-  IN USB_HC_DEV                          *HcDev,\r
-  IN QH_STRUCT                           *PtrQH,\r
-  IN TD_STRUCT                           *PtrFirstTD,\r
-  IN UINT8                               DeviceAddress,\r
-  IN UINT8                               EndPointAddress,\r
-  IN UINT8                               DataToggle,\r
-  IN UINTN                               DataLength,\r
-  IN UINTN                               PollingInterval,\r
-  IN VOID                                *Mapping,\r
-  IN UINT8                               *DataBuffer,\r
-  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction,\r
-  IN VOID                                *Context\r
-  )\r
-/*++\r
-Routine Description:\r
-  Insert QH and TD To Interrupt List\r
-Arguments:\r
-\r
-  HcDev           - USB_HC_DEV\r
-  PtrQH           - QH_STRUCT\r
-  PtrFirstTD      - First TD_STRUCT\r
-  DeviceAddress   - Device Address\r
-  EndPointAddress - EndPoint Address\r
-  DataToggle      - Data Toggle\r
-  DataLength      - Data length \r
-  PollingInterval - Polling Interval when inserted to frame list\r
-  Mapping         - Mapping alue  \r
-  DataBuffer      - Data buffer\r
-  CallBackFunction- CallBackFunction after interrupt transfeer\r
-  Context         - CallBackFunction Context passed as function parameter\r
-Returns:\r
-  EFI_SUCCESS            - Sucess\r
-  EFI_INVALID_PARAMETER  - Paremeter is error \r
-\r
---*/\r
-{\r
-  INTERRUPT_LIST  *Node;\r
-\r
-  Node = AllocatePool (sizeof (INTERRUPT_LIST));\r
-  if (Node == NULL) {\r
-    return ;\r
-  }\r
-  \r
-  //\r
-  // Fill Node field\r
-  //\r
-  Node->Signature     = INTERRUPT_LIST_SIGNATURE;\r
-  Node->DevAddr       = DeviceAddress;\r
-  Node->EndPoint      = EndPointAddress;\r
-  Node->PtrQH         = PtrQH;\r
-  Node->PtrFirstTD    = PtrFirstTD;\r
-  Node->DataToggle    = DataToggle;\r
-  Node->DataLen       = DataLength;\r
-  Node->PollInterval  = PollingInterval;\r
-  Node->Mapping       = Mapping;\r
-  //\r
-  // DataBuffer is allocated host memory, not mapped memory\r
-  //\r
-  Node->DataBuffer        = DataBuffer;\r
-  Node->InterruptCallBack = CallBackFunction;\r
-  Node->InterruptContext  = Context;\r
-\r
-  //\r
-  // insert the new interrupt transfer to the head of the list.\r
-  // The interrupt transfer's monitor function scans the whole list from head\r
-  // to tail. The new interrupt transfer MUST be added to the head of the list\r
-  // for the sake of error recovery.\r
-  //\r
-  InsertHeadList (&(HcDev->InterruptListHead), &(Node->Link));\r
-\r
-  return ;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-DeleteAsyncINTQHTDs (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  IN  UINT8          DeviceAddress,\r
-  IN  UINT8          EndPointAddress,\r
-  OUT UINT8          *DataToggle\r
-  )\r
-/*++\r
-Routine Description:\r
-\r
-  Delete Async INT QH and TDs\r
-Arguments:\r
-\r
-  HcDev           - USB_HC_DEV\r
-  DeviceAddress   - Device Address\r
-  EndPointAddress - EndPoint Address\r
-  DataToggle      - Data Toggle\r
-\r
-Returns:\r
-  EFI_SUCCESS            - Sucess\r
-  EFI_INVALID_PARAMETER  - Paremeter is error \r
-\r
---*/\r
-{\r
-  QH_STRUCT       *MatchQH;\r
-  QH_STRUCT       *ptrNextQH;\r
-  TD_STRUCT       *MatchTD;\r
-  LIST_ENTRY      *Link;\r
-  INTERRUPT_LIST  *MatchList;\r
-  INTERRUPT_LIST  *PtrList;\r
-  BOOLEAN         Found;\r
-\r
-  UINT32          Result;\r
-  UINTN           ErrTDPos;\r
-  UINTN           ActualLen;\r
-\r
-  MatchQH   = NULL;\r
-  MatchTD   = NULL;\r
-  MatchList = NULL;\r
-\r
-  //\r
-  // no interrupt transaction exists\r
-  //\r
-  if (IsListEmpty (&(HcDev->InterruptListHead))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // find the correct QH-TD that need to delete\r
-  // (by matching Device address and EndPoint number to match QH-TD )\r
-  //\r
-  Found = FALSE;\r
-  Link  = &(HcDev->InterruptListHead);\r
-  do {\r
-\r
-    Link    = Link->ForwardLink;\r
-    PtrList = INTERRUPT_LIST_FROM_LINK (Link);\r
-\r
-    if ((PtrList->DevAddr == DeviceAddress) && ((PtrList->EndPoint & 0x0f) == (EndPointAddress & 0x0f))) {\r
-      MatchList = PtrList;\r
-\r
-      Found     = TRUE;\r
-      break;\r
-    }\r
-\r
-  } while (Link->ForwardLink != &(HcDev->InterruptListHead));\r
-\r
-  if (!Found) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // get current endpoint's data toggle bit and save.\r
-  //\r
-  ExecuteAsyncINTTDs (HcDev, MatchList, &Result, &ErrTDPos, &ActualLen);\r
-  UpdateAsyncINTQHTDs (MatchList, Result, (UINT32) ErrTDPos);\r
-  *DataToggle = MatchList->DataToggle;\r
-\r
-  MatchTD     = MatchList->PtrFirstTD;\r
-  MatchQH     = MatchList->PtrQH;\r
-  //\r
-  // find the first matching QH position in the FrameList\r
-  //\r
-  while (MatchQH) {\r
-\r
-    ptrNextQH = MatchQH->ptrNextIntQH;\r
-\r
-    //\r
-    // Search all the entries\r
-    //\r
-    DelLinkSingleQH (HcDev, MatchQH, 0, TRUE, TRUE);\r
-\r
-    MatchQH = ptrNextQH;\r
-  }\r
-  \r
-  //\r
-  // Call PciIo->Unmap() to unmap the busmaster read/write\r
-  //\r
-  HcDev->PciIo->Unmap (HcDev->PciIo, MatchList->Mapping);\r
-\r
-  //\r
-  // free host data buffer allocated,\r
-  // mapped data buffer is freed by Unmap\r
-  //\r
-  if (MatchList->DataBuffer != NULL) {\r
-    gBS->FreePool (MatchList->DataBuffer);\r
-  }\r
-  \r
-  //\r
-  // at last delete the TDs, to aVOID problems\r
-  //\r
-  DeleteQueuedTDs (HcDev, MatchTD);\r
-\r
-  //\r
-  // remove Match node from interrupt list\r
-  //\r
-  RemoveEntryList (&(MatchList->Link));\r
-  gBS->FreePool (MatchList);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-CheckTDsResults (\r
-  IN  TD_STRUCT     *PtrTD,\r
-  IN  UINTN         RequiredLen,\r
-  OUT UINT32        *Result,\r
-  OUT UINTN         *ErrTDPos,\r
-  OUT UINTN         *ActualTransferSize\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Check TDs Results\r
-\r
-Arguments:\r
-\r
-  PtrTD               - TD_STRUCT to check\r
-  RequiredLen         - Required Len\r
-  Result              - Transfer result\r
-  ErrTDPos            - Error TD Position\r
-  ActualTransferSize  - Actual Transfer Size\r
-\r
-Returns:\r
-\r
-  TRUE  - Sucess\r
-  FALSE - Fail\r
-\r
---*/\r
-{\r
-  UINTN Len;\r
-\r
-  *Result   = EFI_USB_NOERROR;\r
-  *ErrTDPos = 0;\r
-\r
-  //\r
-  // Init to zero.\r
-  //\r
-  *ActualTransferSize = 0;\r
-\r
-  while (PtrTD) {\r
-\r
-    if (IsTDStatusActive (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_NOTEXECUTE;\r
-    }\r
-\r
-    if (IsTDStatusStalled (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_STALL;\r
-    }\r
-\r
-    if (IsTDStatusBufferError (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_BUFFER;\r
-    }\r
-\r
-    if (IsTDStatusBabbleError (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_BABBLE;\r
-    }\r
-\r
-    if (IsTDStatusNAKReceived (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_NAK;\r
-    }\r
-\r
-    if (IsTDStatusCRCTimeOutError (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_TIMEOUT;\r
-    }\r
-\r
-    if (IsTDStatusBitStuffError (PtrTD)) {\r
-      *Result |= EFI_USB_ERR_BITSTUFF;\r
-    }\r
-   \r
-    //\r
-    // if any error encountered, stop processing the left TDs.\r
-    //\r
-    if (*Result) {\r
-      return FALSE;\r
-    }\r
-\r
-    Len = GetTDStatusActualLength (PtrTD) & 0x7FF;\r
-    *ActualTransferSize += Len;\r
-\r
-    if (*ActualTransferSize <= RequiredLen && Len < PtrTD->TDData.TDTokenMaxLen) {\r
-      //\r
-      // transter finished and actural length less than required length\r
-      //\r
-      goto Done;\r
-    }\r
-    //\r
-    // Accumulate actual transferred data length in each TD.\r
-    //\r
-    PtrTD = (TD_STRUCT *) (PtrTD->ptrNextTD);\r
-    //\r
-    // Record the first Error TD's position in the queue,\r
-    // this value is zero-based.\r
-    //\r
-    (*ErrTDPos)++;\r
-  }\r
-\r
-Done:\r
-  return TRUE;\r
-}\r
-\r
-\r
-VOID\r
-ExecuteAsyncINTTDs (\r
-  IN  USB_HC_DEV         *HcDev,\r
-  IN  INTERRUPT_LIST     *PtrList,\r
-  OUT UINT32             *Result,\r
-  OUT UINTN              *ErrTDPos,\r
-  OUT UINTN              *ActualLen\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Execute Async Interrupt TDs\r
-\r
-Arguments:\r
-\r
-  HcDev     - USB_HC_DEV\r
-  PtrList   - INTERRUPT_LIST\r
-  Result    - Transfer result\r
-  ErrTDPos  - Error TD Position\r
-  ActualTransferSize  - Actual Transfer Size\r
-  \r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  //\r
-  // *ErrTDPos is zero-based value, indicating the first error TD's position\r
-  // in the TDs' sequence.\r
-  // *ErrTDPos value is only valid when *Result is not equal NOERROR.\r
-  //\r
-  UINTN RequiredLen;\r
-\r
-  RequiredLen = *ActualLen;\r
-  CheckTDsResults (PtrList->PtrFirstTD, RequiredLen, Result, ErrTDPos, ActualLen);\r
-\r
-  return ;\r
-}\r
-\r
-\r
-VOID\r
-UpdateAsyncINTQHTDs (\r
-  IN INTERRUPT_LIST     *PtrList,\r
-  IN UINT32             Result,\r
-  IN UINT32             ErrTDPos\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Update Async Interrupt QH and TDs\r
-\r
-Arguments:\r
-\r
-  PtrList   - INTERRUPT_LIST\r
-  Result    - Transfer reslut\r
-  ErrTDPos  - Error TD Position\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  QH_STRUCT *PtrFirstQH;\r
-  QH_STRUCT *PtrQH;\r
-  TD_STRUCT *PtrFirstTD;\r
-  TD_STRUCT *PtrTD;\r
-  UINT8     DataToggle;\r
-  UINT32    Index;\r
-\r
-  PtrFirstQH  = PtrList->PtrQH;\r
-  PtrFirstTD  = PtrList->PtrFirstTD;\r
-\r
-  DataToggle  = 0;\r
-\r
-  if (Result == EFI_USB_NOERROR) {\r
-\r
-    PtrTD = PtrFirstTD;\r
-    while (PtrTD) {\r
-      DataToggle  = GetTDTokenDataToggle (PtrTD);\r
-      PtrTD       = PtrTD->ptrNextTD;\r
-    }\r
-    \r
-    //\r
-    // save current DataToggle value to interrupt list.\r
-    // this value is used for tracing the interrupt endpoint DataToggle.\r
-    // when this interrupt transfer is deleted, the last DataToggle is saved\r
-    //\r
-    PtrList->DataToggle = DataToggle;\r
-\r
-    PtrTD               = PtrFirstTD;\r
-\r
-    //\r
-    // Since DataToggle bit should toggle after each success transaction,\r
-    // the First TD's DataToggle bit will be updated to XOR of Last TD's\r
-    // DataToggle bit. If the First TD's DataToggle bit is not equal Last\r
-    // TD's DataToggle bit, that means it already be the XOR of Last TD's,\r
-    // so no update is needed.\r
-    //\r
-    if (DataToggle == GetTDTokenDataToggle (PtrFirstTD)) {\r
-      PtrTD = PtrFirstTD;\r
-      while (PtrTD) {\r
-\r
-        DataToggle ^= 1;\r
-        if (DataToggle) {\r
-          SetTDTokenDataToggle1 (PtrTD);\r
-        } else {\r
-          SetTDTokenDataToggle0 (PtrTD);\r
-        }\r
-\r
-        PtrTD = PtrTD->ptrNextTD;\r
-      }\r
-    }\r
-    //\r
-    // restore Link Pointer of QH to First TD\r
-    // (because QH's Link Pointer will change during TD execution)\r
-    //\r
-    PtrQH = PtrFirstQH;\r
-    while (PtrQH) {\r
-\r
-      LinkTDToQH (PtrQH, PtrFirstTD);\r
-      PtrQH = PtrQH->ptrNextIntQH;\r
-    }\r
-    \r
-    //\r
-    // set all the TDs active\r
-    //\r
-    PtrTD = PtrFirstTD;\r
-    while (PtrTD) {\r
-      SetTDStatusActiveorInactive (PtrTD, TRUE);\r
-      PtrTD = PtrTD->ptrNextTD;\r
-    }\r
-\r
-  } else if (((Result & EFI_USB_ERR_NOTEXECUTE) == EFI_USB_ERR_NOTEXECUTE) ||\r
-           ((Result & EFI_USB_ERR_NAK) == EFI_USB_ERR_NAK)\r
-          ) {\r
-    //\r
-    // no update\r
-    //\r
-  } else {\r
-    //\r
-    // Have Errors\r
-    //\r
-    PtrTD = PtrFirstTD;\r
-    //\r
-    // not first TD error\r
-    //\r
-    if (ErrTDPos != 0) {\r
-      //\r
-      // get the last success TD\r
-      //\r
-      for (Index = 1; Index < ErrTDPos; Index++) {\r
-        PtrTD = PtrTD->ptrNextTD;\r
-      }\r
-      //\r
-      // update Data Toggle in the interrupt list node\r
-      //\r
-      PtrList->DataToggle = GetTDTokenDataToggle (PtrTD);\r
-\r
-      //\r
-      // get the error TD\r
-      //\r
-      PtrTD = PtrTD->ptrNextTD;\r
-\r
-    } else {\r
-      PtrList->DataToggle = GetTDTokenDataToggle (PtrTD);\r
-    }\r
-    //\r
-    // do not restore the QH's vertical link pointer,\r
-    // let the callback function do the rest of error handling.\r
-    //\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-VOID\r
-ReleaseInterruptList (\r
-  IN USB_HC_DEV         *HcDev,\r
-  IN LIST_ENTRY         *ListHead\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Release Interrupt List\r
-Arguments:\r
-\r
-  HcDev     - USB_HC_DEV\r
-  ListHead  - List head\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  LIST_ENTRY      *Link;\r
-  LIST_ENTRY      *SavedLink;\r
-  INTERRUPT_LIST  *pNode;\r
-  TD_STRUCT       *PtrTD;\r
-  TD_STRUCT       *ptrNextTD;\r
-  QH_STRUCT       *PtrQH;\r
-  QH_STRUCT       *SavedQH;\r
-\r
-  if (ListHead == NULL) {\r
-    return ;\r
-  }\r
-\r
-  Link = ListHead;\r
-\r
-  //\r
-  // Free all the resources in the interrupt list\r
-  //\r
-  SavedLink = Link->ForwardLink;\r
-  while (!IsListEmpty (ListHead)) {\r
-\r
-    Link      = SavedLink;\r
-\r
-    SavedLink = Link->ForwardLink;\r
-\r
-    pNode     = INTERRUPT_LIST_FROM_LINK (Link);\r
-\r
-    RemoveEntryList (&pNode->Link);\r
-\r
-    SavedQH = pNode->PtrQH;\r
-    for (PtrQH = SavedQH; PtrQH != NULL; PtrQH = SavedQH) {\r
-      SavedQH = PtrQH->ptrNextIntQH;\r
-      UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));\r
-    }\r
-\r
-    PtrTD = pNode->PtrFirstTD;\r
-    while (PtrTD != NULL) {\r
-\r
-      ptrNextTD = PtrTD->ptrNextTD;\r
-      UhciFreePool (HcDev, (UINT8 *) PtrTD, sizeof (TD_STRUCT));\r
-      PtrTD = ptrNextTD;\r
-    }\r
-\r
-    gBS->FreePool (pNode);\r
-  }\r
-}\r
-\r
-\r
-EFI_STATUS\r
-InitializeMemoryManagement (\r
-  IN USB_HC_DEV     *HcDev\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Initialize Memory Management\r
-\r
-Arguments:\r
-\r
-  HcDev - USB_HC_DEV\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS -  Success\r
---*/\r
-{\r
-  MEMORY_MANAGE_HEADER  *MemoryHeader;\r
-  EFI_STATUS            Status;\r
-  UINTN                 MemPages;\r
-\r
-  MemPages  = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
-  Status    = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  HcDev->MemoryHeader = MemoryHeader;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CreateMemoryBlock (\r
-  IN  USB_HC_DEV               *HcDev,\r
-  OUT MEMORY_MANAGE_HEADER     **MemoryHeader,\r
-  IN  UINTN                    MemoryBlockSizeInPages\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
-  and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
-\r
-\r
-Arguments:\r
-\r
-  HcDev        - USB_HC_DEV\r
-  MemoryHeader - MEMORY_MANAGE_HEADER to output\r
-  MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
-Returns:\r
-\r
-  EFI_SUCCESS -  Success\r
---*/\r
-{\r
-  EFI_STATUS            Status;\r
-  VOID                  *CommonBuffer;\r
-  EFI_PHYSICAL_ADDRESS  MappedAddress;\r
-  UINTN                 MemoryBlockSizeInBytes;\r
-  VOID                  *Mapping;\r
-\r
-  //\r
-  // Allocate memory for MemoryHeader\r
-  //\r
-  *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));\r
-  if (*MemoryHeader == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  (*MemoryHeader)->Next = NULL;\r
-\r
-  //\r
-  // set Memory block size\r
-  //\r
-  (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
-\r
-  //\r
-  // each bit in Bit Array will manage 32 bytes memory in memory block\r
-  //\r
-  (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;\r
-\r
-  //\r
-  // Allocate memory for BitArray\r
-  //\r
-  (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);\r
-  if ((*MemoryHeader)->BitArrayPtr == NULL) {\r
-    gBS->FreePool (*MemoryHeader);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  \r
-  //\r
-  // Memory Block uses MemoryBlockSizeInPages pages,\r
-  // and it is allocated as common buffer use.\r
-  //\r
-  Status = HcDev->PciIo->AllocateBuffer (\r
-                           HcDev->PciIo,\r
-                           AllocateAnyPages,\r
-                           EfiBootServicesData,\r
-                           MemoryBlockSizeInPages,\r
-                           &CommonBuffer,\r
-                           0\r
-                           );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
-    gBS->FreePool (*MemoryHeader);\r
-    return Status;\r
-  }\r
-\r
-  MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
-  Status = HcDev->PciIo->Map (\r
-                           HcDev->PciIo,\r
-                           EfiPciIoOperationBusMasterCommonBuffer,\r
-                           CommonBuffer,\r
-                           &MemoryBlockSizeInBytes,\r
-                           &MappedAddress,\r
-                           &Mapping\r
-                           );\r
-  //\r
-  // if returned Mapped size is less than the size we request,do not support.\r
-  //\r
-  if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {\r
-    HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
-    gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
-    gBS->FreePool (*MemoryHeader);\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  //\r
-  // Set Memory block initial address\r
-  //\r
-  (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);\r
-  (*MemoryHeader)->Mapping        = Mapping;\r
-\r
-  ZeroMem (\r
-    (*MemoryHeader)->MemoryBlockPtr,\r
-    EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)\r
-    );\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FreeMemoryHeader (\r
-  IN USB_HC_DEV               *HcDev,\r
-  IN MEMORY_MANAGE_HEADER     *MemoryHeader\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Free Memory Header\r
-\r
-Arguments:\r
-\r
-  HcDev         - USB_HC_DEV\r
-  MemoryHeader  - MemoryHeader to be freed\r
-\r
-Returns:\r
-\r
-  EFI_INVALID_PARAMETER - Parameter is error\r
-  EFI_SUCCESS           - Success\r
-\r
---*/\r
-{\r
-  if ((MemoryHeader == NULL) || (HcDev == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // unmap the common buffer used by the memory block\r
-  //\r
-  HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);\r
-\r
-  //\r
-  // free common buffer\r
-  //\r
-  HcDev->PciIo->FreeBuffer (\r
-                  HcDev->PciIo,\r
-                  EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),\r
-                  MemoryHeader->MemoryBlockPtr\r
-                  );\r
-  //\r
-  // free bit array\r
-  //\r
-  gBS->FreePool (MemoryHeader->BitArrayPtr);\r
-  //\r
-  // free memory header\r
-  //\r
-  gBS->FreePool (MemoryHeader);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-UhciAllocatePool (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT UINT8          **Pool,\r
-  IN  UINTN          AllocSize\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Uhci Allocate Pool\r
-\r
-Arguments:\r
-\r
-  HcDev     - USB_HC_DEV\r
-  Pool      - Place to store pointer to the memory buffer\r
-  AllocSize - Alloc Size\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - Success\r
-\r
---*/\r
-{\r
-  MEMORY_MANAGE_HEADER  *MemoryHeader;\r
-  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
-  MEMORY_MANAGE_HEADER  *NewMemoryHeader;\r
-  UINTN                 RealAllocSize;\r
-  UINTN                 MemoryBlockSizeInPages;\r
-  EFI_STATUS            Status;\r
-\r
-  *Pool         = NULL;\r
-\r
-  MemoryHeader  = HcDev->MemoryHeader;\r
-  ASSERT (MemoryHeader != NULL);\r
-\r
-  //\r
-  // allocate unit is 32 bytes (align on 32 byte)\r
-  //\r
-  if (AllocSize & 0x1F) {\r
-    RealAllocSize = (AllocSize / 32 + 1) * 32;\r
-  } else {\r
-    RealAllocSize = AllocSize;\r
-  }\r
-  \r
-  //\r
-  // There may be linked MemoryHeaders.\r
-  // To allocate a free pool in Memory blocks,\r
-  // must search in the MemoryHeader link list\r
-  // until enough free pool is found.\r
-  //\r
-  Status = EFI_NOT_FOUND;\r
-  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;\r
-       TempHeaderPtr = TempHeaderPtr->Next) {\r
-\r
-    Status = AllocMemInMemoryBlock (\r
-               TempHeaderPtr,\r
-               (VOID **) Pool,\r
-               RealAllocSize / 32\r
-               );\r
-    if (!EFI_ERROR (Status)) {\r
-      ZeroMem (*Pool, AllocSize);\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-  \r
-  //\r
-  // There is no enough memory,\r
-  // Create a new Memory Block\r
-  //\r
-  \r
-  //\r
-  // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,\r
-  // just allocate a large enough memory block.\r
-  //\r
-  if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {\r
-    MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;\r
-  } else {\r
-    MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
-  }\r
-\r
-  Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  \r
-  //\r
-  // Link the new Memory Block to the Memory Header list\r
-  //\r
-  InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
-\r
-  Status = AllocMemInMemoryBlock (\r
-             NewMemoryHeader,\r
-             (VOID **) Pool,\r
-             RealAllocSize / 32\r
-             );\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    ZeroMem (*Pool, AllocSize);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-VOID\r
-UhciFreePool (\r
-  IN USB_HC_DEV     *HcDev,\r
-  IN UINT8          *Pool,\r
-  IN UINTN          AllocSize\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Uhci Free Pool\r
-\r
-Arguments:\r
-\r
-  HcDev     - USB_HC_DEV\r
-  Pool      - Pool to free\r
-  AllocSize - Pool size\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  MEMORY_MANAGE_HEADER  *MemoryHeader;\r
-  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
-  UINTN                 StartBytePos;\r
-  UINTN                 Index;\r
-  UINT8                 StartBitPos;\r
-  UINT8                 Index2;\r
-  UINTN                 Count;\r
-  UINTN                 RealAllocSize;\r
-\r
-  MemoryHeader = HcDev->MemoryHeader;\r
-\r
-  //\r
-  // allocate unit is 32 byte (align on 32 byte)\r
-  //\r
-  if (AllocSize & 0x1F) {\r
-    RealAllocSize = (AllocSize / 32 + 1) * 32;\r
-  } else {\r
-    RealAllocSize = AllocSize;\r
-  }\r
-  //\r
-  // scan the memory header linked list for\r
-  // the asigned memory to free.\r
-  //\r
-  for (TempHeaderPtr = MemoryHeader;TempHeaderPtr != NULL;\r
-       TempHeaderPtr = TempHeaderPtr->Next) {\r
-\r
-    if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&\r
-        ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))\r
-        ) {\r
-      //\r
-      // Pool is in the Memory Block area,\r
-      // find the start byte and bit in the bit array\r
-      //\r
-      StartBytePos  = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;\r
-      StartBitPos   = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);\r
-\r
-      //\r
-      // reset associated bits in bit arry\r
-      //\r
-      for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {\r
-\r
-        TempHeaderPtr->BitArrayPtr[Index] = (UINT8) (TempHeaderPtr->BitArrayPtr[Index] ^ bit (Index2));\r
-        Index2++;\r
-        if (Index2 == 8) {\r
-          Index += 1;\r
-          Index2 = 0;\r
-        }\r
-      }\r
-      //\r
-      // break the loop\r
-      //\r
-      break;\r
-    }\r
-  }\r
-  \r
-  //\r
-  // Release emptied memory blocks (only if the memory block is not\r
-  // the first one in the memory header list\r
-  //\r
-  for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
-    //\r
-    // Debug\r
-    //\r
-    ASSERT (MemoryHeader->Next != NULL);\r
-\r
-    if (IsMemoryBlockEmptied (TempHeaderPtr)) {\r
-\r
-      DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);\r
-      //\r
-      // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
-      // the TempHeaderPtr is pointing to nonsense content.\r
-      //\r
-      FreeMemoryHeader (HcDev, TempHeaderPtr);\r
-      //\r
-      // reset the TempHeaderPtr, continue search for\r
-      // another empty memory block.\r
-      //\r
-      TempHeaderPtr = MemoryHeader->Next;\r
-      continue;\r
-    }\r
-\r
-    TempHeaderPtr = TempHeaderPtr->Next;\r
-  }\r
-}\r
-\r
-VOID\r
-InsertMemoryHeaderToList (\r
-  IN MEMORY_MANAGE_HEADER     *MemoryHeader,\r
-  IN MEMORY_MANAGE_HEADER     *NewMemoryHeader\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Insert Memory Header To List\r
-\r
-Arguments:\r
-\r
-  MemoryHeader    - MEMORY_MANAGE_HEADER\r
-  NewMemoryHeader - MEMORY_MANAGE_HEADER\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
-\r
-  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;\r
-       TempHeaderPtr = TempHeaderPtr->Next) {\r
-    if (TempHeaderPtr->Next == NULL) {\r
-      TempHeaderPtr->Next = NewMemoryHeader;\r
-      break;\r
-    }\r
-  }\r
-}\r
-\r
-EFI_STATUS\r
-AllocMemInMemoryBlock (\r
-  IN  MEMORY_MANAGE_HEADER     *MemoryHeader,\r
-  OUT VOID                     **Pool,\r
-  IN  UINTN                    NumberOfMemoryUnit\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Alloc Memory In MemoryBlock\r
-\r
-Arguments:\r
-\r
-  MemoryHeader        - MEMORY_MANAGE_HEADER\r
-  Pool                - Place to store pointer to memory\r
-  NumberOfMemoryUnit  - Number Of Memory Unit\r
-\r
-Returns:\r
-\r
-  EFI_NOT_FOUND  - Can't find the free memory \r
-  EFI_SUCCESS    - Success\r
-\r
---*/\r
-{\r
-  UINTN TempBytePos;\r
-  UINTN FoundBytePos;\r
-  UINT8 Index;\r
-  UINT8 FoundBitPos;\r
-  UINT8 ByteValue;\r
-  UINT8 BitValue;\r
-  UINTN NumberOfZeros;\r
-  UINTN Count;\r
-\r
-  FoundBytePos  = 0;\r
-  FoundBitPos   = 0;\r
-  ByteValue     = MemoryHeader->BitArrayPtr[0];\r
-  NumberOfZeros = 0;\r
-  Index         = 0;\r
-\r
-  for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {\r
-    \r
-    //\r
-    // Pop out BitValue from a byte in TempBytePos.\r
-    //\r
-    BitValue = (UINT8) (ByteValue & 0x1);\r
-    //\r
-    // right shift the byte\r
-    //\r
-    ByteValue /= 2;\r
-\r
-    if (BitValue == 0) {\r
-      //\r
-      // Found a free bit, the NumberOfZeros only record the number\r
-      // of those consecutive zeros\r
-      //\r
-      NumberOfZeros++;\r
-      //\r
-      // Found enough consecutive free space, break the loop\r
-      //\r
-      if (NumberOfZeros >= NumberOfMemoryUnit) {\r
-        break;\r
-      }\r
-    } else {\r
-      //\r
-      // Encountering a '1', meant the bit is ocupied.\r
-      //\r
-      if (NumberOfZeros >= NumberOfMemoryUnit) {\r
-        //\r
-        // Found enough consecutive free space,break the loop\r
-        //\r
-        break;\r
-      } else {\r
-        //\r
-        // the NumberOfZeros only record the number of those consecutive zeros,\r
-        // so reset the NumberOfZeros to 0 when encountering '1' before finding\r
-        // enough consecutive '0's\r
-        //\r
-        NumberOfZeros = 0;\r
-        //\r
-        // reset the (FoundBytePos,FoundBitPos) to the position of '1'\r
-        //\r
-        FoundBytePos  = TempBytePos;\r
-        FoundBitPos   = Index;\r
-      }\r
-    }\r
-    //\r
-    // step forward a bit\r
-    //\r
-    Index++;\r
-    if (Index == 8) {\r
-      //\r
-      // step forward a byte, getting the byte value,\r
-      // and reset the bit pos.\r
-      //\r
-      TempBytePos += 1;\r
-      ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];\r
-      Index     = 0;\r
-    }\r
-  }\r
-\r
-  if (NumberOfZeros < NumberOfMemoryUnit) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  \r
-  //\r
-  // Found enough free space.\r
-  //\r
-  \r
-  //\r
-  // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:\r
-  //  1)(FoundBytePos,FoundBitPos) record the position\r
-  //    of the last '1' before the consecutive '0's, it must\r
-  //    be adjusted to the start position of the consecutive '0's.\r
-  //  2)the start address of the consecutive '0's is just the start of\r
-  //    the bitarray. so no need to adjust the values of\r
-  //    (FoundBytePos,FoundBitPos).\r
-  //\r
-  if ((MemoryHeader->BitArrayPtr[0] & bit (0)) != 0) {\r
-    FoundBitPos += 1;\r
-  }\r
-  \r
-  //\r
-  // Have the (FoundBytePos,FoundBitPos) make sense.\r
-  //\r
-  if (FoundBitPos > 7) {\r
-    FoundBytePos += 1;\r
-    FoundBitPos -= 8;\r
-  }\r
-  \r
-  //\r
-  // Set the memory as allocated\r
-  //\r
-  for (TempBytePos = FoundBytePos, Index = FoundBitPos,Count = 0;\r
-       Count < NumberOfMemoryUnit; Count ++) {\r
-\r
-    MemoryHeader->BitArrayPtr[TempBytePos] = (UINT8) (MemoryHeader->BitArrayPtr[TempBytePos] | bit (Index));\r
-    Index++;\r
-    if (Index == 8) {\r
-      TempBytePos += 1;\r
-      Index = 0;\r
-    }\r
-  }\r
-\r
-  *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-IsMemoryBlockEmptied (\r
-  IN MEMORY_MANAGE_HEADER     *MemoryHeaderPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Is Memory Block Emptied\r
-\r
-Arguments:\r
-\r
-  MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
-\r
-Returns:\r
-\r
-  TRUE  - Empty\r
-  FALSE - Not Empty \r
-\r
---*/\r
-{\r
-  UINTN Index;\r
-\r
-  for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {\r
-    if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-VOID\r
-DelinkMemoryBlock (\r
-  IN MEMORY_MANAGE_HEADER     *FirstMemoryHeader,\r
-  IN MEMORY_MANAGE_HEADER     *NeedFreeMemoryHeader\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Delink Memory Block\r
-\r
-Arguments:\r
-\r
-  FirstMemoryHeader     - MEMORY_MANAGE_HEADER\r
-  NeedFreeMemoryHeader  - MEMORY_MANAGE_HEADER\r
-\r
-Returns:\r
-\r
-  VOID\r
-\r
---*/\r
-{\r
-  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
-\r
-  if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {\r
-    return ;\r
-  }\r
-  for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL;\r
-       TempHeaderPtr = TempHeaderPtr->Next) {\r
-\r
-    if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {\r
-      //\r
-      // Link the before and after\r
-      //\r
-      TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;\r
-      break;\r
-    }\r
-  }\r
-}\r
-\r
-EFI_STATUS\r
-DelMemoryManagement (\r
-  IN USB_HC_DEV     *HcDev\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Delete Memory Management\r
-\r
-Arguments:\r
-\r
-  HcDev - USB_HC_DEV\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - Success\r
-\r
---*/\r
-{\r
-  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
-\r
-  for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
-\r
-    DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);\r
-    //\r
-    // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
-    // the TempHeaderPtr is pointing to nonsense content.\r
-    //\r
-    FreeMemoryHeader (HcDev, TempHeaderPtr);\r
-    //\r
-    // reset the TempHeaderPtr,continue free another memory block.\r
-    //\r
-    TempHeaderPtr = HcDev->MemoryHeader->Next;\r
-  }\r
-\r
-  FreeMemoryHeader (HcDev, HcDev->MemoryHeader);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-CleanUsbTransactions (\r
-  IN USB_HC_DEV     *HcDev\r
-  )\r
-{\r
-  //\r
-  // only asynchronous interrupt transfers are always alive on the bus\r
-  //\r
-  ReleaseInterruptList (HcDev, &(HcDev->InterruptListHead));\r
-}\r
-\r
-VOID\r
-TurnOffUSBEmulation (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo\r
-  )\r
-/*++\r
-  \r
-  Routine Description:\r
-    Disable USB Emulation\r
-  Arguments:\r
-    PciIo  -  EFI_PCI_IO_PROTOCOL\r
-  Returns:\r
-    VOID\r
---*/\r
-{\r
-  UINT16  Command;\r
-\r
-  //\r
-  // Disable USB Emulation\r
-  //\r
-  Command = 0;\r
-  PciIo->Pci.Write (\r
-               PciIo,\r
-               EfiPciIoWidthUint16,\r
-               USB_EMULATION,\r
-               1,\r
-               &Command\r
-               );\r
-\r
-  return ;\r
-}\r