On Saturday 18 September 2004 8:50 am, Alan Stern wrote:
> 
> Actually, I'm trying to generalize along a different dimension: How to
> handle root hubs.

Yes, that's still a bit too special-casey for my taste, and right
at an API boundary (the worst place for special cases).


> With other USB devices, a logical disconnect is 
> implemented by setting change_bits in the device's parent hub.  Resets are
> implemented by telling the parent hub to reinitialize the appropriate
> port. 

And root hubs have no such port.

> Suspend and resume are implemented by telling the parent hub to 
> suspend/resume the port.

That's the _implementation_ of a suspend() or resume() method
for some device that's not a root hub.

> Evidently none of those mechanisms can be used 
> with root hubs.

Not in detail, no.   All usb devices have suspend() and resume()
methods, implemented differently through the driver model.
There's no reset() method in the driver model, though the HCD
glue layer has one for initialization.


> So we need both a way for khubd to carry these things out, and a way to 
> _tell_ khubd to do them.  

Right now there's no restriction that khubd do those things;
they're implemented by whatever task starts the work.

> Two separate problems, but they both fall under  
> the same special case.  The idea of reusing nerrors for notifications is 
> a solution to the second problem -- how to tell khubd that something 
> needs to be done.

I find myself thinking about a hardware register with bitfields like:

   nerrors - 8 bits, number of consecutive errors
   resume - 1 bit, task is to resume hub
   shutdown - 1 bit, task is to shutdown hub
   reset - 1 bit, task is to reset the hub
   hub changed - 1 bit, from hub status urb, task is ..
   port changed - N bits, from hub status urb, task is ..

Overloading nerrors seems error prone, they'd be better off
as distinct flags.


> Yeah.  After some more thought, it seems likely that whatever caused the
> HC to die either wouldn't need such a thorough reset or wouldn't be helped
> by it.  With UHCI, for example, the HC will shut itself down if it
> encounters invalid data in the schedule (result of a driver bug; the only
> way to fix it is to remove the bug) or PCI troubles (probably transient;
> if not then reinitialization won't help).

I look at this statistically.  Linux USB is pretty stable for most
purposes, and won't hit these problems.  Adding some kind
of "reactivate after fatal error" recovery might be a win when
the error is from some semi-random alignment of factors that
doesn't reproduce easily ... and memory wasn't corrupted,
which we can't actually know.

But when it's reproducible, due to hardware issues or maybe
a bug in some device drive affecting usbcore/hcd, or if the
memory gets corrupted ... reactivation may not be a win.
In similar situations, I've often seen mechanisms to prevent
restarts "too soon" (configurable) after the last one.


> > ... call bus_rescan_devices().  Either way,
> > the bus rescan might not give the device back to usbcore/khubd.
> 
> Not the way I was proposing.  The driver core and PCI core wouldn't know
> anything had happened and no rescanning would be needed, since the
> remove() and probe() routines would be called directly. 

I see ... I misread what you wrote, which was to call pci_driver.remove()
and probe() directly.  That would work, yes -- but as you said, it would
not work as well for non-PCI controllers.


> > > P.S.: While we're on the subject of root hubs...  What is
> > > an HCD supposed  
> > > to do when the root hub is suspended and a remote wakeup IRQ arrives?  
> > > Maybe this calls for another sentinel value in hub->nerrors.
> > 
> > The root hub should just wake up; how else can it handle the IRQ?
> > If it were in a PM mode where the state couldn't change, it wouldn't
> > have enabled wakeup before it went to sleep.
> 
> You missed my point.  The root hub _can't_ "just wake up"; someone has to
> call usb_resume_device(), and that can't be done in_interrupt.  

Like this bit from OHCI:

        if (ints & OHCI_INTR_RD) {
                ohci_vdbg (ohci, "resume detect\n");
                schedule_work(&ohci->rh_resume);
        }

There are lots of integration issues in this area still, but I think all HC
hardware handles that sort of state ... maybe it'd be useful to call
that a "bus suspend".  It's not a PCI suspend; since that's a PCI IRQ.
And clearly it's not a "global suspend" even in the context of a
signle HC, since the controller registers are still in use.
 

> The 
> logical choice for that someone is again khubd -- so how does the HCD (or
> the hcd glue layer) tell khubd that the root hub needs to be resumed?

In the current tree, khubd is never involved in resume processing.

That'll always be some task involved in suspend/resume, either
system-wide (writing /sys/power/state or /proc/acpi/sleep) or else
device-specific (writing /sys/devices/.../power/state).

However, you do have that patch of mine that makes reactivate()
call kick_hubd() ... that'll tell khubd something's up, but only after
the other task did its own part of the resume sequence.

- Dave
 

> Alan Stern
> 
> 


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to