Hi,

this version, though probably horribly broken, should have all features
I intended it to have. So could you have a look at this ?
Especially the reevaluation of the device. I am not all that clear about
the generic driver stuff in it.
I am too tired to do coding any further tonight.

        Regards
                Oliver

You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


[EMAIL PROTECTED], 2002-10-11 01:08:08+02:00, [EMAIL PROTECTED]
  - conf changes




diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c    Fri Oct 11 01:08:39 2002
+++ b/drivers/usb/core/hub.c    Fri Oct 11 01:08:39 2002
@@ -1236,7 +1236,7 @@
                return 1;
        }
 
-       ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
+       ret = do_set_conf(dev, dev->actconfig->bConfigurationValue);
        if (ret < 0) {
                err("failed to set dev %s active configuration (error=%d)",
                        dev->devpath, ret);
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c        Fri Oct 11 01:08:39 2002
+++ b/drivers/usb/core/message.c        Fri Oct 11 01:08:39 2002
@@ -838,6 +838,43 @@
 }
 
 /**
+ * do_set_conf - send the actual message changing configuration
+ * @dev: the device whose configuration is being updated
+ * @configuration: the configuration being chosen.
+ * Context: !in_interrupt ()
+ */
+int do_set_conf(struct usb_device *dev, int configuration)
+{
+       int r,i;
+       struct usb_config_descriptor *cp;
+printk("Setting configuration.\n");
+               for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
+               if (dev->config[i].bConfigurationValue == configuration) {
+                       cp = &dev->config[i];
+                       goto found;
+               }
+       }
+
+       return -EINVAL;
+
+found:
+
+       r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+                               USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+                               NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+       if (r)
+               return r;
+
+       dev->actconfig = cp;
+       dev->toggle[0] = 0;
+       dev->toggle[1] = 0;
+       usb_set_maxpacket(dev);
+
+       return 0;
+
+}
+
+/**
  * usb_set_configuration - Makes a particular device setting be current
  * @dev: the device whose configuration is being updated
  * @configuration: the configuration being chosen.
@@ -871,7 +908,7 @@
 {
        int i, ret;
        struct usb_config_descriptor *cp = NULL;
-       
+
        for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
                if (dev->config[i].bConfigurationValue == configuration) {
                        cp = &dev->config[i];
@@ -883,17 +920,29 @@
                return -EINVAL;
        }
 
-       if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                       USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
-                       NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0)
-               return ret;
+       down(&dev->serialize);
 
-       dev->actconfig = cp;
-       dev->toggle[0] = 0;
-       dev->toggle[1] = 0;
-       usb_set_maxpacket(dev);
+       for (i = 0; i < USB_MAXCHILDREN; i++) {
+               struct usb_device **child = dev->children + i;
+               if (*child) {
+                       ret = -EBUSY;
+                       goto err; /* refuse if children were harmed */
+               }
+       }
+printk("Got lock in usb_set_configuration.\n");
 
-       return 0;
+       usb_reap_interfaces(dev); /* get rid of all interfaces */
+
+       if ((ret = do_set_conf(dev, configuration)))
+               goto err;
+
+       dev->desired_conf = configuration; /* for pm */
+
+       ret = do_logical_register_dev(dev); /* reevaluate device */
+
+err:
+       up(&dev->serialize);
+       return ret;
 }
 
 
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c    Fri Oct 11 01:08:39 2002
+++ b/drivers/usb/core/usb.c    Fri Oct 11 01:08:39 2002
@@ -75,6 +75,7 @@
 {
        struct usb_interface * intf = to_usb_interface(dev);
        struct usb_driver * driver = to_usb_driver(dev->driver);
+       struct usb_device * udev =  interface_to_usbdev(intf);
        const struct usb_device_id *id;
        int error = -ENODEV;
        int m;
@@ -94,7 +95,11 @@
        if (id) {
                dbg ("%s - got id", __FUNCTION__);
                down (&driver->serialize);
+printk("Got driver lock.\n");
+               down (&udev->serialize);
+printk("Got device lock.\n");
                error = driver->probe (intf, id);
+               up (&udev->serialize);
                up (&driver->serialize);
        }
        if (!error)
@@ -110,10 +115,12 @@
 {
        struct usb_interface *intf;
        struct usb_driver *driver;
+       struct usb_device *udev;
        int m;
 
        intf = list_entry(dev,struct usb_interface,dev);
        driver = to_usb_driver(dev->driver);
+       udev = interface_to_usbdev(intf);
 
        if (!driver) {
                err("%s does not have a valid driver to work with!",
@@ -135,7 +142,9 @@
         * the holder of the lock guards against 
         * module unload */
        down(&driver->serialize);
-
+printk("Got driver lock.\n");
+       down(&udev->serialize);
+printk("Got device lock.\n");
        if (intf->driver && intf->driver->disconnect)
                intf->driver->disconnect(intf);
 
@@ -143,6 +152,7 @@
        if (intf->driver)
                usb_driver_release_interface(driver, intf);
 
+       up(&udev->serialize);
        up(&driver->serialize);
        if (driver->owner)
                __MOD_DEC_USE_COUNT(driver->owner);
@@ -317,7 +327,7 @@
  * usb_driver_release_interface - unbind a driver from an interface
  * @driver: the driver to be unbound
  * @iface: the interface from which it will be unbound
- * 
+ *
  * This should be used by drivers to release their claimed interfaces.
  * It is normally called in their disconnect() methods, and only for
  * drivers that bound to more than one interface in their probe().
@@ -761,6 +771,26 @@
        return -1;
 }
 
+/** usb_reap_interfaces - disconnect all interfaces of a usb device
+ *  @dev: pointer to the device whose interfaces shall be disconnected
+ *  Context: !in_interrupt ()
+ *
+ *  Getting rid of interfaces associated with drivers.
+ *  This is for physical disconnection and configuration changes
+ */
+void usb_reap_interfaces(struct usb_device *dev)
+{
+       int i;
+
+       if (dev->actconfig) {
+               for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
+                       struct usb_interface *interface = 
+&dev->actconfig->interface[i];
+
+                       /* remove this interface */
+                       put_device(&interface->dev);
+               }
+       }
+}
 /**
  * usb_disconnect - disconnect a device (usbcore-internal)
  * @pdev: pointer to device being disconnected
@@ -792,14 +822,7 @@
                        usb_disconnect(child);
        }
 
-       if (dev->actconfig) {
-               for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
-                       struct usb_interface *interface = 
&dev->actconfig->interface[i];
-
-                       /* remove this interface */
-                       put_device(&interface->dev);
-               }
-       }
+       usb_reap_interfaces(dev);
 
        /* Free the device number and remove the /proc/bus/usb entry */
        if (dev->devnum > 0) {
@@ -923,6 +946,66 @@
 }
 
 /*
+ * Logical reevaluation of a device - for new devices or configuration 
changes
+ */
+int do_logical_register_dev(struct usb_device *dev)
+{
+       int err;
+       int i;
+       
+       /*
+        * Set the driver for the usb device to point to the "generic" driver.
+        * This prevents the main usb device from being sent to the usb bus
+        * probe function.  Yes, it's a hack, but a nice one :)
+        */
+       dev->dev.driver = &usb_generic_driver;
+       dev->dev.bus = &usb_bus_type;
+       if (dev->dev.bus_id[0] == 0)
+               sprintf (&dev->dev.bus_id[0], "%d-%s",
+                        dev->bus->busnum, dev->devpath);
+       err = device_register (&dev->dev);
+       if (err)
+               return err;
+
+       /* add the USB device specific driverfs files */
+       usb_create_driverfs_dev_files (dev);
+
+       /* Register all of the interfaces for this device with the driver core.
+        * Remember, interfaces get bound to drivers, not devices. */
+       for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
+               struct usb_interface *interface = &dev->actconfig->interface[i];
+               struct usb_interface_descriptor *desc = interface->altsetting;
+
+               interface->dev.parent = &dev->dev;
+               interface->dev.driver = NULL;
+               interface->dev.bus = &usb_bus_type;
+               sprintf (&interface->dev.bus_id[0], "%d-%s:%d",
+                        dev->bus->busnum, dev->devpath,
+                        interface->altsetting->bInterfaceNumber);
+               if (!desc->iInterface
+                               || usb_string (dev, desc->iInterface,
+                                       interface->dev.name,
+                                       sizeof interface->dev.name) <= 0) {
+                       /* typically devices won't bother with interface
+                        * descriptions; this is the normal case.  an
+                        * interface's driver might describe it better.
+                        * (also: iInterface is per-altsetting ...)
+                        */
+                       sprintf (&interface->dev.name[0],
+                               "usb-%s-%s interface %d",
+                               dev->bus->bus_name, dev->devpath,
+                               interface->altsetting->bInterfaceNumber);
+               }
+               dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
+               device_register (&interface->dev);
+               usb_create_driverfs_intf_files (interface);
+       }
+       
+       return 0;
+}
+
+
+/*
  * By the time we get here, the device has gotten a new device ID
  * and is in the default state. We need to identify the thing and
  * get the ball rolling..
@@ -1008,7 +1091,7 @@
        }
 
        /* we set the default configuration here */
