On 08.04.2016 13:16, Mathias Nyman wrote:
On 07.04.2016 17:23, Alan Stern wrote:
On Thu, 7 Apr 2016, Mathias Nyman wrote:
In this case there may be alternatives. For example, you could just
delay a few ms until the pending event has been handled. Or, if you
really just want to prevent runtime suspend, you should check to see if
this was a runtime suspend and not a system suspend. Or you could
prevent the bus from being runtime suspended in the first place by
doing a pm_runtime_get_sync().
I just want to prevent runtime suspend.
The pm_message_t msg is lost when hcd_bus_suspend() calls hcd->driver->bus_suspend(hcd).
Maybe it could be added?
It could. You'd just have to update all the existing callback routines
to accept the additional argument.
Or is there some other easy way to figure out if it is runtime suspend?
There isn't. But I still think you might be better off using the
existing runtime PM facilities to prevent runtime suspend at bad times
-- if possible.
The commit message said something about waiting for a newly discovered
hub to be probed. Can you go into more detail?
A USB3 device connected to a runtime suspended host woke up the host, polled the roothub,
found nothing and immediately tried to suspend again.
Logs show:
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: // Setting command ring address to 0xffffe001
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: xhci_resume: starting port polling.
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: xhci_hub_status_data: stopping port polling.
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: xhci_suspend: stopping port polling.
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: Port Status Change Event for port 3
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: resume root hub
..other entries..
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: Port Status Change Event for port 1
Feb 16 20:03:33 xhci_hcd 0000:0e:00.0: resume root hub
So what probably happened here was that connecting the usb device caused a
PCI PME# event to wake up the xhci PCI controller, calling
xhci_pci_resume(), calling
xhci_resume(), calling
usb_hcd_resume_root_hub(both usb2 and usb3 hcds) and
usb_hcd_poll_rh_status(both usb2 and usb3 hcd). polling rh status calls
hcd->driver->hub_status_data() -> xhci_hub_status_data()
xhci_hub_status_data() reads PORTSCs -> no change -> stop polling -> return 0
In core/hub.c hub_probe() autosuspend is set to 0 for roothubs with a long explanation why.
I assume that as xhci_hub_status_data clears the HCD_FLAG_POLL_RH flag and returns 0 (no changes)
we immediately runtime suspend the hub -> runtime suspend host.
To continue, it looks like calling usb_hcd_resume_root_hub() is ends calling autosuspend
usb_hcd_resume_root_hub (hcd)
set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
queue_work(pm_wq, &hcd->wakeup_work); -> hcd_resume_work()
..workqueue async..
hcd_resume_work()
usb_remote_wakeup(hcd->self.root_hub)
status = usb_autoresume_device(udev); // calls pm_runtime_get_sync, returns 0
if (status == 0)
usb_autosuspend_device(udev); // calls pm_runtime_put_sync_autosuspend(&udev->dev)
pm_runtime_get_sync() probably calls xhci_bus_resume() for the roothub,
but apparently that doesn't prevent suspending either.
Maybe I should increase the autosuspend delay for xhci roothubs, or then see if there is
something wrong with xhci_bus_resume()
-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