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

Reply via email to