-       err = usb_set_configuration(dev, dev->config[0].bConfigurationValue);
+       err = do_set_conf(dev, dev->config[0].bConfigurationValue);
        if (err) {
                err("failed to set device %d default configuration (error=%d)",
                        dev->devnum, err);
@@ -1026,55 +1109,14 @@
                usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
 #endif
 
-       /*
-        * Set the driver for the usb device to point to the "generic" driver.
-        * This prevents the main usb device from being sent to the usb bus
-        * probe function.  Yes, it's a hack, but a nice one :)
-        */
+
        usb_generic_driver.bus = &usb_bus_type;
        dev->dev.parent = parent;
-       dev->dev.driver = &usb_generic_driver;
-       dev->dev.bus = &usb_bus_type;
-       if (dev->dev.bus_id[0] == 0)
-               sprintf (&dev->dev.bus_id[0], "%d-%s",
-                        dev->bus->busnum, dev->devpath);
-       err = device_register (&dev->dev);
+       
+       err = do_logical_register_dev(dev);
+       
        if (err)
                return err;
-
-       /* add the USB device specific driverfs files */
-       usb_create_driverfs_dev_files (dev);
-
-       /* Register all of the interfaces for this device with the driver core.
-        * Remember, interfaces get bound to drivers, not devices. */
-       for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
-               struct usb_interface *interface = &dev->actconfig->interface[i];
-               struct usb_interface_descriptor *desc = interface->altsetting;
-
-               interface->dev.parent = &dev->dev;
-               interface->dev.driver = NULL;
-               interface->dev.bus = &usb_bus_type;
-               sprintf (&interface->dev.bus_id[0], "%d-%s:%d",
-                        dev->bus->busnum, dev->devpath,
-                        interface->altsetting->bInterfaceNumber);
-               if (!desc->iInterface
-                               || usb_string (dev, desc->iInterface,
-                                       interface->dev.name,
-                                       sizeof interface->dev.name) <= 0) {
-                       /* typically devices won't bother with interface
-                        * descriptions; this is the normal case.  an
-                        * interface's driver might describe it better.
-                        * (also: iInterface is per-altsetting ...)
-                        */
-                       sprintf (&interface->dev.name[0],
-                               "usb-%s-%s interface %d",
-                               dev->bus->bus_name, dev->devpath,
-                               interface->altsetting->bInterfaceNumber);
-               }
-               dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id);
-               device_register (&interface->dev);
-               usb_create_driverfs_intf_files (interface);
-       }
 
        /* add a /proc/bus/usb entry */
        usbfs_add_device(dev);
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h       Fri Oct 11 01:08:39 2002
+++ b/include/linux/usb.h       Fri Oct 11 01:08:39 2002
@@ -375,6 +375,7 @@
 
        int have_langid;                /* whether string_langid is valid yet */
        int string_langid;              /* language ID for strings */
+       int desired_conf;               /* configuration to restore on resume */
 
        void *hcpriv;                   /* Host Controller private data */
        
@@ -1032,6 +1033,9 @@
                struct scatterlist *sg, int n_hw_ents);
 void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
                struct scatterlist *sg, int n_hw_ents);
+void usb_reap_interfaces(struct usb_device *dev);
+int do_set_conf(struct usb_device *dev, int configuration);
+int do_logical_register_dev(struct usb_device *dev);
 
 /*-------------------------------------------------------------------*
  *                         SYNCHRONOUS CALL SUPPORT                  *

===================================================================


This BitKeeper patch contains the following changesets:
1.890
## Wrapped with gzip_uu ##


begin 664 bkpatch3040
M'XL(`'<(ICT``[59Z7+;1A+^33S%1"D[),5C<(.4Y9(M*39K%=FK([79*,4"
M@2&)$@B@<$CV+OWNVST#@(`(21&]CEDBB.GIZ>G^^LS/Y#IA\;@5^MX=BZ6?
MR<<P2>$G"\*`#9;ABOE>D'T9A/$"%B_"$!:'^'HH=@QGM_TT9BP9LB^*+@'-
M9SMUE@26DG%+'JCEF_1KQ,:MB],/UV?O+B3I\)`<+^U@P2Y92@X/I=GMD9LQ
M?W`;A_82CUN7RVN%4EF6%9VJNB'K:\5256TM&W3FPJ.KF*/YS!A)L>MF@6]'
M1V'B^ML<%)E2BYJ*ILMKU=3,D71"Y($UHH0J0YD.99E0>4PM^.Q394PI$3<\
M:M(%V==(GTKOR?>+?2PYI$^<,)@3AV]-I'\0386]TN>-BJ3^"_^3)&I3Z2U9
MQ&QQ)*1SPM7:C?%.R3!+9D,GC-EPQ9+$7K"!PW5$#:K*NJ;)QEJFAC9:SPU=
M4RW--%Q+MJ@Z>THISS&7J4P5E9I4!5V8I@K2;:O/"QP_<]F0<T5.@^5&D1K5
M-;H&P31S[2J*ZEJNKL\-337D)P5[A&E5(I5:BM(H4?56N-6IRC,"32FJIFMK
MQU`8TRU%-IV9K5+]99HJ&==D,A7U>9F668-,JJPIZMJ1;6.NFZJFN3-=-U\H
M4\FX*A.EFC7B[MM,W^S+.\HK/8?>JHC@VU0QP,6HK%L&]VY#K3NW.:;JWW%N
MF?3E'^C<H,!/I!_?\P^XZN='=+F#TY_(BCHBLC3)OULQAE?BAM.$I5,4I.VR
MNQZ!/_VWMI/B&V_1?SL[Y@]9;*=>&/QN^QGK'#2;F4/U>3._P%6>-7/5.THS
M*U2GPLPRN/].=AY9I*\;/\[2PH&?LS6_W0ZVGI@F6CA)X\Q)"7"9@E4]AY$N
M@6!W!V8G7I"R>&X[;)J&4Z"`UVUX-P?;3D8&4:4HAI^W[;T/89H+1OS0N1W<
M!'M`TVJYX7U`VJ\SCA>H%#S;]_Z#T*AM%,=6-DY&7+16%C5NGH`^'Q$=B3F!
M@03Y/9ZXQHFL6ASO\/7L=?`V.UQ&UG0N3-2T]T15*`H@OD@7S`)A1Z'2L-OE
M-XN9'4W+&R2`$M=+`"@!@ZO;OD\J:^&<V+@IEP+8$7($SV,2A9R,I"%)EZR0
M\GX9)JS*(%DBQQFKG,%<S@8</&5?TC'YR0N$.'$6I:3=09F1X`-+4R]8D-AS
M48X*4SM)0L>[EMAIL PROTECTED]]])E@>`!WW:U]!("GWD8DVCY-?$<VZ^<#M&$V(%+G&I\
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
&XRC-'0``
`
end



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to