On Mon, Jun 12, 2006 at 03:17:35PM -0400, Alan Stern wrote:
> Greg:
> 
> This patch (as714) makes the USB device (as opposed to interface) driver
> usb_generic be treated just like all other drivers, subject to matching,
> probing, and unbinding.  For instance, some of the normal boilerplate
> stuff that goes along with discovery of a new USB device (registration in
> usbfs, creation of the sysfs attribute files, and selection of an initial
> configuration) is moved into the probe routine, where any normal driver 
> would put it.
> 
> This change isn't particularly important for now -- other than in an
> organizational sense -- but it opens the door to having alternate USB
> device drivers.  The examples that spring to mind are when a host exports
> a USB device over the network or to a virtual guest operating system.  In
> each case, the device shouldn't show up as a normal USB device on the host
> but rather on the client/guest.  This could be accomplished by binding the
> host's device to a different driver.  If this was done for a root hub, an
> entire USB device tree could automatically be exported!

Nice idea.  I'm trying to remember why I didn't do this all those years
ago and can't recall why.  Thanks for fixing this up.

One comment thought:

> @@ -516,14 +756,14 @@ static int usb_uevent(struct device *dev
>       /* driver is often null here; dev_dbg() would oops */
>       pr_debug ("usb %s: uevent\n", dev->bus_id);
>  
> -     /* Must check driver_data here, as on remove driver is always NULL */
> -     if ((dev->driver == &usb_generic_driver) || 
> -         (dev->driver_data == &usb_generic_driver_data))
> -             return 0;
> -
> -     intf = to_usb_interface(dev);
> -     usb_dev = interface_to_usbdev (intf);
> -     alt = intf->cur_altsetting;
> +     if (is_usb_device(dev)) {
> +             usb_dev = to_usb_device(dev);
> +             alt = NULL;
> +     } else {
> +             intf = to_usb_interface(dev);
> +             usb_dev = interface_to_usbdev (intf);
> +             alt = intf->cur_altsetting;
> +     }
>  
>       if (usb_dev->devnum < 0) {
>               pr_debug ("usb %s: already deleted?\n", dev->bus_id);
> @@ -566,15 +806,22 @@ static int usb_uevent(struct device *dev
>                          usb_dev->descriptor.bDeviceProtocol))
>               return -ENOMEM;
>  
> -     if (add_uevent_var(envp, num_envp, &i,
> +     if (is_usb_device(dev)) {
> +
> +             /* FIXME: What is an appropriate MODALIAS line for a
> +              * USB device (not interface)? */

There isn't one.

In fact, you shouldn't be adding _any_ usb stuff for uevents for usb
devices, we only care about interfaces.  Why did you change this?

> Index: usb-2.6/drivers/usb/core/usb.h
> ===================================================================
> --- usb-2.6.orig/drivers/usb/core/usb.h
> +++ usb-2.6/drivers/usb/core/usb.h
> @@ -31,8 +31,16 @@ extern int usb_suspend_device(struct usb
>  extern int usb_resume_device(struct usb_device *dev);
>  
>  extern struct bus_type usb_bus_type;
> -extern struct device_driver usb_generic_driver;
> -extern int usb_generic_driver_data;
> +extern struct usb_driver usb_generic_driver;
> +
> +/* Here's how we tell apart devices and interfaces.  Luckily there's
> + * no such thing as a platform USB device, so we can steal the use
> + * of the platform field. */
> +
> +static inline int is_usb_device(struct device *dev)
> +{
> +     return dev->platform_data == &usb_generic_driver;
> +}

Ah, nice hack, I like it :)

> --- usb-2.6.orig/include/linux/usb.h
> +++ usb-2.6/include/linux/usb.h
> @@ -581,6 +581,8 @@ extern ssize_t usb_store_new_id(struct u
>   * @driver: the driver model core driver structure.
>   * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
>   *   added to this driver by preventing the sysfs file from being created.
> + * @for_devices: indicates that the driver manages USB devices and not
> + *   USB interfaces (very uncommon).
>   *
>   * USB drivers must provide a name, probe() and disconnect() methods,
>   * and an id_table.  Other driver fields are optional.
> @@ -619,6 +621,8 @@ struct usb_driver {
>       struct usb_dynids dynids;
>       struct device_driver driver;
>       unsigned int no_dynamic_id:1;
> +
> +     unsigned int for_devices:1;

Nice, this is why I didn't do this before, I didn't think of doing it
this way.  It makes more sense now.

thanks,

greg k-h


_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to