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