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++; }