]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c
1. Add NULL QH to set as QH header;
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / Ehci / Dxe / EhciSched.c
index 48432c0b98c63cad6a880ce583f7960cd1c3e9cb..34e31a896fed5fc57f92c52fee20d20a21374201 100644 (file)
 /*++\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
+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
     EhciSched.c\r
-    \r
-Abstract: \r
-    \r
+\r
+Abstract:\r
+\r
 \r
 Revision History\r
 --*/\r
 \r
 #include "Ehci.h"\r
 \r
+\r
+EFI_STATUS\r
+SetAndWaitDoorBell (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  IN  UINTN           Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set DoorBell and wait it to complete\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      Data;\r
+  UINTN       Delay;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             USBCMD,\r
+             &Data\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Data |= USBCMD_IAAD;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             USBCMD,\r
+             Data\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+    Status = ReadEhcOperationalReg (\r
+               HcDev,\r
+               USBSTS,\r
+               &Data\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    if ((Data & USBSTS_IAA) == USBSTS_IAA) {\r
+      break;\r
+    }\r
+\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Data = Data & 0xFFFFFFC0;\r
+  Data |= USBSTS_IAA;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             USBSTS,\r
+             Data\r
+             );\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+CreateNULLQH (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create the NULL QH to make it as the Async QH header\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EHCI_QH_ENTITY        *NULLQhPtr;\r
+  //\r
+  // Allocate  memory for Qh structure\r
+  //\r
+  Status = EhciAllocatePool (\r
+             HcDev,\r
+             (UINT8 **) &NULLQhPtr,\r
+             sizeof (EHCI_QH_ENTITY)\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+     return Status;\r
+  }\r
+\r
+  NULLQhPtr->Qh.Status = QTD_STATUS_HALTED;\r
+  NULLQhPtr->Qh.HeadReclamationFlag = 1;\r
+  NULLQhPtr->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(NULLQhPtr->Qh) >> 5));\r
+  NULLQhPtr->Qh.SelectType = QH_SELECT_TYPE;\r
+  NULLQhPtr->Qh.NextQtdTerminate = 1;\r
+\r
+  NULLQhPtr->Next = NULLQhPtr;\r
+  NULLQhPtr->Prev = NULLQhPtr;\r
+\r
+  HcDev->NULLQH = NULLQhPtr;\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+VOID\r
+DestroyNULLQH (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+{\r
+\r
+  if (HcDev->NULLQH != NULL) {\r
+    EhciFreePool (HcDev, (UINT8 *)HcDev->NULLQH, sizeof (EHCI_QH_ENTITY));\r
+    HcDev->NULLQH = NULL;\r
+  }\r
+}\r
+\r
+\r
+\r
 EFI_STATUS\r
 InitialPeriodicFrameList (\r
   IN  USB2_HC_DEV     *HcDev,\r
@@ -36,7 +185,7 @@ Arguments:
 \r
   HcDev   - USB2_HC_DEV\r
   Length  - Frame List Length\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
@@ -52,7 +201,7 @@ Returns:
   UINTN                 BufferSizeInBytes;\r
   UINTN                 FrameIndex;\r
   FRAME_LIST_ENTRY      *FrameEntryPtr;\r
-  \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
@@ -99,7 +248,7 @@ Returns:
   }\r
 \r
   //\r
-  // Put high 32bit into CtrlDataStructSeg reg \r
+  // Put high 32bit into CtrlDataStructSeg reg\r
   // when 64bit addressing range capability\r
   //\r
   if (HcDev->Is64BitCapable != 0) {\r
@@ -112,7 +261,7 @@ Returns:
       goto unmap_buffer;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Tell the Host Controller where the Frame List lies,\r
   // by set the Frame List Base Address Register.\r
@@ -166,7 +315,7 @@ Arguments:
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->PeriodicFrameListMap);\r
@@ -189,12 +338,12 @@ Arguments:
 \r
   HcDev          - USB2_HC_DEV\r
   NotifyFunction - Timer Notify Function\r
-  \r
+\r
 Returns:\r
-  \r
+\r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-  \r
+\r
 --*/\r
 {\r
   return gBS->CreateEvent (\r
@@ -219,12 +368,12 @@ Routine Description:
 Arguments:\r
 \r
   HcDev - USB2_HC_DEV\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-  \r
+\r
 --*/\r
 {\r
   return gBS->CloseEvent (HcDev->AsyncRequestEvent);\r
@@ -243,12 +392,12 @@ Routine Description:
 Arguments:\r
 \r
   HcDev - USB2_HC_DEV\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-  \r
+\r
 --*/\r
 {\r
   return gBS->SetTimer (\r
@@ -271,12 +420,12 @@ Routine Description:
 Arguments:\r
 \r
   HcDev - USB2_HC_DEV\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-  \r
+\r
 --*/\r
 {\r
   return gBS->SetTimer (\r
@@ -303,18 +452,18 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  HcDev        - USB2_HC_DEV \r
+  HcDev        - USB2_HC_DEV\r
   DeviceAddr   - Address of Device\r
   Endpoint     - Endpoint Number\r
   DeviceSpeed  - Device Speed\r
   MaxPacketLen - Max Length of one Packet\r
   QhPtrPtr     - A pointer of pointer to Qh for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -337,10 +486,6 @@ Returns:
     Status = EFI_OUT_OF_RESOURCES;\r
     goto exit;\r
   }\r
-  //\r
-  // Init fields in Qh\r
-  //\r
-  ZeroMem (*QhPtrPtr, sizeof (EHCI_QH_ENTITY));\r
 \r
   //\r
   // Software field\r
@@ -359,8 +504,8 @@ Returns:
   QhHwPtr->SelectType           = 0;\r
   QhHwPtr->MaxPacketLen         = (UINT32) MaxPacketLen;\r
   QhHwPtr->EndpointSpeed        = (DeviceSpeed & 0x3);\r
-  QhHwPtr->EndpointNum          = (Endpoint & 0x0f);\r
-  QhHwPtr->DeviceAddr           = (DeviceAddr & 0x7f);\r
+  QhHwPtr->EndpointNum          = (Endpoint & 0x0F);\r
+  QhHwPtr->DeviceAddr           = (DeviceAddr & 0x7F);\r
   QhHwPtr->Multiplier           = HIGH_BANDWIDTH_PIPE_MULTIPLIER;\r
   QhHwPtr->Rsvd1                = 0;\r
   QhHwPtr->Rsvd2                = 0;\r
@@ -382,18 +527,18 @@ DestoryQh (
 \r
 Routine Description:\r
 \r
-  Destory Qh Structure \r
-  \r
+  Destory Qh Structure\r
+\r
 Arguments:\r
 \r
-  HcDev - USB2_HC_DEV \r
+  HcDev - USB2_HC_DEV\r
   QhPtr - A pointer to Qh\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-  \r
+\r
 --*/\r
 {\r
   ASSERT (HcDev);\r
@@ -420,18 +565,18 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  HcDev        - USB2_HC_DEV \r
+  HcDev        - USB2_HC_DEV\r
   DeviceAddr   - Address of Device\r
   DeviceSpeed  - Device Speed\r
   MaxPacketLen - Max Length of one Packet\r
   Translator   - Translator Transaction for SplitX\r
   QhPtrPtr     - A pointer of pointer to Qh for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -467,7 +612,9 @@ Returns:
   (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);\r
   (*QhPtrPtr)->Qh.SelectType          = QH_SELECT_TYPE;\r
   (*QhPtrPtr)->Qh.QhTerminate         = FALSE;\r
-  (*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;\r
+  if (EFI_USB_SPEED_HIGH != DeviceSpeed)  {\r
+    (*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;\r
+  }\r
   (*QhPtrPtr)->Qh.NakCountReload      = NAK_COUNT_RELOAD;\r
   if (NULL != Translator) {\r
     (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
@@ -498,19 +645,19 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  HcDev        - USB2_HC_DEV \r
+  HcDev        - USB2_HC_DEV\r
   DeviceAddr   - Address of Device\r
   EndPointAddr - Address of Endpoint\r
   DeviceSpeed  - Device Speed\r
   MaxPacketLen - Max Length of one Packet\r
   Translator   - Translator Transaction for SplitX\r
   QhPtrPtr     - A pointer of pointer to Qh for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -530,7 +677,7 @@ Returns:
     Status = EFI_OUT_OF_RESOURCES;\r
     goto exit;\r
   }\r
-  \r
+\r
   //\r
   // Software fields\r
   //\r
@@ -543,7 +690,7 @@ Returns:
   //\r
   // BulkTransfer don't use DataToggleControl\r
   //\r
-  (*QhPtrPtr)->Qh.DataToggleControl   = FALSE;  \r
+  (*QhPtrPtr)->Qh.DataToggleControl   = FALSE;\r
   (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);\r
   (*QhPtrPtr)->Qh.SelectType          = QH_SELECT_TYPE;\r
   (*QhPtrPtr)->Qh.QhTerminate         = FALSE;\r
@@ -579,7 +726,7 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  HcDev        - USB2_HC_DEV \r
+  HcDev        - USB2_HC_DEV\r
   DeviceAddr   - Address of Device\r
   EndPointAddr - Address of Endpoint\r
   DeviceSpeed  - Device Speed\r
@@ -587,12 +734,12 @@ Arguments:
   Interval     - value of interval\r
   Translator   - Translator Transaction for SplitX\r
   QhPtrPtr     - A pointer of pointer to Qh for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -612,7 +759,7 @@ Returns:
     Status = EFI_OUT_OF_RESOURCES;\r
     goto exit;\r
   }\r
-  \r
+\r
   //\r
   // Software fields\r
   //\r
@@ -663,19 +810,19 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  HcDev       - USB2_HC_DEV \r
+  HcDev       - USB2_HC_DEV\r
   DataPtr     - A pointer to user data buffer to transfer\r
   DataLen     - Length of user data to transfer\r
   PktId       - Packet Identification of this Qtd\r
   Toggle      - Data Toggle of this Qtd\r
   QtdStatus   - Default value of status of this Qtd\r
   QtdPtrPtr   - A pointer of pointer to Qtd for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -696,11 +843,6 @@ Returns:
     Status = EFI_OUT_OF_RESOURCES;\r
     goto exit;\r
   }\r
-  //\r
-  // Init fields in Qtd\r
-  //\r
-\r
-  ZeroMem (*QtdPtrPtr, sizeof (EHCI_QTD_ENTITY));\r
 \r
   //\r
   // Software field\r
@@ -750,7 +892,7 @@ Returns:
     Status = EFI_INVALID_PARAMETER;\r
     goto exit;\r
   }\r
-  \r
+\r
   //\r
   // Set Data Buffer Pointers\r
   //\r
@@ -777,19 +919,19 @@ CreateSetupQtd (
 \r
 Routine Description:\r
 \r
-  Create Qtd Structure for Setup \r
+  Create Qtd Structure for Setup\r
 \r
 Arguments:\r
 \r
-  HcDev      - USB2_HC_DEV \r
+  HcDev      - USB2_HC_DEV\r
   DevReqPtr  - A pointer to Device Request Data\r
   QtdPtrPtr  - A pointer of pointer to Qtd for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   return CreateQtd (\r
@@ -816,22 +958,22 @@ CreateDataQtd (
 \r
 Routine Description:\r
 \r
-  Create Qtd Structure for data \r
+  Create Qtd Structure for data\r
 \r
 Arguments:\r
 \r
-  HcDev       - USB2_HC_DEV \r
+  HcDev       - USB2_HC_DEV\r
   DataPtr     - A pointer to user data buffer to transfer\r
   DataLen     - Length of user data to transfer\r
   PktId       - Packet Identification of this Qtd\r
   Toggle      - Data Toggle of this Qtd\r
   QtdPtrPtr   - A pointer of pointer to Qtd for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   return CreateQtd (\r
@@ -855,19 +997,19 @@ CreateAltQtd (
 \r
 Routine Description:\r
 \r
-  Create Qtd Structure for Alternative \r
+  Create Qtd Structure for Alternative\r
 \r
 Arguments:\r
 \r
-  HcDev      - USB2_HC_DEV \r
+  HcDev      - USB2_HC_DEV\r
   PktId      - Packet Identification of this Qtd\r
   QtdPtrPtr  - A pointer of pointer to Qtd for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   return CreateQtd (\r
@@ -891,19 +1033,19 @@ CreateStatusQtd (
 \r
 Routine Description:\r
 \r
-  Create Qtd Structure for status \r
+  Create Qtd Structure for status\r
 \r
 Arguments:\r
 \r
-  HcDev       - USB2_HC_DEV \r
+  HcDev       - USB2_HC_DEV\r
   PktId       - Packet Identification of this Qtd\r
   QtdPtrPtr   - A pointer of pointer to Qtd for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   return CreateQtd (\r
@@ -931,22 +1073,22 @@ CreateControlQtds (
 \r
 Routine Description:\r
 \r
-  Create Qtds list for Control Transfer \r
+  Create Qtds list for Control Transfer\r
 \r
 Arguments:\r
 \r
-  HcDev           - USB2_HC_DEV \r
+  HcDev           - USB2_HC_DEV\r
   DataPktId       - Packet Identification of Data Qtds\r
   RequestCursor   - A pointer to request structure buffer to transfer\r
   DataCursor      - A pointer to user data buffer to transfer\r
   DataLen         - Length of user data to transfer\r
   ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS      Status;\r
@@ -961,8 +1103,7 @@ Returns:
   UINTN           CapacityOfQtd;\r
   UINTN           SizePerQtd;\r
   UINTN           DataCount;\r
-  UINTN           Xnum;\r
-  \r
+\r
   QtdPtr          = NULL;\r
   PreQtdPtr       = NULL;\r
   SetupQtdPtr     = NULL;\r
@@ -983,7 +1124,7 @@ Returns:
     Status = EFI_OUT_OF_RESOURCES;\r
     goto exit;\r
   }\r
-  \r
+\r
   //\r
   //  Data Stage of Control Transfer\r
   //\r
@@ -1026,14 +1167,8 @@ Returns:
       LinkQtdToQtd (PreQtdPtr, QtdPtr);\r
     }\r
 \r
-    //\r
-    // Reverse Data Toggle or not determined by parity of transactions of one qtd\r
-    //\r
-    Xnum = Translator ? GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE_WITH_TT) : GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE);\r
-    if (Xnum % 2 != 0) {\r
-      DataToggle ^= 1;\r
-    }\r
-    \r
+    DataToggle ^= 1;\r
+\r
     PreQtdPtr = QtdPtr;\r
     DataCursor += SizePerQtd;\r
     DataCount -= SizePerQtd;\r
@@ -1059,7 +1194,7 @@ Returns:
     Status = EFI_OUT_OF_RESOURCES;\r
     goto destory_qtds;\r
   }\r
-  \r
+\r
   //\r
   // Link setup Qtd -> data Qtds -> status Qtd\r
   //\r
@@ -1095,23 +1230,23 @@ CreateBulkOrInterruptQtds (
 \r
 Routine Description:\r
 \r
-  Create Qtds list for Bulk or Interrupt Transfer \r
+  Create Qtds list for Bulk or Interrupt Transfer\r
 \r
 Arguments:\r
 \r
-  HcDev        - USB2_HC_DEV \r
+  HcDev        - USB2_HC_DEV\r
   PktId        - Packet Identification of Qtds\r
   DataCursor   - A pointer to user data buffer to transfer\r
   DataLen      - Length of user data to transfer\r
   DataToggle   - Data Toggle to start\r
   Translator   - Translator Transaction for SplitX\r
   QtdsHead     - A pointer of pointer to first Qtd for control tranfer for return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS            Success\r
   EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS      Status;\r
@@ -1166,11 +1301,11 @@ Returns:
     DataCursor += SizePerQtd;\r
     DataCount -= SizePerQtd;\r
   }\r
-  \r
+\r
   //\r
   // Set Alternate Qtd\r
   //\r
-  if (INPUT_PACKET_ID == PktId && 1 < GetNumberOfQtd (FirstQtdPtr)) {\r
+  if (INPUT_PACKET_ID == PktId && 0 < GetNumberOfQtd (FirstQtdPtr)) {\r
     Status = CreateAltQtd (\r
               HcDev,\r
               PktId,\r
@@ -1206,9 +1341,9 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  HcDev         - USB2_HC_DEV \r
-  FirstQtdPtr   - A pointer to first Qtd in the list \r
-    \r
+  HcDev         - USB2_HC_DEV\r
+  FirstQtdPtr   - A pointer to first Qtd in the list\r
+\r
 Returns:\r
 \r
   VOID\r
@@ -1246,11 +1381,11 @@ GetNumberOfQtd (
 Routine Description:\r
 \r
   Number of Qtds in the list\r
-  \r
+\r
 Arguments:\r
 \r
   FirstQtdPtr - A pointer to first Qtd in the list\r
-    \r
+\r
 Returns:\r
 \r
   Number of Qtds in the list\r
@@ -1262,8 +1397,6 @@ Returns:
   Count   = 0;\r
   QtdPtr  = FirstQtdPtr;\r
 \r
-  ;\r
-\r
   while (NULL != QtdPtr) {\r
     Count++;\r
     QtdPtr = QtdPtr->Next;\r
@@ -1272,33 +1405,6 @@ Returns:
   return Count;\r
 }\r
 \r
-UINTN\r
-GetNumberOfTransaction (\r
-  IN UINTN    SizeOfData,\r
-  IN UINTN    SizeOfTransaction\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Number of Transactions in one Qtd\r
-  \r
-Arguments:\r
-\r
-  SizeOfData           - Size of one Qtd\r
-  SizeOfTransaction    - Size of one Transaction\r
-   \r
-Returns:\r
-\r
-  Number of Transactions in this Qtd\r
-\r
---*/\r
-{\r
-\r
-  return ((SizeOfData & (SizeOfTransaction - 1)) ? SizeOfData / SizeOfTransaction + 1 : SizeOfData / SizeOfTransaction);\r
-\r
-}\r
-\r
 UINTN\r
 GetCapacityOfQtd (\r
   IN UINT8    *BufferCursor\r
@@ -1308,11 +1414,11 @@ GetCapacityOfQtd (
 Routine Description:\r
 \r
   Get Size of First Qtd\r
-  \r
+\r
 Arguments:\r
 \r
   BufferCursor       - BufferCursor of the Qtd\r
-   \r
+\r
 Returns:\r
 \r
   Size of First Qtd\r
@@ -1320,7 +1426,11 @@ Returns:
 --*/\r
 {\r
 \r
-  return (EHCI_MAX_QTD_CAPACITY - (EHCI_BLOCK_SIZE * GetNumberOfTransaction (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor), EHCI_BLOCK_SIZE)));\r
+ if (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor)) {\r
+   return EFI_PAGE_SIZE * 4;\r
+ } else {\r
+   return EFI_PAGE_SIZE * 5;\r
+ }\r
 \r
 }\r
 \r
@@ -1333,15 +1443,15 @@ GetApproxiOfInterval (
 Routine Description:\r
 \r
   Get the approximate value in the 2 index sequence\r
-  \r
+\r
 Arguments:\r
 \r
   Interval  - the value of interval\r
-  \r
+\r
 Returns:\r
 \r
   approximate value of interval in the 2 index sequence\r
-  \r
+\r
 --*/\r
 {\r
   UINTN Orignate;\r
@@ -1371,15 +1481,15 @@ GetQtdAlternateNextPointer (
 Routine Description:\r
 \r
   Get Qtd alternate next pointer field\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   A pointer to hardware alternate Qtd\r
-  \r
+\r
 --*/\r
 {\r
   EHCI_QTD_HW *Value;\r
@@ -1402,15 +1512,15 @@ GetQtdNextPointer (
 Routine Description:\r
 \r
   Get Qtd next pointer field\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   A pointer to next hardware Qtd structure\r
-  \r
+\r
 --*/\r
 {\r
   EHCI_QTD_HW *Value;\r
@@ -1424,8 +1534,9 @@ Returns:
   return Value;\r
 }\r
 \r
-VOID LinkQtdToQtd (\r
-  IN EHCI_QTD_ENTITY * PreQtdPtr, \r
+VOID\r
+LinkQtdToQtd (\r
+  IN EHCI_QTD_ENTITY * PreQtdPtr,\r
   IN EHCI_QTD_ENTITY * QtdPtr\r
   )\r
 /*++\r
@@ -1433,12 +1544,12 @@ VOID LinkQtdToQtd (
 Routine Description:\r
 \r
   Link Qtds together\r
-  \r
+\r
 Arguments:\r
 \r
   PreQtdPtr   - A pointer to pre Qtd\r
   QtdPtr      - A pointer to next Qtd\r
-    \r
+\r
 Returns:\r
 \r
   VOID\r
@@ -1467,8 +1578,9 @@ Returns:
 }\r
 \r\r
 \r
-VOID LinkQtdsToAltQtd (\r
-  IN EHCI_QTD_ENTITY  * FirstQtdPtr, \r
+VOID\r
+LinkQtdsToAltQtd (\r
+  IN EHCI_QTD_ENTITY  * FirstQtdPtr,\r
   IN EHCI_QTD_ENTITY  * AltQtdPtr\r
   )\r
 /*++\r
@@ -1476,12 +1588,12 @@ VOID LinkQtdsToAltQtd (
 Routine Description:\r
 \r
   Link AlterQtds together\r
-  \r
+\r
 Arguments:\r
 \r
   FirstQtdPtr  - A pointer to first Qtd in the list\r
   AltQtdPtr    - A pointer to alternative Qtd\r
-    \r
+\r
 Returns:\r
 \r
   VOID\r
@@ -1496,7 +1608,7 @@ Returns:
 \r
   AltQtdHwPtr = &(AltQtdPtr->Qtd);\r
   QtdPtr      = FirstQtdPtr;\r
-  \r
+\r
   while (NULL != QtdPtr) {\r
     //\r
     // Software link\r
@@ -1523,12 +1635,12 @@ LinkQtdToQh (
 Routine Description:\r
 \r
   Link Qtds list to Qh\r
-  \r
+\r
 Arguments:\r
 \r
   QhPtr    - A pointer to Qh\r
   QtdPtr   - A pointer to first Qtd in the list\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
@@ -1560,6 +1672,18 @@ Returns:
   QhPtr->Qh.NextQtdPointer    = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);\r
   QhPtr->Qh.NextQtdTerminate  = FALSE;\r
 \r
+  QhPtr->Qh.AltNextQtdPointer    = 0;\r
+  QhPtr->Qh.AltNextQtdTerminate  = TRUE;\r
+\r
+\r
+  if ((QtdPtr->Qtd.PidCode == OUTPUT_PACKET_PID_CODE) &&\r
+      (QhPtr->TransferType == BULK_TRANSFER)) {\r
+      //\r
+      //Start PING first\r
+      //\r
+      QhPtr->Qh.Status |= QTD_STATUS_DO_PING;\r
+    }\r
+\r
   return ;\r
 }\r
 \r
@@ -1573,17 +1697,17 @@ LinkQhToAsyncList (
 Routine Description:\r
 \r
   Link Qh to Async Schedule List\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev  - USB2_HC_DEV \r
+  HcDev  - USB2_HC_DEV\r
   QhPtr  - A pointer to Qh\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS       Success\r
   EFI_DEVICE_ERROR  Fail\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -1591,9 +1715,23 @@ Returns:
   ASSERT (HcDev);\r
   ASSERT (QhPtr);\r
 \r
-  QhPtr->Qh.HeadReclamationFlag = TRUE;\r
 \r
-  Status                        = SetAsyncListAddr (HcDev, QhPtr);\r
+  //\r
+  // NULL QH created before\r
+  //\r
+\r
+  HcDev->NULLQH->Next = QhPtr;\r
+  HcDev->NULLQH->Prev = QhPtr;\r
+\r
+  QhPtr->Next = HcDev->NULLQH;\r
+  QhPtr->Prev = HcDev->NULLQH;\r
+\r
+\r
+  HcDev->NULLQH->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(QhPtr->Qh) >> 5));\r
+  QhPtr->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(HcDev->NULLQH->Qh) >> 5));\r
+\r
+\r
+  Status = SetAsyncListAddr (HcDev, HcDev->NULLQH);\r
   if (EFI_ERROR (Status)) {\r
     Status = EFI_DEVICE_ERROR;\r
     goto exit;\r
@@ -1609,7 +1747,7 @@ Returns:
 \r
     Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((gEHCDebugLevel, "WaitForAsyncScheduleEnable TimeOut"));\r
+      DEBUG ((gEHCDebugLevel, "EHCI: WaitForAsyncScheduleEnable TimeOut"));\r
       Status = EFI_TIMEOUT;\r
       goto exit;\r
     }\r
@@ -1637,17 +1775,17 @@ UnlinkQhFromAsyncList (
 Routine Description:\r
 \r
   Unlink Qh from Async Schedule List\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev  - USB2_HC_DEV \r
+  HcDev  - USB2_HC_DEV\r
   QhPtr  - A pointer to Qh\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS       Success\r
   EFI_DEVICE_ERROR  Fail\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -1657,23 +1795,37 @@ Returns:
   ASSERT (HcDev);\r
   ASSERT (QhPtr);\r
 \r
-  if (QhPtr == QhPtr->Next) {\r
 \r
-    Status = DisableAsynchronousSchedule (HcDev);\r
-    if (EFI_ERROR (Status)) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto exit;\r
-    }\r
+  HcDev->NULLQH->Next = HcDev->NULLQH;\r
+  HcDev->NULLQH->Prev = HcDev->NULLQH;\r
 \r
-    Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((gEHCErrorLevel, "WaitForAsyncScheduleDisable TimeOut\n"));\r
-      Status = EFI_TIMEOUT;\r
-      goto exit;\r
-    }\r
 \r
+  QhPtr->Next = QhPtr;\r
+  QhPtr->Prev = QhPtr;\r
+\r
+  HcDev->NULLQH->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(HcDev->NULLQH->Qh) >> 5));\r
+\r
+\r
+  SetAndWaitDoorBell (HcDev, 2 * EHCI_GENERIC_TIMEOUT);\r
+\r
+  QhPtr->Qh.QhTerminate         = 1;\r
+  QhPtr->Qh.QhHorizontalPointer = 0;\r
+\r
+\r
+  Status = DisableAsynchronousSchedule (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
   }\r
 \r
+  Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((gEHCErrorLevel, "EHCI: WaitForAsyncScheduleDisable TimeOut\n"));\r
+    Status = EFI_TIMEOUT;\r
+    goto exit;\r
+  }\r
+\r
+\r
 exit:\r
   return Status;\r
 }\r
@@ -1688,16 +1840,16 @@ LinkQhToPeriodicList (
 Routine Description:\r
 \r
   Link Qh to Periodic Schedule List\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev  - USB2_HC_DEV \r
+  HcDev  - USB2_HC_DEV\r
   QhPtr  - A pointer to Qh\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   FRAME_LIST_ENTRY  *FrameEntryPtr;\r
@@ -1720,7 +1872,7 @@ Returns:
     //\r
     // AsyncInterruptTransfer Qh\r
     //\r
-    \r
+\r
     //\r
     // Link to Frame[0] List\r
     //\r
@@ -1835,11 +1987,11 @@ Returns:
       }\r
     }\r
   } else {\r
-  \r
+\r
     //\r
     // SyncInterruptTransfer Qh\r
     //\r
-    \r
+\r
     if (!FrameEntryPtr->LinkTerminate) {\r
       //\r
       // Not Null FrameList\r
@@ -1883,17 +2035,17 @@ UnlinkQhFromPeriodicList (
 Routine Description:\r
 \r
   Unlink Qh from Periodic Schedule List\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev     - USB2_HC_DEV \r
+  HcDev     - USB2_HC_DEV\r
   QhPtr     - A pointer to Qh\r
   Interval  - Interval of this periodic transfer\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   FRAME_LIST_ENTRY  *FrameEntryPtr;\r
@@ -1908,11 +2060,11 @@ Returns:
   FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
 \r
   if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {\r
-  \r
+\r
     //\r
     // AsyncInterruptTransfer Qh\r
     //\r
-    \r
+\r
     if (NULL == QhPtr->Prev) {\r
       //\r
       // Qh is the First one on  Frame[0] List\r
@@ -1938,7 +2090,7 @@ Returns:
         }\r
       }\r
     } else {\r
-    \r
+\r
       //\r
       // Not First one on  Frame[0] List\r
       //\r
@@ -2018,16 +2170,16 @@ LinkToAsyncReqeust (
 Routine Description:\r
 \r
   Llink AsyncRequest Entry to Async Request List\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev             - USB2_HC_DEV \r
+  HcDev             - USB2_HC_DEV\r
   AsyncRequestPtr   - A pointer to Async Request Entry\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   EHCI_ASYNC_REQUEST  *CurrentPtr;\r
@@ -2054,16 +2206,16 @@ UnlinkFromAsyncReqeust (
 Routine Description:\r
 \r
   Unlink AsyncRequest Entry from Async Request List\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev            - USB2_HC_DEV \r
+  HcDev            - USB2_HC_DEV\r
   AsyncRequestPtr  - A pointer to Async Request Entry\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   if (NULL == AsyncRequestPtr->Prev) {\r
@@ -2095,10 +2247,10 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  QtdHwPtr  - A pointer to Qtd hardware structure \r
+  QtdHwPtr  - A pointer to Qtd hardware structure\r
   DataPtr   - A pointer to user data buffer\r
   DataLen   - Length of the user data buffer\r
-    \r
+\r
 Returns:\r
 \r
   VOID\r
@@ -2107,21 +2259,20 @@ Returns:
 {\r
   UINTN RemainLen;\r
 \r
-  RemainLen = DataLen;\r
   ASSERT (QtdHwPtr);\r
+  ASSERT (DataLen <= 5 * EFI_PAGE_SIZE);\r
 \r
+  RemainLen = DataLen;\r
   //\r
   // Allow buffer address range across 4G.\r
   // But EFI_USB_MAX_BULK_BUFFER_NUM = 1, so don't allow\r
   // seperate buffer array.\r
   //\r
-\r
   //\r
   // Set BufferPointer0, ExtBufferPointer0 and Offset\r
   //\r
-  QtdHwPtr->BufferPointer0    = (UINT32) (GET_0B_TO_31B (DataPtr) >> 12);\r
+  QtdHwPtr->BufferPointer0    = (UINT32) (GET_0B_TO_31B (DataPtr) >> EFI_PAGE_SHIFT);\r
   QtdHwPtr->CurrentOffset     = (UINT32) (GET_0B_TO_31B (DataPtr) & EFI_PAGE_MASK);\r
-  QtdHwPtr->ExtBufferPointer0 = (UINT32) GET_32B_TO_63B (DataPtr);\r
 \r
   //\r
   // Set BufferPointer1 and ExtBufferPointer1\r
@@ -2132,7 +2283,6 @@ Returns:
   }\r
 \r
   QtdHwPtr->BufferPointer1    = QtdHwPtr->BufferPointer0 + 1;\r
-  QtdHwPtr->ExtBufferPointer1 = (QtdHwPtr->BufferPointer1 == 0) ? (QtdHwPtr->ExtBufferPointer0 + 1) : QtdHwPtr->ExtBufferPointer0;\r
 \r
   //\r
   // Set BufferPointer2 and ExtBufferPointer2\r
@@ -2143,7 +2293,6 @@ Returns:
   }\r
 \r
   QtdHwPtr->BufferPointer2    = QtdHwPtr->BufferPointer1 + 1;\r
-  QtdHwPtr->ExtBufferPointer2 = (QtdHwPtr->BufferPointer2 == 0) ? (QtdHwPtr->ExtBufferPointer1 + 1) : QtdHwPtr->ExtBufferPointer1;\r
 \r
   //\r
   // Set BufferPointer3 and ExtBufferPointer3\r
@@ -2154,7 +2303,6 @@ Returns:
   }\r
 \r
   QtdHwPtr->BufferPointer3    = QtdHwPtr->BufferPointer2 + 1;\r
-  QtdHwPtr->ExtBufferPointer3 = (QtdHwPtr->BufferPointer2 == 0) ? (QtdHwPtr->ExtBufferPointer2 + 1) : QtdHwPtr->ExtBufferPointer2;\r
 \r
   //\r
   // Set BufferPointer4 and ExtBufferPointer4\r
@@ -2165,7 +2313,6 @@ Returns:
   }\r
 \r
   QtdHwPtr->BufferPointer4    = QtdHwPtr->BufferPointer3 + 1;\r
-  QtdHwPtr->ExtBufferPointer4 = (QtdHwPtr->BufferPointer3 == 0) ? (QtdHwPtr->ExtBufferPointer3 + 1) : QtdHwPtr->ExtBufferPointer3;\r
 \r
 exit:\r
   return ;\r
@@ -2180,16 +2327,16 @@ IsQtdStatusActive (
 Routine Description:\r
 \r
   Whether Qtd status is active or not\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   TRUE    Active\r
   FALSE   Inactive\r
-  \r
+\r
 --*/\r
 {\r
   UINT8   QtdStatus;\r
@@ -2197,6 +2344,7 @@ Returns:
 \r
   QtdStatus = (UINT8) (HwQtdPtr->Status);\r
   Value     = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);\r
+  //DEBUG ((gEHCErrorLevel, "EHCI: IsQtdStatusActive 0x%X, Address = %x\r\n",HwQtdPtr->Status, HwQtdPtr));\r
 \r
   return Value;\r
 }\r
@@ -2210,16 +2358,16 @@ IsQtdStatusHalted (
 Routine Description:\r
 \r
   Whether Qtd status is halted or not\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   TRUE    Halted\r
   FALSE   Not halted\r
-  \r
+\r
 --*/\r
 {\r
   UINT8   QtdStatus;\r
@@ -2240,16 +2388,16 @@ IsQtdStatusBufferError (
 Routine Description:\r
 \r
   Whether Qtd status is buffer error or not\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   TRUE    Buffer error\r
   FALSE   No buffer error\r
-  \r
+\r
 --*/\r
 {\r
   UINT8   QtdStatus;\r
@@ -2270,16 +2418,16 @@ IsQtdStatusBabbleError (
 Routine Description:\r
 \r
   Whether Qtd status is babble error or not\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   TRUE    Babble error\r
   FALSE   No babble error\r
-  \r
+\r
 --*/\r
 {\r
   UINT8   QtdStatus;\r
@@ -2300,16 +2448,16 @@ IsQtdStatusTransactionError (
 Routine Description:\r
 \r
   Whether Qtd status is transaction error or not\r
-  \r
+\r
 Arguments:\r
 \r
   HwQtdPtr - A pointer to hardware Qtd structure\r
-  \r
+\r
 Returns:\r
 \r
   TRUE    Transaction error\r
   FALSE   No transaction error\r
-  \r
+\r
 --*/\r
 {\r
   UINT8   QtdStatus;\r
@@ -2330,16 +2478,16 @@ IsDataInTransfer (
 Routine Description:\r
 \r
   Whether is a DataIn direction transfer\r
-  \r
+\r
 Arguments:\r
 \r
-  EndPointAddress - address of the endpoint \r
-  \r
+  EndPointAddress - address of the endpoint\r
+\r
 Returns:\r
 \r
   TRUE    DataIn\r
   FALSE   DataOut\r
-  \r
+\r
 --*/\r
 {\r
   BOOLEAN Value;\r
@@ -2368,22 +2516,22 @@ MapDataBuffer (
 Routine Description:\r
 \r
   Map address of user data buffer\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev              - USB2_HC_DEV \r
+  HcDev              - USB2_HC_DEV\r
   TransferDirection  - direction of transfer\r
-  Data               - A pointer to user data buffer \r
+  Data               - A pointer to user data buffer\r
   DataLength         - length of user data\r
   PktId              - Packte Identificaion\r
   DataCursor         - mapped address to return\r
   DataMap            - identificaion of this mapping to return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-    \r
+\r
 --*/\r
 {\r
   EFI_STATUS            Status;\r
@@ -2408,7 +2556,7 @@ Returns:
                             DataMap\r
                             );\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((gEHCDebugLevel, "MapDataBuffer Failed\n"));\r
+      DEBUG ((gEHCDebugLevel, "EHCI: MapDataBuffer Failed\n"));\r
       Status = EFI_DEVICE_ERROR;\r
       goto exit;\r
     }\r
@@ -2468,19 +2616,19 @@ MapRequestBuffer (
 Routine Description:\r
 \r
   Map address of request structure buffer\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev           - USB2_HC_DEV \r
+  HcDev           - USB2_HC_DEV\r
   Request         - A pointer to request structure\r
   RequestCursor   - Mapped address of request structure to return\r
   RequestMap      - Identificaion of this mapping to return\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-    \r
+\r
 --*/\r
 {\r
   EFI_STATUS            Status;\r
@@ -2519,19 +2667,19 @@ DeleteAsyncRequestTransfer (
 Routine Description:\r
 \r
   Delete all asynchronous request transfer\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev           - USB2_HC_DEV \r
+  HcDev           - USB2_HC_DEV\r
   DeviceAddress   - address of usb device\r
   EndPointAddress - address of endpoint\r
   DataToggle      - stored data toggle\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-    \r
+\r
 --*/\r
 {\r
   EFI_STATUS          Status;\r
@@ -2578,7 +2726,7 @@ Returns:
 \r
   Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleDisable TimeOut\n"));\r
+    DEBUG ((gEHCErrorLevel, "EHCI: WaitForPeriodicScheduleDisable TimeOut\n"));\r
     Status = EFI_TIMEOUT;\r
     goto exit;\r
   }\r
@@ -2605,7 +2753,7 @@ Returns:
 \r
     Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleEnable TimeOut\n"));\r
+      DEBUG ((gEHCErrorLevel, "EHCI: WaitForPeriodicScheduleEnable TimeOut\n"));\r
       Status = EFI_TIMEOUT;\r
       goto exit;\r
     }\r
@@ -2637,15 +2785,15 @@ CleanUpAllAsyncRequestTransfer (
 Routine Description:\r
 \r
   Clean up all asynchronous request transfer\r
-  \r
+\r
 Arguments:\r
 \r
-  HcDev - USB2_HC_DEV \r
-  \r
+  HcDev - USB2_HC_DEV\r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   EHCI_ASYNC_REQUEST  *AsyncRequestPtr;\r
@@ -2681,15 +2829,15 @@ ZeroOutQhOverlay (
 Routine Description:\r
 \r
   Zero out the fields in Qh structure\r
-  \r
+\r
 Arguments:\r
 \r
   QhPtr - A pointer to Qh structure\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   QhPtr->Qh.CurrentQtdPointer   = 0;\r
@@ -2711,11 +2859,6 @@ Returns:
   QhPtr->Qh.FrameTag            = 0;\r
   QhPtr->Qh.BufferPointer3      = 0;\r
   QhPtr->Qh.BufferPointer4      = 0;\r
-  QhPtr->Qh.ExtBufferPointer0   = 0;\r
-  QhPtr->Qh.ExtBufferPointer1   = 0;\r
-  QhPtr->Qh.ExtBufferPointer2   = 0;\r
-  QhPtr->Qh.ExtBufferPointer3   = 0;\r
-  QhPtr->Qh.ExtBufferPointer4   = 0;\r
 }\r
 \r
 VOID\r
@@ -2729,17 +2872,17 @@ UpdateAsyncRequestTransfer (
 Routine Description:\r
 \r
   Update asynchronous request transfer\r
-  \r
+\r
 Arguments:\r
 \r
-  AsyncRequestPtr  - A pointer to async request  \r
-  TransferResult   - transfer result \r
+  AsyncRequestPtr  - A pointer to async request\r
+  TransferResult   - transfer result\r
   ErrQtdPos        - postion of error Qtd\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
-  \r
+\r
 --*/\r
 {\r
   EHCI_QTD_ENTITY *QtdPtr;\r
@@ -2747,7 +2890,7 @@ Returns:
   QtdPtr      = NULL;\r
 \r
   if (EFI_USB_NOERROR == TransferResult) {\r
-  \r
+\r
     //\r
     // Update Qh for next trigger\r
     //\r
@@ -2811,7 +2954,7 @@ Returns:
 \r
   TRUE    Qtds finished\r
   FALSE   Not finish\r
-  \r
+\r
 --*/\r
 {\r
   UINTN           ActualLenPerQtd;\r
@@ -2829,25 +2972,37 @@ Returns:
   QtdHwPtr  = &(QtdPtr->Qtd);\r
 \r
   while (NULL != QtdHwPtr) {\r
-\r
     if (IsQtdStatusActive (QtdHwPtr)) {\r
       *Result |= EFI_USB_ERR_NOTEXECUTE;\r
     }\r
 \r
     if (IsQtdStatusHalted (QtdHwPtr)) {\r
+\r
+      DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_HALTED 0x%X\n", QtdHwPtr->Status));\r
       *Result |= EFI_USB_ERR_STALL;\r
     }\r
 \r
     if (IsQtdStatusBufferError (QtdHwPtr)) {\r
+      DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_BUFFER_ERR 0x%X\n", QtdHwPtr->Status));\r
       *Result |= EFI_USB_ERR_BUFFER;\r
     }\r
 \r
     if (IsQtdStatusBabbleError (QtdHwPtr)) {\r
+      DEBUG ((gEHCErrorLevel, "EHCI: StatusBufferError 0x%X\n", QtdHwPtr->Status));\r
       *Result |= EFI_USB_ERR_BABBLE;\r
     }\r
 \r
     if (IsQtdStatusTransactionError (QtdHwPtr)) {\r
-      *Result |= EFI_USB_ERR_TIMEOUT;\r
+\r
+      //\r
+      //Exclude Special Case\r
+      //\r
+      if (((QtdHwPtr->Status & QTD_STATUS_HALTED) == QTD_STATUS_HALTED) ||\r
+          ((QtdHwPtr->Status & QTD_STATUS_ACTIVE) == QTD_STATUS_ACTIVE) ||\r
+          ((QtdHwPtr->ErrorCount != QTD_ERROR_COUNTER))) {\r
+        *Result |= EFI_USB_ERR_TIMEOUT;\r
+        DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_TRANSACTION_ERR: 0x%X\n", QtdHwPtr->Status));\r
+      }\r
     }\r
 \r
     ActualLenPerQtd     = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;\r
@@ -2864,16 +3019,21 @@ Returns:
       break;\r
     }\r
 \r
-    if ((!IsControl) && (QtdPtr->TotalBytes > 0)) {\r
+    if ((INPUT_PACKET_PID_CODE == QtdHwPtr->PidCode)&& (QtdPtr->TotalBytes > 0)) {\r
       //\r
-      // Did something, but isn't full workload\r
+      // Short Packet: IN, Short\r
       //\r
+      DEBUG ((gEHCDebugLevel, "EHCI: Short Packet Status: 0x%x\n", QtdHwPtr->Status));\r
       break;\r
     }\r
 \r
-    (*ErrQtdPos)++;\r
-    QtdPtr   = QtdPtr->Next;\r
-    QtdHwPtr = &(QtdPtr->Qtd);\r
+    if (QtdPtr->Next != NULL) {\r
+      (*ErrQtdPos)++;\r
+      QtdPtr   = QtdPtr->Next;\r
+      QtdHwPtr = &(QtdPtr->Qtd);\r
+    } else {\r
+      QtdHwPtr = NULL;\r
+    }\r
 \r
   }\r
 \r
@@ -2901,16 +3061,16 @@ Arguments:
   HcDev            - USB2_HC_DEV\r
   IsControl        - Is control transfer or not\r
   QhPtr            - A pointer to Qh\r
-  ActualLen        - Actual transfered Len \r
+  ActualLen        - Actual transfered Len\r
   DataToggle       - Data Toggle\r
   TimeOut          - TimeOut threshold\r
   TransferResult   - Transfer result\r
-  \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS      Sucess\r
   EFI_DEVICE_ERROR Fail\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -2924,7 +3084,7 @@ Returns:
   *ActualLen      = 0;\r
   Finished        = FALSE;\r
 \r
-  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;\r
+  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50);\r
 \r
   do {\r
     *TransferResult = 0;\r
@@ -2951,6 +3111,7 @@ Returns:
 \r
   if (EFI_USB_NOERROR != *TransferResult) {\r
     if (0 == Delay) {\r
+      DEBUG((gEHCErrorLevel, "EHCI: QTDS TimeOut\n"));\r
       Status = EFI_TIMEOUT;\r
     } else {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -2961,7 +3122,7 @@ Returns:
   // Special for Bulk and Interrupt Transfer\r
   //\r
   *DataToggle = (UINT8) QhPtr->Qh.DataToggle;\r
-  \r
+\r
   return Status;\r
 }\r
 \r
@@ -2972,30 +3133,30 @@ AsyncRequestMoniter (
   )\r
 /*++\r
 Routine Description:\r
-  \r
+\r
   Interrupt transfer periodic check handler\r
-    \r
+\r
 Arguments:\r
   Event    - Interrupt event\r
   Context  - Pointer to USB2_HC_DEV\r
-    \r
+\r
 Returns:\r
 \r
   EFI_SUCCESS        Success\r
   EFI_DEVICE_ERROR   Fail\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS          Status;\r
   USB2_HC_DEV         *HcDev;\r
   EHCI_ASYNC_REQUEST  *AsyncRequestPtr;\r
+  EHCI_ASYNC_REQUEST  *NextPtr;\r
   EHCI_QTD_HW         *QtdHwPtr;\r
   UINTN               ErrQtdPos;\r
   UINTN               ActualLen;\r
   UINT32              TransferResult;\r
   UINT8               *ReceiveBuffer;\r
   UINT8               *ProcessBuffer;\r
-  EHCI_ASYNC_REQUEST  *NextPtr;\r
 \r
   Status          = EFI_SUCCESS;\r
   QtdHwPtr        = NULL;\r
@@ -3011,10 +3172,10 @@ Returns:
     ActualLen       = 0;\r
 \r
     CheckQtdsTransferResult (\r
-      FALSE, \r
-      AsyncRequestPtr->QhPtr, \r
-      &TransferResult, \r
-      &ErrQtdPos, \r
+      FALSE,\r
+      AsyncRequestPtr->QhPtr,\r
+      &TransferResult,\r
+      &ErrQtdPos,\r
       &ActualLen\r
       );\r
 \r
@@ -3032,7 +3193,7 @@ Returns:
     }\r
 \r
     QtdHwPtr = &(AsyncRequestPtr->QhPtr->FirstQtdPtr->Qtd);\r
-    ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << 12) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);\r
+    ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << EFI_PAGE_SHIFT) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);\r
     CopyMem (\r
       ProcessBuffer,\r
       ReceiveBuffer,\r
@@ -3052,7 +3213,7 @@ Returns:
     } else {\r
 \r
       //\r
-      // leave error recovery to its related device driver. A common case of \r
+      // leave error recovery to its related device driver. A common case of\r
       // the error recovery is to re-submit the interrupt transfer.\r
       // When an interrupt transfer is re-submitted, its position in the linked\r
       // list is changed. It is inserted to the head of the linked list, while\r