Okay. I don't have answers to everything, but I will try to make the questions as explicit as possible.
Regarding device resets and error handling: As discussed earlier, we need a way for a driver to inform the core that a device's descriptors have changed (following a firmware download, for example). Let's call this new function usb_device_altered(). It will queue a request to be handled in another thread (necessary to prevent deadlock). When the request is carried out, it will first do the equivalent of setting config 0: remove the existing interfaces and unbind the drivers. I'm undecided about whether it should actually send this command to the device; that will most likely be unnecessary. It will then release the host-side configuration records and proceed as though this was a new device just entering the ADDRESS state. It will re-read the device and configuration descriptors from the device, select a configuration, and create the sysfs interface devices. BTW, we will also have to add a DEVICE_ALTERED ioctl to usbfs. Oliver is concerned about what will happen following a failed device reset or if the device driver doesn't call usb_device_altered(): > To a certain extend we need to deal with it. It's core's business if it > happens with adr 0 state. And we need to deal with it if the driver gives up. > Which means that the core gets the hard irrecoverable errors ;-) > And we need a means for the drivers to tell the core about such cases. Some of the failures of usb_device_reset() are straightforward. If we can't tell the port to reset the hub, then we just return an error code. If the reset succeeds but there is no device connected afterwards, we can just return an error code because khubd will learn about the disconnection all by itself in due course. If the device is still connected but we can't set its address, we can disable the port and return an error code. (If disabling the port fails we must power-down the port, and if that fails we must reset the hub. This could get tricky... but it's the same processing that must happen for every new connection.) If we can set the address back to what it was but can't select the original configuration or the original interface settings, things get more interesting. My feeling is that we should return an error code and proceed with the possibly-incorrect kernel data structures still in place. The device driver, if it is working properly, will shortly call usb_device_altered() and thereby fix everything up. We really don't have much choice about this. Oliver pointed out earlier that involved maneuvers like firmware downloads may involve several sequential steps, and the device may not have any well-defined state in the intermediate portions. If the core tried to interfere in any way, this sort of reconfiguration would be impossible for a driver to carry out. All right then, but what if through an error or bad writing the driver doesn't call usb_device_altered()? Depending on how large the change was, the device may now work only partially, or even not at all. But that's exactly what happens anyway when a driver does something wrong or contains a bug! In this situation the problem clearly lies in the driver, so the driver would need to be fixed, not the core. In the meantime, the kernel will struggle along with incorrect host-side configuration records. That's not so terrible, and if need be the user can always unplug the device and then re-attach it. The one truly bizarre scenario I can think of involves the user unplugging the device and plugging in a different one, all in under 1/4 second so that khubd doesn't have time to notice it. The driver for the old device will quickly realize something is wrong and will attempt various fixes, leading up to a device reset. The reset will succeed and will give the new device the old device's address. It might even set the old device's configuration value! For a short while things might seem to work, or they might not -- but eventually khubd will get the message and reset the port again. The driver will be unbound, the old device struct will go away, and things will start up fresh. So even this unlikely set of events is not very bad. On a different tack... The operation of setting a new configuration will need to be handled by a separate thread (separate from the calling device driver, I mean), just like usb_device_altered(). Fitting a proper API for this may require some effort; I notice that several drivers already call usb_set_configuration() synchronously. Some set the config to its already-existing value, others blindly set it to 1. This will have to be examined closely and in some cases changed. Trying to set a new value synchronously will almost certainly result in deadlock. Even trying to reset the current value, which normally should be innocuous, might cause deadlock if the call failed. Concerning parallelization of the operations involved in connect/reset/disconnect processing, David writes: > I suspect a per-hub "struct work_struct" would suffice, > though it's TBD exactly what work would be done there. Note that there operations require a separate thread or work-queue equivalent, because they have to take place in process context. I can think of several other possible arrangements: (A) One work-queue entry per request, created on demand. This would involve creating lots of little kernel processes and would make it difficult to handle requests in the correct order. (B) One persistent kernel thread per bus. This could result in a large number of largely dormant threads. On the plus side, this is a natural level for handling address-0 serialization. (C) One single kernel thread to do everything -- i.e., khubd. That's what we've got now. I don't know what's best; maybe something not listed here. Also, bear in mind that the work being discussed doesn't crop up too often. Parallelization is not needed for performance reasons, only for reliability. Alan Stern ------------------------------------------------------- This SF.net email is sponsored by: eBay Get office equipment for less on eBay! http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5 _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel