MdeModulePkg/Xhci: Remove TRB when canceling Async Int Transfer
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 31 May 2017 02:56:35 +0000 (10:56 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Fri, 2 Jun 2017 06:23:29 +0000 (14:23 +0800)
Some USB devices don't report data periodically through Int
Transfer. They report data only when be asked. If the TRB
is not removed from the XHCI HW, when next time HOST asks
data again, the data is reported but consumed by the previous
TRB, which results the HOST thinks data never comes.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c

index 58a2f984a9450a127e065f95fa8ec35580ef15c7..9e34faf2637d8031b275fd93872c856dfc6f8033 100644 (file)
@@ -1319,6 +1319,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 +1331,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 +1364,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