On 29.04.2016 22:25, Alan Stern wrote:
When a USB driver is bound to an interface (either through probing or by claiming it) or is unbound from an interface, the USB core always disables Link Power Management during the transition and then re-enables it afterward. The reason is because the driver might want to prevent hub-initiated link power transitions, in which case the HCD would have to recalculate the various LPM parameters. This recalculation takes place when LPM is re-enabled and the new parameters are sent to the device and its parent hub. However, if the driver does not want to prevent hub-initiated link power transitions then none of this work is necessary. The parameters don't need to be recalculated, and LPM doesn't need to be disabled and re-enabled. It turns out that disabling and enabling LPM can be time-consuming, enough so that it interferes with user programs that want to claim and release interfaces rapidly via usbfs. Since the usbfs kernel driver doesn't set the disable_hub_initiated_lpm flag, we can speed things up and get the user programs to work by leaving LPM alone whenever the flag isn't set. And while we're improving the way disable_hub_initiated_lpm gets used, let's also fix its kerneldoc. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Tested-by: Matthew Giassa <matthew@xxxxxxxxxx> CC: Mathias Nyman <mathias.nyman@xxxxxxxxx> CC: <stable@xxxxxxxxxxxxxxx> --- Mathias, can you check that this is right? If the driver's disable_hub_initiated_lpm flag isn't set then binding or unbinding it shouldn't require any changes to the LPM parameters. The flag gets used in only one place, in xhci_calculate_lpm_timeout(), and if it isn't set then then result would be the same as if the driver weren't bound. Thanks.
It looks like xhci driver calculates the u1 and u2 timeout values for ports based on udev->u1_params.sel * x (where x depends on endpoint type). It loops through all active interfaces all endpoints, and picks the worst (longest) timeout as the timeout value. In this sense if a interface drive disappears or appears it could be possible that the timeout values change, even if the xhci_calculate_lpm_timeout() is not set. usb_enable_lpm() usb_enable_link_state() hcd->driver->enable_usb3_lpm_timeout(hcd, udev, state) xhci_calculate_lpm_timeout() for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) xhci_update_timeout_for_interface(... &timeout)) for (j = 0; j < alt->desc.bNumEndpoints; j++) xhci_update_timeout_for_endpoint(&timeout) // saves longest timeout xhci_call_host_update_timeout_for_endpoint(&timeout) ..xhci_calculate_intel_u1_timeout() // skipped a few steps case USB_ENDPOINT_XFER_CONTROL: timeout = udev->u1_params.sel * 3; case USB_ENDPOINT_XFER_BULK: timeout = udev->u1_params.sel * 5; case USB_ENDPOINT_XFER_INT: timeout = ... -Mathias -- 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