From c3d5d800d775095e0bbd0ac8862df234cdd4332d Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Fri, 31 Aug 2018 15:26:30 +0200 Subject: [PATCH] MdeModulePkg/EhciDxe: fix host controller reset condition in BindingStart Commit 09943f5ecc0f ("MdeModulePkg: Skip to manage usb debug port in EDKII EHCI driver if it's used by usb debug port driver", 2012-04-28) made the host controller reset in EhcDriverBindingStart() conditional. The intent was to avoid the reset when - one of the USB ports on the host controller was a Debug Port, AND - the Debug Port was in use. This translates to the following positive condition: reset the controller only if: - no USB port on the host controller is a Debug Port, OR - the Debug Port is not in use. Commit 09943f5ecc0f failed to implement the first subcondition, and thus the result is too strict now (for resetting the host controller). Relax it to the correct condition. This issue was found by Steven Shi on QEMU. QEMU's EHCI device model does not have a Debug Port. In repeated disconnect / connect cycles, the controller is never reset in EhcDriverBindingStart(), therefore the devices on the controller are never re-enumerated after a disconnect. Cc: Gerd Hoffmann Cc: Jian J Wang Cc: Ruiyu Ni Cc: Star Zeng Cc: Steven Shi Reported-by: Steven Shi Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1129 Fixes: 09943f5ecc0fbc0c98c511c82703a0ba3b2b5819 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek Reviewed-by: Star Zeng Tested-by: Steven Shi --- MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c index 30ad2b2ffe..89ed034b90 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c @@ -1918,7 +1918,9 @@ EhcDriverBindingStart ( EhcClearLegacySupport (Ehc); } - if (Ehc->DebugPortNum != 0) { + if (Ehc->DebugPortNum == 0) { + EhcResetHC (Ehc, EHC_RESET_TIMEOUT); + } else { State = EhcReadDbgRegister(Ehc, 0); if ((State & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) != (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) { EhcResetHC (Ehc, EHC_RESET_TIMEOUT);