diff options
author | Alok Kulkarni <18198210+akulkar4@users.noreply.github.com> | 2022-03-01 12:37:38 -0800 |
---|---|---|
committer | Liming Gao <gaoliming@byosoft.com.cn> | 2025-07-10 09:06:35 +0800 |
commit | a00ad45ea45203052491fe2b25c9393a59c75c53 (patch) | |
tree | 1e03a415ff5c0f2f0715ef9b1c94a8f146a734fc /MdeModulePkg | |
parent | 7c2e2d4f1a6fec4caeadc8295f1a7a21364e07ec (diff) | |
download | edk2-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.c | 11 |
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);
|