MdeModulePkg/XhciDxe: Refine IsTransferRingTrb and IsAsyncIntTrb
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 28 Jun 2017 08:55:12 +0000 (16:55 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Wed, 5 Jul 2017 03:31:05 +0000 (11:31 +0800)
Current implementation of IsTransferRingTrb only checks whether
the TRB is in the RING of the URB.
The patch enhanced the logic to check that whether the TRB belongs
to the transaction of URB.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c

index 457344051b7dcd5a074efa1c3acacbc1bb5802fc..a72a104b803246261bbb147e01fda11804c7feaf 100644 (file)
@@ -977,45 +977,42 @@ XhcFreeSched (
 }\r
 \r
 /**\r
-  Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.\r
+  Check if the Trb is a transaction of the URB.\r
 \r
-  @param Xhc    The XHCI Instance.\r
-  @param Trb    The TRB to be checked.\r
-  @param Urb    The pointer to the matched Urb.\r
+  @param Trb    The TRB to be checked\r
+  @param Urb    The URB to be checked.\r
 \r
-  @retval TRUE  The Trb is matched with a transaction of the URBs in the async list.\r
-  @retval FALSE The Trb is not matched with any URBs in the async list.\r
+  @retval TRUE  It is a transaction of the URB.\r
+  @retval FALSE It is not any transaction of the URB.\r
 \r
 **/\r
 BOOLEAN\r
-IsAsyncIntTrb (\r
+IsTransferRingTrb (\r
   IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  TRB_TEMPLATE        *Trb,\r
-  OUT URB                 **Urb\r
+  IN  URB                 *Urb\r
   )\r
 {\r
-  LIST_ENTRY              *Entry;\r
-  LIST_ENTRY              *Next;\r
-  TRB_TEMPLATE            *CheckedTrb;\r
-  URB                     *CheckedUrb;\r
-  UINTN                   Index;\r
+  LINK_TRB      *LinkTrb;\r
+  TRB_TEMPLATE  *CheckedTrb;\r
+  UINTN         Index;\r
+  EFI_PHYSICAL_ADDRESS PhyAddr;\r
 \r
-  EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
-    CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
-    CheckedTrb = CheckedUrb->TrbStart;\r
-    for (Index = 0; Index < CheckedUrb->TrbNum; Index++) {\r
-      if (Trb == CheckedTrb) {\r
-        *Urb = CheckedUrb;\r
-        return TRUE;\r
-      }\r
-      CheckedTrb++;\r
-      //\r
-      // If the checked TRB is the link TRB at the end of the transfer ring,\r
-      // recircle it to the head of the ring.\r
-      //\r
-      if (CheckedTrb->Type == TRB_TYPE_LINK) {\r
-        CheckedTrb = (TRB_TEMPLATE*) CheckedUrb->Ring->RingSeg0;\r
-      }\r
+  CheckedTrb = Urb->TrbStart;\r
+  for (Index = 0; Index < Urb->TrbNum; Index++) {\r
+    if (Trb == CheckedTrb) {\r
+      return TRUE;\r
+    }\r
+    CheckedTrb++;\r
+    //\r
+    // If the checked TRB is the link TRB at the end of the transfer ring,\r
+    // recircle it to the head of the ring.\r
+    //\r
+    if (CheckedTrb->Type == TRB_TYPE_LINK) {\r
+      LinkTrb = (LINK_TRB *) CheckedTrb;\r
+      PhyAddr = (EFI_PHYSICAL_ADDRESS)(LinkTrb->PtrLo | LShiftU64 ((UINT64) LinkTrb->PtrHi, 32));\r
+      CheckedTrb = (TRB_TEMPLATE *)(UINTN) UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN) PhyAddr, sizeof (TRB_TEMPLATE));\r
+      ASSERT (CheckedTrb == Urb->Ring->RingSeg0);\r
     }\r
   }\r
 \r
@@ -1023,38 +1020,39 @@ IsAsyncIntTrb (
 }\r
 \r
 /**\r
-  Check if the Trb is a transaction of the URB.\r
+  Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list.\r
 \r
-  @param Trb    The TRB to be checked\r
-  @param Urb    The transfer ring to be checked.\r
+  @param Xhc    The XHCI Instance.\r
+  @param Trb    The TRB to be checked.\r
+  @param Urb    The pointer to the matched Urb.\r
 \r
-  @retval TRUE  It is a transaction of the URB.\r
-  @retval FALSE It is not any transaction of the URB.\r
+  @retval TRUE  The Trb is matched with a transaction of the URBs in the async list.\r
+  @retval FALSE The Trb is not matched with any URBs in the async list.\r
 \r
 **/\r
 BOOLEAN\r
-IsTransferRingTrb (\r
+IsAsyncIntTrb (\r
+  IN  USB_XHCI_INSTANCE   *Xhc,\r
   IN  TRB_TEMPLATE        *Trb,\r
-  IN  URB                 *Urb\r
+  OUT URB                 **Urb\r
   )\r
 {\r
-  TRB_TEMPLATE  *CheckedTrb;\r
-  UINTN         Index;\r
-\r
-  CheckedTrb = Urb->Ring->RingSeg0;\r
-\r
-  ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER);\r
+  LIST_ENTRY              *Entry;\r
+  LIST_ENTRY              *Next;\r
+  URB                     *CheckedUrb;\r
 \r
-  for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) {\r
-    if (Trb == CheckedTrb) {\r
+  EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
+    CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
+    if (IsTransferRingTrb (Xhc, Trb, CheckedUrb)) {\r
+      *Urb = CheckedUrb;\r
       return TRUE;\r
     }\r
-    CheckedTrb++;\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
+\r
 /**\r
   Check the URB's execution result and update the URB's\r
   result accordingly.\r
@@ -1131,7 +1129,7 @@ XhcCheckUrbResult (
     // This way is used to avoid that those completed async transfer events don't get\r
     // handled in time and are flushed by newer coming events.\r
     //\r
-    if (IsTransferRingTrb (TRBPtr, Urb)) {\r
+    if (IsTransferRingTrb (Xhc, TRBPtr, Urb)) {\r
       CheckedUrb = Urb;\r
     } else if (IsAsyncIntTrb (Xhc, TRBPtr, &AsyncUrb)) {    \r
       CheckedUrb = AsyncUrb;\r