]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
MdeModulePkg/XhciDxe: Dump the CMD/EVENT/INT/BULK ring information
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciSched.c
index 58a2f984a9450a127e065f95fa8ec35580ef15c7..f7f3409686b8c9d13484b0f2cbb571475b63809b 100644 (file)
@@ -604,8 +604,6 @@ XhcInitSched (
   XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT(CmdRingPhy));\r
   XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRingPhy));\r
 \r
-  DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0));\r
-\r
   //\r
   // Disable the 'interrupter enable' bit in USB_CMD\r
   // and clear IE & IP bit in all Interrupter X Management Registers.\r
@@ -620,7 +618,10 @@ XhcInitSched (
   // Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer\r
   //\r
   CreateEventRing (Xhc, &Xhc->EventRing);\r
-  DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0));\r
+  DEBUG ((DEBUG_INFO, "XhcInitSched: Created CMD ring [%p~%p) EVENT ring [%p~%p)\n",\r
+    Xhc->CmdRing.RingSeg0,        (UINTN)Xhc->CmdRing.RingSeg0 + sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER,\r
+    Xhc->EventRing.EventRingSeg0, (UINTN)Xhc->EventRing.EventRingSeg0 + sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER\r
+    ));\r
 }\r
 \r
 /**\r
@@ -977,45 +978,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 +1021,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 +1130,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
@@ -1319,6 +1318,7 @@ XhciDelAsyncIntTransfer (
   LIST_ENTRY              *Next;\r
   URB                     *Urb;\r
   EFI_USB_DATA_DIRECTION  Direction;\r
+  EFI_STATUS              Status;\r
 \r
   Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;\r
   EpNum    &= 0x0F;\r
@@ -1330,6 +1330,15 @@ XhciDelAsyncIntTransfer (
     if ((Urb->Ep.BusAddr == BusAddr) &&\r
         (Urb->Ep.EpAddr == EpNum) &&\r
         (Urb->Ep.Direction == Direction)) {\r
+      //\r
+      // Device doesn't finish the IntTransfer until real data comes\r
+      // So the TRB should be removed as well.\r
+      //\r
+      Status = XhcDequeueTrbFromEndpoint (Xhc, Urb);\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((EFI_D_ERROR, "XhciDelAsyncIntTransfer: XhcDequeueTrbFromEndpoint failed\n"));\r
+      }\r
+\r
       RemoveEntryList (&Urb->UrbList);\r
       FreePool (Urb->Data);\r
       XhcFreeUrb (Xhc, Urb);\r
@@ -1354,9 +1363,20 @@ XhciDelAllAsyncIntTransfers (
   LIST_ENTRY              *Entry;\r
   LIST_ENTRY              *Next;\r
   URB                     *Urb;\r
+  EFI_STATUS              Status;\r
 \r
   EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) {\r
     Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList);\r
+\r
+    //\r
+    // Device doesn't finish the IntTransfer until real data comes\r
+    // So the TRB should be removed as well.\r
+    //\r
+    Status = XhcDequeueTrbFromEndpoint (Xhc, Urb);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "XhciDelAllAsyncIntTransfers: XhcDequeueTrbFromEndpoint failed\n"));\r
+    }\r
+\r
     RemoveEntryList (&Urb->UrbList);\r
     FreePool (Urb->Data);\r
     XhcFreeUrb (Xhc, Urb);\r
@@ -2649,6 +2669,11 @@ XhcInitializeEndpointContext (
           EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
           Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
           CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+          DEBUG ((DEBUG_INFO, "Endpoint[%x]: Created BULK ring [%p~%p)\n",\r
+                  EpDesc->EndpointAddress,\r
+                  EndpointTransferRing->RingSeg0,\r
+                  (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+                  ));\r
         }\r
 \r
         break;\r
@@ -2717,6 +2742,11 @@ XhcInitializeEndpointContext (
           EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
           Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
           CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+          DEBUG ((DEBUG_INFO, "Endpoint[%x]: Created INT ring [%p~%p)\n",\r
+                  EpDesc->EndpointAddress,\r
+                  EndpointTransferRing->RingSeg0,\r
+                  (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+                  ));\r
         }\r
         break;\r
 \r
@@ -2831,6 +2861,11 @@ XhcInitializeEndpointContext64 (
           EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
           Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
           CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+          DEBUG ((DEBUG_INFO, "Endpoint64[%x]: Created BULK ring [%p~%p)\n",\r
+                  EpDesc->EndpointAddress,\r
+                  EndpointTransferRing->RingSeg0,\r
+                  (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+                  ));\r
         }\r
 \r
         break;\r
@@ -2899,6 +2934,11 @@ XhcInitializeEndpointContext64 (
           EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING));\r
           Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing;\r
           CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]);\r
+          DEBUG ((DEBUG_INFO, "Endpoint64[%x]: Created INT ring [%p~%p)\n",\r
+                  EpDesc->EndpointAddress,\r
+                  EndpointTransferRing->RingSeg0,\r
+                  (UINTN) EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (TRB_TEMPLATE)\r
+                  ));\r
         }\r
         break;\r
 \r