summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
diff options
context:
space:
mode:
authorHenz, Patrick <patrick.henz@hpe.com>2023-09-13 02:05:57 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-09-25 02:56:05 +0000
commit43dcf453fc15ca152945ca41dcce7f2f43a14313 (patch)
treee2e6f68e843d79efec6eb73fca4e2ad7552407b8 /MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
parent8b2e6b90b85fd4b1f7f921da09b16f5175acea8a (diff)
downloadedk2-43dcf453fc15ca152945ca41dcce7f2f43a14313.tar.gz
edk2-43dcf453fc15ca152945ca41dcce7f2f43a14313.tar.bz2
edk2-43dcf453fc15ca152945ca41dcce7f2f43a14313.zip
MdeModulePkg/XhciDxe: Use Performance Timer for XHCI Timeouts
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2948 XhciDxe uses the timer functionality provided by the boot services table to detect timeout conditions. This breaks the driver's ExitBootServices call back, as CoreExitBootServices halts the timer before signaling the ExitBootServices event. If the host controller fails to halt in the call back, the timeout condition will never occur and the boot gets stuck in an indefinite spin loop. Use the free running timer provided by TimerLib to calculate timeouts, avoiding the potential hang. Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Ray Ni <ray.ni@intel.com> Signed-off-by: Patrick Henz <patrick.henz@hpe.com> Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Diffstat (limited to 'MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c')
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c72
1 files changed, 29 insertions, 43 deletions
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 53421e64a8..613b1485f1 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -2,6 +2,7 @@
XHCI transfer scheduling routines.
+(C) Copyright 2023 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>
Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved.<BR>
@@ -1276,15 +1277,14 @@ EXIT:
/**
Execute the transfer by polling the URB. This is a synchronous operation.
- @param Xhc The XHCI Instance.
- @param CmdTransfer The executed URB is for cmd transfer or not.
- @param Urb The URB to execute.
- @param Timeout The time to wait before abort, in millisecond.
+ @param Xhc The XHCI Instance.
+ @param CmdTransfer The executed URB is for cmd transfer or not.
+ @param Urb The URB to execute.
+ @param Timeout The time to wait before abort, in millisecond.
- @return EFI_DEVICE_ERROR The transfer failed due to transfer error.
- @return EFI_TIMEOUT The transfer failed due to time out.
- @return EFI_SUCCESS The transfer finished OK.
- @retval EFI_OUT_OF_RESOURCES Memory for the timer event could not be allocated.
+ @return EFI_DEVICE_ERROR The transfer failed due to transfer error.
+ @return EFI_TIMEOUT The transfer failed due to time out.
+ @return EFI_SUCCESS The transfer finished OK.
**/
EFI_STATUS
@@ -1299,12 +1299,14 @@ XhcExecTransfer (
UINT8 SlotId;
UINT8 Dci;
BOOLEAN Finished;
- EFI_EVENT TimeoutEvent;
+ UINT64 TimeoutTicks;
+ UINT64 ElapsedTicks;
+ UINT64 TicksDelta;
+ UINT64 CurrentTick;
BOOLEAN IndefiniteTimeout;
Status = EFI_SUCCESS;
Finished = FALSE;
- TimeoutEvent = NULL;
IndefiniteTimeout = FALSE;
if (CmdTransfer) {
@@ -1322,34 +1324,18 @@ XhcExecTransfer (
if (Timeout == 0) {
IndefiniteTimeout = TRUE;
- goto RINGDOORBELL;
- }
-
- Status = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &TimeoutEvent
- );
-
- if (EFI_ERROR (Status)) {
- goto DONE;
- }
-
- Status = gBS->SetTimer (
- TimeoutEvent,
- TimerRelative,
- EFI_TIMER_PERIOD_MILLISECONDS (Timeout)
- );
-
- if (EFI_ERROR (Status)) {
- goto DONE;
}
-RINGDOORBELL:
XhcRingDoorBell (Xhc, SlotId, Dci);
+ TimeoutTicks = XhcConvertTimeToTicks (
+ XHC_MICROSECOND_TO_NANOSECOND (
+ Timeout * XHC_1_MILLISECOND
+ )
+ );
+ ElapsedTicks = 0;
+ CurrentTick = GetPerformanceCounter ();
+
do {
Finished = XhcCheckUrbResult (Xhc, Urb);
if (Finished) {
@@ -1357,22 +1343,22 @@ RINGDOORBELL:
}
gBS->Stall (XHC_1_MICROSECOND);
- } while (IndefiniteTimeout || EFI_ERROR (gBS->CheckEvent (TimeoutEvent)));
+ TicksDelta = XhcGetElapsedTicks (&CurrentTick);
+ // Ensure that ElapsedTicks is always incremented to avoid indefinite hangs
+ if (TicksDelta == 0) {
+ TicksDelta = XhcConvertTimeToTicks (XHC_MICROSECOND_TO_NANOSECOND (XHC_1_MICROSECOND));
+ }
-DONE:
- if (EFI_ERROR (Status)) {
- Urb->Result = EFI_USB_ERR_NOTEXECUTE;
- } else if (!Finished) {
+ ElapsedTicks += TicksDelta;
+ } while (IndefiniteTimeout || ElapsedTicks < TimeoutTicks);
+
+ if (!Finished) {
Urb->Result = EFI_USB_ERR_TIMEOUT;
Status = EFI_TIMEOUT;
} else if (Urb->Result != EFI_USB_NOERROR) {
Status = EFI_DEVICE_ERROR;
}
- if (TimeoutEvent != NULL) {
- gBS->CloseEvent (TimeoutEvent);
- }
-
return Status;
}