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