Re: [RFC v2 2/9] xHCI: Kick khubd when USB3 resume really completes.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 01/26/2012 07:36 AM, Sarah Sharp wrote:
> xHCI roothubs go through slightly different port state machines when
> either a device initiates a remote wakeup and signals resume, or when
> the host initiates a resume.
> 
> According to section 4.19.1.2.13 of the xHCI 1.0 spec, on host-initiated
> resume, the xHC port state machine automatically goes through the U3Exit
> state into the U0 state, setting the port link state change (PLC) bit in
> the process.
> 
> When a device initiates resume, the xHCI port state machine goes into
> the "Resume" state and sets the PLC bit.  Then the xHCI driver writes U0
> into the port link state register to transition the port to U0 from the
> Resume state.
> 
> We can't be sure the device is actually in the U0 state until we receive
> the next port status change event with the PLC bit set.  We really don't
> want khubd to be polling the roothub port status bits until the device
> is really in U0.
> 
> Andiry, this is a pretty unlikely race condition to hit, but do you
> think it should be queued for stable?  khubd could see the device in a
> resuming state, and maybe even start issuing transfers before the device
> fully wakes up.
> 

Sorry for the late reply. Return from a long vacation and drown in mails...

Yes, I think the patch is reasonable and compliant with 4.15.2.1. You
can queue it to stable.

Thanks,
Andiry

> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> Cc: Andiry Xu <andiry.xu@xxxxxxx>
> ---
>  drivers/usb/host/xhci-ring.c |   29 +++++++++++++++++------------
>  1 files changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 5a818cb..67149bb 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -1321,20 +1321,16 @@ static void handle_port_status(struct xhci_hcd *xhci,
>  		}
>  
>  		if (DEV_SUPERSPEED(temp)) {
> -			xhci_dbg(xhci, "resume SS port %d\n", port_id);
> +			xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
> +			xhci_test_and_clear_bit(xhci, port_array,
> +					faked_port_index, PORT_PLC);
>  			xhci_set_link_state(xhci, port_array, faked_port_index,
>  						XDEV_U0);
> -			slot_id = xhci_find_slot_id_by_port(hcd, xhci,
> -					faked_port_index + 1);
> -			if (!slot_id) {
> -				xhci_dbg(xhci, "slot_id is zero\n");
> -				goto cleanup;
> -			}
> -			xhci_ring_device(xhci, slot_id);
> -			xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
> -			/* Clear PORT_PLC */
> -			xhci_test_and_clear_bit(xhci, port_array,
> -						faked_port_index, PORT_PLC);
> +			/* Need to wait until the next link state change
> +			 * indicates the device is actually in U0.
> +			 */
> +			bogus_port_status = true;
> +			goto cleanup;
>  		} else {
>  			xhci_dbg(xhci, "resume HS port %d\n", port_id);
>  			bus_state->resume_done[faked_port_index] = jiffies +
> @@ -1345,6 +1341,15 @@ static void handle_port_status(struct xhci_hcd *xhci,
>  		}
>  	}
>  
> +	if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
> +			DEV_SUPERSPEED(temp)) {
> +		xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
> +		slot_id = xhci_find_slot_id_by_port(hcd, xhci,
> +				faked_port_index + 1);
> +		if (slot_id && xhci->devs[slot_id])
> +			xhci_ring_device(xhci, slot_id);
> +	}
> +
>  	if (hcd->speed != HCD_USB3)
>  		xhci_test_and_clear_bit(xhci, port_array, faked_port_index,
>  					PORT_PLC);


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux