Dave and Olav:

It's easy to see that different HCDs handle suspend/resume with some 
important differences.  IMHO we should try to make these things work as 
uniformly as possible.  Here's a brief description of how uhci-hcd now 
works; do you guys think it would be worthwhile changing the other drivers 
to match?  (For the isp116x, read "platform device" for "PCI device" 
below.)


        There's no recursion.  When the PCI device is suspended or
        resumed, the code does _not_ suspend or resume the root hub
        device.

This is in keeping with my attitude that the USB subsystem shouldn't do 
much (or any!) recursion for suspend/resume.  During a system sleep/wakeup 
transition it's not necessary, as the PM core will do it for us.  For 
runtime power management the recursion can be left up to userspace tools.  
(This leaves unanswered the question of how to handle a situation where 
one user program is trying to suspend a parent device while at the same 
time another program is trying to resume a child device.  Let's not worry 
about that for now.)


        There's an exception made if CONFIG_USB_SUSPEND isn't set.
        In that case the PCI device's suspend/resume routines do
        automatically call the internal subroutines for suspending/
        resuming the root hub -- otherwise the root hub would never
        change state!

Note that they don't call usb_suspend_device or usb_resume_device, since
those routines don't do anything when CONFIG_USB_SUSPEND isn't set.


        On the other hand, the code does do a minimal amount of
        checking.  The PCI device's suspend routine checks that the
        root hub is already suspended, and the root hub's resume
        routine checks that the PCI device is already resumed.  If
        the checks fail an error is returned.

Note that these checks don't actually involve dereferencing 
hcd->self.root_hub.  The driver keeps track internally of the state of 
the root hub.  Thus there's no danger should the code run at a time 
when the root hub hasn't been registered (although in fact that can't 
happen).


        Auto-suspend (called AUTO_STOP in uhci-hcd) is handled
        separately from the normal suspend pathway.  In particular,
        it doesn't involve calling usb_suspend_device for the root
        hub.  Likewise, resuming from AUTO_STOP doesn't involve
        calling usb_resume_device.  Only internal routines are
        involved.

This is partly so that auto-suspend can work even when CONFIG_USB_SUSPEND
is off.  But more importantly, it reflects a separation of
responsibilities between the hub driver and the HCD.  As far as usbcore is
concerned, the root hub is (like every other hub) totally under the
control of the hub driver.  It shouldn't be suspended or resumed on the
whim of the HCD, which is only supposed to manage the hardware.

When the hub driver gets auto-suspend capability added, the HCD won't need 
it.  Until then, an HCD-initiated auto-suspend is completely internal to 
the driver -- usbcore is unaware that anything has happened.


        An HCD should be largely unaware of the existence of
        hcd->self.root_hub.  When the HCD needs to do something
        that affects the root hub, a facility should be provided
        by usbcore.  In short, the HCD should never need to
        dereference hcd->self.root_hub.

The facilities currently available for use by HCDs include usb_hc_died,
usb_hcd_resume_root_hub, and usb_hcd_poll_rh_status.  Normally usbcore
will call usb_hc_died on behalf of the HCD, so the driver doesn't need to
do so by hand.  The usb_hcd_poll_rh_status routine is quite new, and
drivers should convert to use IRQs rather than polling for port changes.

>From looking through the code, I see that we need another facility added:
usb_hcd_root_hub_lost_power.  This would take over the duty of marking all
the children devices as NOTATTACHED and simulating connect-change events
on their ports, something which clearly belongs in usbcore and not in
HCDs.


I think that covers pretty much everything.  If I left something out, 
please let me know.

Olav, I noticed a couple of things in isp116c-hcd.c that could be changed.  
In the IRQ routine you have a comment asking what to do when an 
unrecoverable error occurs.  The answer is to set hcd->state to 
HC_STATE_HALT and take whatever other actions are needed to quiesce the 
controller.  Then usbcore will automatically call usb_hc_died for you.  
See uhci_irq() and hc_died() in uhci-hcd.c for an example.

Also, your isp116x_rh_resume routine isn't needed.  When the root hub is
suspended (and usbcore knows that it's suspended!) and a resume request
comes in, all you need to do is call usb_hcd_resume_root_hub.  (You can
call it in interrupt context.)  Then khubd will take care of resuming the
root hub for you, and you don't have to worry about races between the
workqueue thread running and the root hub being unregistered.

Alan Stern



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to