On 07.11.2016 23:47, Alan Stern wrote:
On Fri, 4 Nov 2016, Mathias Nyman wrote:
USB-3 does not have any link state that will avoid negotiating a connection
with a plugged-in cable but will signal the host when the cable is
unplugged.
For USB-3 we used to first set the link to Disabled, then to RxDdetect to
be able to detect cable connects or disconnects. But in RxDetect the
connected device is detected again and eventually enabled.
Instead set the link into U3 and disable remote wakeups for the device.
This is what Windows does, and what Alan Stern suggested.
The general idea is okay, but there is one problem. See below.
*/
static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
{
- int ret;
- int total_time;
- u16 portchange, portstatus;
-
- if (!hub_is_superspeed(hub->hdev))
- return -EINVAL;
-
- ret = hub_port_status(hub, port1, &portstatus, &portchange);
- if (ret < 0)
- return ret;
+ struct usb_port *port_dev = hub->ports[port1 - 1];
+ struct usb_device *udev = port_dev->child;
You could pass port_dev as an argument from hub_port_disable() instead
of recomputing it.
true
+ if (udev && udev->port_is_suspended && udev->do_remote_wakeup) {
+ ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U0);
+ if (ret)
+ goto out;
+ msleep(USB_RESUME_TIMEOUT);
+ ret = usb_disable_remote_wakeup(udev);
This won't work. When this routine runs udev->state has already been
set to USB_STATE_NOTATTACHED, and therefore it's impossible to send any
URBs to udev.
You may be able to avoid this problem by changing hub_port_disable().
Have it call usb_set_device_state() after disabling the port instead of
before.
Right, thank you.
I'll do that, or at least do what is needed to disable remote wakeup
before setting the udev->state to USB_STATE_NOTATTACHED
Otherwise this seems reasonable.
Thank you, much appreciated
-Mathas
--
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