]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c
MdeModulePkg XhciPei/UsbBusPei: Add XHCI recovery support.
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusPei / UsbIoPeim.c
index 897b22896a2bc5d9a706df58ccfcc70697d354d4..d13a7ee0a336fc9240f2e6b5982f070ee73c7821 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 The module is used to implement Usb Io PPI interfaces.\r
 \r
 /** @file\r
 The module is used to implement Usb Io PPI interfaces.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved. <BR>\r
   \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
   \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -24,7 +24,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   @param  This                   The pointer of PEI_USB_IO_PPI.\r
   @param  Request                USB device request to send.\r
   @param  Direction              Specifies the data direction for the data stage.\r
   @param  This                   The pointer of PEI_USB_IO_PPI.\r
   @param  Request                USB device request to send.\r
   @param  Direction              Specifies the data direction for the data stage.\r
-  @param  Timeout                Indicates the maximum timeout, in millisecond.\r
+  @param  Timeout                Indicates the maximum timeout, in millisecond. If Timeout\r
+                                 is 0, then the caller must wait for the function to be\r
+                                 completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.\r
   @param  Data                   Data buffer to be transmitted or received from USB device.\r
   @param  DataLength             The size (in bytes) of the data buffer.\r
 \r
   @param  Data                   Data buffer to be transmitted or received from USB device.\r
   @param  DataLength             The size (in bytes) of the data buffer.\r
 \r
@@ -50,9 +52,38 @@ PeiUsbControlTransfer (
   EFI_STATUS                  Status;\r
   PEI_USB_DEVICE              *PeiUsbDev;\r
   UINT32                      TransferResult;\r
   EFI_STATUS                  Status;\r
   PEI_USB_DEVICE              *PeiUsbDev;\r
   UINT32                      TransferResult;\r
+  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;\r
+  UINT8                       EndpointIndex;\r
 \r
   PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);\r
 \r
 \r
   PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);\r
 \r
+  EndpointDescriptor = NULL;\r
+  EndpointIndex = 0;\r
+\r
+  if ((Request->Request     == USB_REQ_CLEAR_FEATURE) &&\r
+      (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&\r
+      (Request->Value       == USB_FEATURE_ENDPOINT_HALT)) {\r
+    //\r
+    // Request->Index is the Endpoint Address, use it to get the Endpoint Index.\r
+    //\r
+    while (EndpointIndex < MAX_ENDPOINT) {\r
+      Status = PeiUsbGetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      if (EndpointDescriptor->EndpointAddress == Request->Index) {\r
+        break;\r
+      }\r
+\r
+      EndpointIndex++;\r
+    }\r
+\r
+    if (EndpointIndex == MAX_ENDPOINT) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
   if (PeiUsbDev->Usb2HcPpi != NULL) {\r
     Status = PeiUsbDev->Usb2HcPpi->ControlTransfer (\r
                         PeiServices,\r
   if (PeiUsbDev->Usb2HcPpi != NULL) {\r
     Status = PeiUsbDev->Usb2HcPpi->ControlTransfer (\r
                         PeiServices,\r
@@ -74,7 +105,7 @@ PeiUsbControlTransfer (
                         PeiUsbDev->UsbHcPpi,\r
                         PeiUsbDev->DeviceAddress,\r
                         PeiUsbDev->DeviceSpeed,\r
                         PeiUsbDev->UsbHcPpi,\r
                         PeiUsbDev->DeviceAddress,\r
                         PeiUsbDev->DeviceSpeed,\r
-                        PeiUsbDev->MaxPacketSize0,\r
+                        (UINT8) PeiUsbDev->MaxPacketSize0,\r
                         Request,\r
                         Direction,\r
                         Data,\r
                         Request,\r
                         Direction,\r
                         Data,\r
@@ -83,6 +114,19 @@ PeiUsbControlTransfer (
                         &TransferResult\r
                         );\r
   }\r
                         &TransferResult\r
                         );\r
   }\r
+\r
+  //\r
+  // Reset the endpoint toggle when endpoint stall is cleared\r
+  //\r
+  if ((Request->Request     == USB_REQ_CLEAR_FEATURE) &&\r
+      (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&\r
+      (Request->Value       == USB_FEATURE_ENDPOINT_HALT)) {\r
+    if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {\r
+      PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
+    }\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "PeiUsbControlTransfer: %r\n", Status));\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
@@ -96,7 +140,9 @@ PeiUsbControlTransfer (
                                 from or receive into.\r
   @param  DataLength            The lenght of the data buffer.\r
   @param  Timeout               Indicates the maximum time, in millisecond, which the\r
                                 from or receive into.\r
   @param  DataLength            The lenght of the data buffer.\r
   @param  Timeout               Indicates the maximum time, in millisecond, which the\r
-                                transfer is allowed to complete.\r
+                                transfer is allowed to complete. If Timeout is 0, then\r
+                                the caller must wait for the function to be completed\r
+                                until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.\r
 \r
   @retval EFI_SUCCESS           The transfer was completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.\r
 \r
   @retval EFI_SUCCESS           The transfer was completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.\r
@@ -190,9 +236,10 @@ PeiUsbBulkTransfer (
   }\r
 \r
   if (OldToggle != DataToggle) {\r
   }\r
 \r
   if (OldToggle != DataToggle) {\r
-    PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
+    PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
   }\r
 \r
   }\r
 \r
+  DEBUG ((EFI_D_INFO, "PeiUsbBulkTransfer: %r\n", Status));\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r