]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c
MdeModulePkg XhciPei: Remove redundant functions
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciPei / XhcPeim.c
index eaea38d94d299386fcbd62016f2fe755f2ef55ab..ee4d1f97bd047a792ba81813d92a6498252f9866 100644 (file)
@@ -2,7 +2,7 @@
 PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
 which is used to enable recovery function from USB Drivers.\r
 \r
 PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
 which is used to enable recovery function from USB Drivers.\r
 \r
-Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2014 - 2017, 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
@@ -211,29 +211,7 @@ XhcPeiReadCapRegister (
   return Data;\r
 }\r
 \r
   return Data;\r
 }\r
 \r
-/**\r
-  Read XHCI door bell register.\r
-\r
-  @param  Xhc       The XHCI device.\r
-  @param  Offset    The offset of the door bell register.\r
-\r
-  @return The register content read\r
-\r
-**/\r
-UINT32\r
-XhcPeiReadDoorBellReg (\r
-  IN  PEI_XHC_DEV       *Xhc,\r
-  IN  UINT32            Offset\r
-  )\r
-{\r
-  UINT32                  Data;\r
-\r
-  ASSERT (Xhc->DBOff != 0);\r
 \r
 \r
-  Data = MmioRead32 (Xhc->UsbHostControllerBaseAddress + Xhc->DBOff + Offset);\r
-\r
-  return Data;\r
-}\r
 \r
 /**\r
   Write the data to the XHCI door bell register.\r
 \r
 /**\r
   Write the data to the XHCI door bell register.\r
@@ -407,6 +385,12 @@ XhcPeiResetHC (
   }\r
 \r
   XhcPeiSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
   }\r
 \r
   XhcPeiSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
+  //\r
+  // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset.\r
+  // Otherwise there may have the timeout case happened.\r
+  // The below is a workaround to solve such problem.\r
+  //\r
+  MicroSecondDelay (1000);\r
   Status = XhcPeiWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
 ON_EXIT:\r
   DEBUG ((EFI_D_INFO, "XhcPeiResetHC: %r\n", Status));\r
   Status = XhcPeiWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
 ON_EXIT:\r
   DEBUG ((EFI_D_INFO, "XhcPeiResetHC: %r\n", Status));\r
@@ -656,21 +640,28 @@ XhcPeiControlTransfer (
     if (EFI_ERROR(RecoveryStatus)) {\r
       DEBUG((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiDequeueTrbFromEndpoint failed\n"));\r
     }\r
     if (EFI_ERROR(RecoveryStatus)) {\r
       DEBUG((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiDequeueTrbFromEndpoint failed\n"));\r
     }\r
-    goto FREE_URB;\r
+    XhcPeiFreeUrb (Xhc, Urb);\r
+    goto ON_EXIT;\r
   } else {\r
     if (*TransferResult == EFI_USB_NOERROR) {\r
       Status = EFI_SUCCESS;\r
   } else {\r
     if (*TransferResult == EFI_USB_NOERROR) {\r
       Status = EFI_SUCCESS;\r
-    } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
+    } else if ((*TransferResult == EFI_USB_ERR_STALL) || (*TransferResult == EFI_USB_ERR_BABBLE)) {\r
       RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);\r
       if (EFI_ERROR (RecoveryStatus)) {\r
         DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));\r
       }\r
       Status = EFI_DEVICE_ERROR;\r
       RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);\r
       if (EFI_ERROR (RecoveryStatus)) {\r
         DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));\r
       }\r
       Status = EFI_DEVICE_ERROR;\r
-      goto FREE_URB;\r
+      XhcPeiFreeUrb (Xhc, Urb);\r
+      goto ON_EXIT;\r
     } else {\r
     } else {\r
-      goto FREE_URB;\r
+      XhcPeiFreeUrb (Xhc, Urb);\r
+      goto ON_EXIT;\r
     }\r
   }\r
     }\r
   }\r
+  //\r
+  // Unmap data before consume.\r
+  //\r
+  XhcPeiFreeUrb (Xhc, Urb);\r
 \r
   //\r
   // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint.\r
 \r
   //\r
   // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint.\r
@@ -687,7 +678,7 @@ XhcPeiControlTransfer (
       // 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
       // 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
         //\r
         // If it's a usb3.0 device, then its max packet size is a 2^n.\r
         //\r
@@ -698,7 +689,7 @@ XhcPeiControlTransfer (
       Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));\r
       if (Xhc->UsbDevContext[SlotId].ConfDesc == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
       Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));\r
       if (Xhc->UsbDevContext[SlotId].ConfDesc == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
-        goto FREE_URB;\r
+        goto ON_EXIT;\r
       }\r
       if (Xhc->HcCParams.Data.Csz == 0) {\r
         Status = XhcPeiEvaluateContext (Xhc, SlotId, MaxPacket0);\r
       }\r
       if (Xhc->HcCParams.Data.Csz == 0) {\r
         Status = XhcPeiEvaluateContext (Xhc, SlotId, MaxPacket0);\r
@@ -716,7 +707,7 @@ XhcPeiControlTransfer (
         Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool (*DataLength);\r
         if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
         Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool (*DataLength);\r
         if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
-          goto FREE_URB;\r
+          goto ON_EXIT;\r
         }\r
         CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);\r
       }\r
         }\r
         CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);\r
       }\r
@@ -838,9 +829,6 @@ XhcPeiControlTransfer (
     *(UINT32 *) Data = *(UINT32 *) &PortStatus;\r
   }\r
 \r
     *(UINT32 *) Data = *(UINT32 *) &PortStatus;\r
   }\r
 \r
-FREE_URB:\r
-  XhcPeiFreeUrb (Xhc, Urb);\r
-\r
 ON_EXIT:\r
 \r
   if (EFI_ERROR (Status)) {\r
 ON_EXIT:\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -982,7 +970,7 @@ XhcPeiBulkTransfer (
   } else {\r
     if (*TransferResult == EFI_USB_NOERROR) {\r
       Status = EFI_SUCCESS;\r
   } else {\r
     if (*TransferResult == EFI_USB_NOERROR) {\r
       Status = EFI_SUCCESS;\r
-    } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
+    } else if ((*TransferResult == EFI_USB_ERR_STALL) || (*TransferResult == EFI_USB_ERR_BABBLE)) {\r
       RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);\r
       if (EFI_ERROR (RecoveryStatus)) {\r
         DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));\r
       RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);\r
       if (EFI_ERROR (RecoveryStatus)) {\r
         DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));\r
@@ -1392,6 +1380,36 @@ XhcPeiGetRootHubPortStatus (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  One notified function to stop the Host Controller at the end of PEI\r
+\r
+  @param[in]  PeiServices        Pointer to PEI Services Table.\r
+  @param[in]  NotifyDescriptor   Pointer to the descriptor for the Notification event that\r
+                                 caused this function to execute.\r
+  @param[in]  Ppi                Pointer to the PPI data associated with this function.\r
+\r
+  @retval     EFI_SUCCESS  The function completes successfully\r
+  @retval     others\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+XhcEndOfPei (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+{\r
+  PEI_XHC_DEV    *Xhc;\r
+\r
+  Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS_NOTIFY(NotifyDescriptor);\r
+\r
+  XhcPeiHaltHC (Xhc, XHC_GENERIC_TIMEOUT);\r
+\r
+  XhcPeiFreeSched (Xhc);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   @param FileHandle     Handle of the file being invoked.\r
   @param PeiServices    Describes the list of possible PEI Services.\r
 /**\r
   @param FileHandle     Handle of the file being invoked.\r
   @param PeiServices    Describes the list of possible PEI Services.\r
@@ -1433,6 +1451,8 @@ XhcPeimEntry (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  IoMmuInit ();\r
+\r
   Index = 0;\r
   while (TRUE) {\r
     Status = UsbControllerPpi->GetUsbController (\r
   Index = 0;\r
   while (TRUE) {\r
     Status = UsbControllerPpi->GetUsbController (\r
@@ -1524,7 +1544,12 @@ XhcPeimEntry (
     XhcDev->PpiDescriptor.Guid = &gPeiUsb2HostControllerPpiGuid;\r
     XhcDev->PpiDescriptor.Ppi = &XhcDev->Usb2HostControllerPpi;\r
 \r
     XhcDev->PpiDescriptor.Guid = &gPeiUsb2HostControllerPpiGuid;\r
     XhcDev->PpiDescriptor.Ppi = &XhcDev->Usb2HostControllerPpi;\r
 \r
+    XhcDev->EndOfPeiNotifyList.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
+    XhcDev->EndOfPeiNotifyList.Guid = &gEfiEndOfPeiSignalPpiGuid;\r
+    XhcDev->EndOfPeiNotifyList.Notify = XhcEndOfPei;\r
+\r
     PeiServicesInstallPpi (&XhcDev->PpiDescriptor);\r
     PeiServicesInstallPpi (&XhcDev->PpiDescriptor);\r
+    PeiServicesNotifyPpi (&XhcDev->EndOfPeiNotifyList);\r
 \r
     Index++;\r
   }\r
 \r
     Index++;\r
   }\r