Re: [RFC] xhci: clear port_remote_wakeup on device disconnection

From: Oliver Neukum
Date: Tue Mar 19 2019 - 07:13:13 EST


On Mo, 2019-03-18 at 18:00 +0100, Nicolas Saenz Julienne wrote:
>
> This patch clears "port_remote_wakeup" upon detecting a device
> disconnection. Making sure the above mentioned situation doesn't trigger
> a PM busyloop.

Hi,

that is an interesting race condition.

>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@xxxxxxx>
> ---
> drivers/usb/host/xhci-hub.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
> index e2eece693655..bea853f45aec 100644
> --- a/drivers/usb/host/xhci-hub.c
> +++ b/drivers/usb/host/xhci-hub.c
> @@ -942,6 +942,9 @@ static void xhci_get_usb3_port_status(struct xhci_port *port, u32 *status,
> bus_state->suspended_ports &= ~(1 << portnum);
> }
>
> + if (!(portsc & PORT_CONNECT))
> + bus_state->port_remote_wakeup &= ~(1 << portnum);
> +
> xhci_hub_report_usb3_link_state(xhci, status, portsc);
> xhci_del_comp_mod_timer(xhci, portsc, portnum);
> }

Why are you putting that logic into xhci_get_usb3_port_status()?
It looks to me like there is already something related in the caller

/* USB2 and USB3 specific bits, including Port Link State */
if (hcd->speed >= HCD_USB3)
xhci_get_usb3_port_status(port, &status, raw_port_status);
else
xhci_get_usb2_port_status(port, &status, raw_port_status,
flags);
/*
* Clear stale usb2 resume signalling variables in case port changed
* state during resume signalling. For example on error
*/
if ((bus_state->resume_done[wIndex] ||
test_bit(wIndex, &bus_state->resuming_ports)) &&
(raw_port_status & PORT_PLS_MASK) != XDEV_U3 &&
(raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) {
bus_state->resume_done[wIndex] = 0;
clear_bit(wIndex, &bus_state->resuming_ports);
usb_hcd_end_port_resume(&hcd->self, wIndex);
}

Otherwise very good catch!

Regards
Oliver