Skip to content

Commit 79989bd

Browse files
matnymangregkh
authored andcommitted
xhci: always resume roothubs if xHC was reset during resume
Usb device connect may not be detected after runtime resume if xHC is reset during resume. In runtime resume cases xhci_resume() will only resume roothubs if there are pending port events. If the xHC host is reset during runtime resume due to a Save/Restore Error (SRE) then these pending port events won't be detected as PORTSC change bits are not immediately set by host after reset. Unconditionally resume roothubs if xHC is reset during resume to ensure device connections are detected. Also return early with error code if starting xHC fails after reset. Issue was debugged and a similar solution suggested by Remi Pommarel. Using this instead as it simplifies future refactoring. Reported-by: Remi Pommarel <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218987 Suggested-by: Remi Pommarel <[email protected]> Tested-by: Remi Pommarel <[email protected]> Cc: [email protected] Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 35c41b9 commit 79989bd

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

drivers/usb/host/xhci.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,10 +1125,20 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
11251125
xhci_dbg(xhci, "Start the secondary HCD\n");
11261126
retval = xhci_run(xhci->shared_hcd);
11271127
}
1128-
1128+
if (retval)
1129+
return retval;
1130+
/*
1131+
* Resume roothubs unconditionally as PORTSC change bits are not
1132+
* immediately visible after xHC reset
1133+
*/
11291134
hcd->state = HC_STATE_SUSPENDED;
1130-
if (xhci->shared_hcd)
1135+
1136+
if (xhci->shared_hcd) {
11311137
xhci->shared_hcd->state = HC_STATE_SUSPENDED;
1138+
usb_hcd_resume_root_hub(xhci->shared_hcd);
1139+
}
1140+
usb_hcd_resume_root_hub(hcd);
1141+
11321142
goto done;
11331143
}
11341144

@@ -1152,7 +1162,6 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
11521162

11531163
xhci_dbc_resume(xhci);
11541164

1155-
done:
11561165
if (retval == 0) {
11571166
/*
11581167
* Resume roothubs only if there are pending events.
@@ -1178,6 +1187,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
11781187
usb_hcd_resume_root_hub(hcd);
11791188
}
11801189
}
1190+
done:
11811191
/*
11821192
* If system is subject to the Quirk, Compliance Mode Timer needs to
11831193
* be re-initialized Always after a system resume. Ports are subject

0 commit comments

Comments
 (0)