That state model isn't as clean as it might be, but so far that hasn't been an issue ... and it was better than what went before, where there was no notion of what sorts of operations made sense. (Queuing urbs to disabled HCDs, for example, never makes sense.)
Is the main point then to keep track of things and prevent bad operations (like queueing URBs to or handling IRQs for disabled controllers)? Come
That's part of what hcd->state is for, yes. But that's just a side-effect of wanting usbcore -- and host-side usb device drivers -- to behave the same regardless of what HCD is used.
right down to it, what operations does the glue layer care about?
Everything that doesn't _need_ to be hardware-specific would ideally move out of the HCDs into usbcore/"glue".
All HCDs need to implement the same life-cycle for USB devices (including root hubs) and for URBs. Achieving that by sharing code is easier than the alternative, regardless of how well the (regression) testing and bugfixing work.
1. Resetting the hardware into a known idle condition
2. Telling the HCD to start/stop the controller
3. Knowing when the controller dies
Those three are part of the root hub life-cycle. Note that we still haven't moved all "restart controller" logic into usbcore; the UHCI code still has its own mechanism (which seems to fire during routine operation), as does OHCI (during certain PM resume scenarios, only).
4. Allowing URBs to be queued
And canceled, completed, shut down ... the whole URB life-cycle. Every HCD has to implement the same model there, and it's easier to do that if they're sharing infrastructure.
5. Allowing IRQs to propagate
This doesn't necessarily need to live in the glue layer, but it does since (a) it allocates the IRQs, so the PCI HCDs share that small bit of code, and (b) for unrecoverable/fatal error IRQs, it gives a simple hook to trigger cleanup: see if the state of the HCD changed.
6. Passing PM suspend/resume messages down to the HCD
Needs more work, once PM behaves well outside of USB. So does the hub driver, to enable remote wakeup.
Have I missed anything? This all looks private to the glue layer (with the exception of 3, which needs a notification from the HCD).
See "struct hc_driver" ... there are more hooks for the root hub (UHCI uses these) and for the usb device lifecycle ... which UHCI doesn't yet use. Two device-level hooks of interest are:
+ usb_device.hcpriv is a struct hcd_dev, which holds among
other things one void* pointer for each endpoint. This could be used for uhci_find_urb_ep(), although the
UHCI notion of endpoint state is much weaker than needed
for OHCI or EHCI. + hc_driver.endpoint_disable is called to scrub out the last
of the endpoint state held by the HCD (hc_dev.ep or whatever).Eventually (2.7, and maybe safe to backport) "hcd_dev" should move into "usb_device" and vanish as a separate thing.
Why not simply decide that the hcd glue layer owns the state? Drivers needn't change it at all; they can let the glue layer know whether transitions succeed by way of return codes. And there could be callbacks, like usb_hc_died(), for drivers to notify the glue layer about spontaneous transitions. (Maybe that's the only one needed.)
That might work. Now that we have reset(), it might actually make sense to change hcd->state to RUNNING before start() ... requiring the HCD to call usb_hc_died() as soon as it fails. At least, so long as no other task could be expecting all RUNNING hosts to be operational ... it's the fault handling that make me hesitate to change such stuff. And the way that the "dead HC" cleanup isn't yet integrated much with khubd.
- Dave
------------------------------------------------------- SF.Net is sponsored by: Speed Start Your Linux Apps Now. Build and deploy apps & Web services for Linux with a free DVD software kit from IBM. Click Now! http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
