On Thu, Feb 6, 2014 at 1:05 PM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > On Fri, 31 Jan 2014, Dan Williams wrote: > >> ClearPortFeature(PORT_POWER) on a usb3 port places the port in either a >> DSPORT.Powered-off-detect / DSPORT.Powered-off-reset loop, or the >> DSPORT.Powered-off state. There is no way to ensure that RX >> terminations will persist in this state, so it is possible a device will >> degrade to its usb2 connection. Prevent this by blocking power-off of a >> usb3 port while its usb2 peer is active, and powering on a usb3 port >> before its usb2 peer. > >> --- a/drivers/usb/core/port.c >> +++ b/drivers/usb/core/port.c >> @@ -77,12 +77,19 @@ static int usb_port_runtime_resume(struct device *dev) >> struct usb_device *hdev = to_usb_device(dev->parent->parent); >> struct usb_interface *intf = to_usb_interface(dev->parent); >> struct usb_hub *hub = usb_hub_to_struct_hub(hdev); >> + struct usb_port *peer = port_dev->peer; >> int port1 = port_dev->portnum; >> int retval; >> >> if (!hub) >> return -EINVAL; >> >> + /* power on our usb3 peer before this usb2 port to prevent a usb3 >> + * device from degrading to its usb2 connection >> + */ >> + if (!hub_is_superspeed(hdev) && peer) >> + pm_runtime_get_sync(&peer->dev); >> + > > Have you considered what would happen if this runs before the ACPI data > causes the peers to be re-matched? If userspace is sets pm_qos_no_poweroff to 0 before we have figured out the peer then suspending this port may lead to a disconnect. However, since we know that a usb3 port must have a peer we can take a reference that is not dropped until the usb2 port suspends for this first time. That change lines up nicely with your comments below. Nice cleanup, thank you. -- 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