]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
MdeModulePkg/Usb: Fix wrong condition judgment to support usb3.1 dev
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / Xhci.c
index bd308613f6eade89246b54be4d292eae93b5380e..4798bea86061efd107dd6dbeb7b2c2e948b3056a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The XHCI controller driver.\r
 \r
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
 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
@@ -905,17 +905,28 @@ XhcControlTransfer (
   *TransferResult = Urb->Result;\r
   *DataLength     = Urb->Completed;\r
 \r
-  if (*TransferResult == EFI_USB_NOERROR) {\r
-    Status = EFI_SUCCESS;\r
-  } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
-    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
-    if (EFI_ERROR (RecoveryStatus)) {\r
-      DEBUG ((EFI_D_ERROR, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n"));\r
+  if (Status == EFI_TIMEOUT) {\r
+    //\r
+    // The transfer timed out. Abort the transfer by dequeueing of the TD.\r
+    //\r
+    RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb);\r
+    if (EFI_ERROR(RecoveryStatus)) {\r
+      DEBUG((EFI_D_ERROR, "XhcControlTransfer: XhcDequeueTrbFromEndpoint failed\n"));\r
     }\r
-    Status = EFI_DEVICE_ERROR;\r
     goto FREE_URB;\r
   } else {\r
-    goto FREE_URB;\r
+    if (*TransferResult == EFI_USB_NOERROR) {\r
+      Status = EFI_SUCCESS;\r
+    } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
+      RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
+      if (EFI_ERROR (RecoveryStatus)) {\r
+        DEBUG ((EFI_D_ERROR, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n"));\r
+      }\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto FREE_URB;\r
+    } else {\r
+      goto FREE_URB;\r
+    }\r
   }\r
 \r
   Xhc->PciIo->Flush (Xhc->PciIo);\r
@@ -944,7 +955,7 @@ XhcControlTransfer (
         // Store a copy of device scriptor as hub device need this info to configure endpoint.\r
         //\r
         CopyMem (&Xhc->UsbDevContext[SlotId].DevDesc, Data, *DataLength);\r
-        if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB == 0x0300) {\r
+        if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB >= 0x0300) {\r
           //\r
           // If it's a usb3.0 device, then its max packet size is a 2^n.\r
           //\r
@@ -968,6 +979,10 @@ XhcControlTransfer (
         ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations);\r
         Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength);\r
         CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);\r
+        //\r
+        // Default to use AlternateSetting 0 for all interfaces.\r
+        //\r
+        Xhc->UsbDevContext[SlotId].ActiveAlternateSetting = AllocateZeroPool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->NumInterfaces * sizeof (UINT8));\r
       }\r
     } else if (((DescriptorType == USB_DESC_TYPE_HUB) ||\r
                (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) {\r
@@ -1009,6 +1024,20 @@ XhcControlTransfer (
         break;\r
       }\r
     }\r
+  } else if ((Request->Request     == USB_REQ_SET_INTERFACE) &&\r
+             (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_INTERFACE))) {\r
+    //\r
+    // Hook Set_Interface request from UsbBus as we need configure interface setting.\r
+    // Request->Value indicates AlterlateSetting to set\r
+    // Request->Index indicates Interface to set\r
+    //\r
+    if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] != (UINT8) Request->Value) {\r
+      if (Xhc->HcCParams.Data.Csz == 0) {\r
+        Status = XhcSetInterface (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);\r
+      } else {\r
+        Status = XhcSetInterface64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request);\r
+      }\r
+    }\r
   } else if ((Request->Request     == USB_REQ_GET_STATUS) &&\r
              (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) {\r
     ASSERT (Data != NULL);\r
@@ -1223,14 +1252,24 @@ XhcBulkTransfer (
   *TransferResult = Urb->Result;\r
   *DataLength     = Urb->Completed;\r
 \r
-  if (*TransferResult == EFI_USB_NOERROR) {\r
-    Status = EFI_SUCCESS;\r
-  } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
-    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
-    if (EFI_ERROR (RecoveryStatus)) {\r
-      DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: XhcRecoverHaltedEndpoint failed\n"));\r
+  if (Status == EFI_TIMEOUT) {\r
+    //\r
+    // The transfer timed out. Abort the transfer by dequeueing of the TD.\r
+    //\r
+    RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb);\r
+    if (EFI_ERROR(RecoveryStatus)) {\r
+      DEBUG((EFI_D_ERROR, "XhcBulkTransfer: XhcDequeueTrbFromEndpoint failed\n"));\r
+    }\r
+  } else {\r
+    if (*TransferResult == EFI_USB_NOERROR) {\r
+      Status = EFI_SUCCESS;\r
+    } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
+      RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
+      if (EFI_ERROR (RecoveryStatus)) {\r
+        DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: XhcRecoverHaltedEndpoint failed\n"));\r
+      }\r
+      Status = EFI_DEVICE_ERROR;\r
     }\r
-    Status = EFI_DEVICE_ERROR;\r
   }\r
 \r
   Xhc->PciIo->Flush (Xhc->PciIo);\r
@@ -1465,10 +1504,6 @@ XhcSyncInterruptTransfer (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!XHCI_IS_DATAIN (EndPointAddress)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
   if ((*DataToggle != 1) && (*DataToggle != 0)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1524,14 +1559,24 @@ XhcSyncInterruptTransfer (
   *TransferResult = Urb->Result;\r
   *DataLength     = Urb->Completed;\r
 \r
-  if (*TransferResult == EFI_USB_NOERROR) {\r
-    Status = EFI_SUCCESS;\r
-  } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
-    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
-    if (EFI_ERROR (RecoveryStatus)) {\r
-      DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: XhcRecoverHaltedEndpoint failed\n"));\r
+  if (Status == EFI_TIMEOUT) {\r
+    //\r
+    // The transfer timed out. Abort the transfer by dequeueing of the TD.\r
+    //\r
+    RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb);\r
+    if (EFI_ERROR(RecoveryStatus)) {\r
+      DEBUG((EFI_D_ERROR, "XhcSyncInterruptTransfer: XhcDequeueTrbFromEndpoint failed\n"));\r
+    }\r
+  } else {\r
+    if (*TransferResult == EFI_USB_NOERROR) {\r
+      Status = EFI_SUCCESS;\r
+    } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
+      RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
+      if (EFI_ERROR (RecoveryStatus)) {\r
+        DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: XhcRecoverHaltedEndpoint failed\n"));\r
+      }\r
+      Status = EFI_DEVICE_ERROR;\r
     }\r
-    Status = EFI_DEVICE_ERROR;\r
   }\r
 \r
   Xhc->PciIo->Flush (Xhc->PciIo);\r
@@ -1808,7 +1853,7 @@ XhcCreateUsbHc (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
+                  TPL_NOTIFY,\r
                   XhcMonitorAsyncRequests,\r
                   Xhc,\r
                   &Xhc->PollTimer\r
@@ -1829,7 +1874,7 @@ ON_ERROR:
   One notified function to stop the Host Controller when gBS->ExitBootServices() called.\r
 \r
   @param  Event                   Pointer to this event\r
-  @param  Context                 Event hanlder private data\r
+  @param  Context                 Event handler private data\r
 \r
 **/\r
 VOID\r
@@ -1951,7 +1996,7 @@ XhcDriverBindingStart (
                     &Supports\r
                     );\r
   if (!EFI_ERROR (Status)) {\r
-    Supports &= EFI_PCI_DEVICE_ENABLE;\r
+    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
     Status = PciIo->Attributes (\r
                       PciIo,\r
                       EfiPciIoAttributeOperationEnable,\r