summaryrefslogtreecommitdiff
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorAlok Kulkarni <18198210+akulkar4@users.noreply.github.com>2022-03-01 12:37:38 -0800
committerLiming Gao <gaoliming@byosoft.com.cn>2025-07-10 09:06:35 +0800
commita00ad45ea45203052491fe2b25c9393a59c75c53 (patch)
tree1e03a415ff5c0f2f0715ef9b1c94a8f146a734fc /MdeModulePkg
parent7c2e2d4f1a6fec4caeadc8295f1a7a21364e07ec (diff)
downloadedk2-a00ad45ea45203052491fe2b25c9393a59c75c53.zip
edk2-a00ad45ea45203052491fe2b25c9393a59c75c53.tar.gz
edk2-a00ad45ea45203052491fe2b25c9393a59c75c53.tar.bz2
MdeModulePkg: UsbBusDxe Reset USB port GetPortStatus returns device error.
During USB device enumeration, issuing a hot reset on a port is skipped if there is a reset change status already detected on the port. This can happen when enumerating devices after a host controller soft reset (which drives a hot reset down the ports). However, in certain cases an attached device may not be responsive even if the reset change and connection status bits are set. For e.g., according to xHCI spec section 4.19.5.1 the port reset change bits can be set when a hot reset driven on the port transitions to a warm reset and completes with errors. For such instances it is worthwhile to force a hot reset during enumeration to try and recover unresponsive devices. During enumeration check whether querying port status returns EFI_DEVICE_ERROR and try a port reset if there is a device attached to the port. Signed-off-by: Aaron Pop <aaronpop@microsoft.com>
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
index b3a4063..713415d 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
@@ -900,12 +900,17 @@ UsbEnumeratePort (
Child = NULL;
HubApi = HubIf->HubApi;
+ // Zero out PortState in case GetPortStatus does not set
+ // it and we continue on the EFI_DEVICE_ERROR path
+ PortState.PortStatus = 0;
+ PortState.PortChangeStatus = 0;
+
//
// Host learns of the new device by polling the hub for port changes.
//
Status = HubApi->GetPortStatus (HubIf, Port, &PortState);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) && (Status != EFI_DEVICE_ERROR)) {
DEBUG ((DEBUG_ERROR, "UsbEnumeratePort: failed to get state of port %d\n", Port));
return Status;
}
@@ -987,7 +992,9 @@ UsbEnumeratePort (
// Now, new device connected, enumerate and configure the device
//
DEBUG ((DEBUG_INFO, "UsbEnumeratePort: new device connected at port %d\n", Port));
- if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
+ if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET) &&
+ (Status != EFI_DEVICE_ERROR))
+ {
Status = UsbEnumerateNewDev (HubIf, Port, FALSE);
} else {
Status = UsbEnumerateNewDev (HubIf, Port, TRUE);