Hi, this is the first version of the updated and improved patch. It fails for me in an utterly bizarre way. It breaks some shared libraries. Could somebody replicate that, or is it time to run memtest86?
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], 2003-01-22 00:50:24+01:00, [EMAIL PROTECTED] - safe configuration test drivers/usb/core/devio.c | 2 +- drivers/usb/core/hcd-pci.c | 2 +- drivers/usb/core/hcd.h | 2 +- drivers/usb/core/hub.c | 31 ++++++++++++++++++++----------- drivers/usb/core/message.c | 28 ++++++++++++++++++++++++---- drivers/usb/core/usb.c | 42 +++++++++++++++++++++++++++++++----------- include/linux/usb.h | 1 + 7 files changed, 79 insertions(+), 29 deletions(-) diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c --- a/drivers/usb/core/devio.c Wed Jan 22 00:53:43 2003 +++ b/drivers/usb/core/devio.c Wed Jan 22 00:53:43 2003 @@ -758,7 +758,7 @@ if (get_user(u, (unsigned int *)arg)) return -EFAULT; - if (usb_set_configuration(ps->dev, u) < 0) + if (usb_set_logical_configuration(ps->dev, u) < 0) return -EINVAL; return 0; } diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c --- a/drivers/usb/core/hcd-pci.c Wed Jan 22 00:53:43 2003 +++ b/drivers/usb/core/hcd-pci.c Wed Jan 22 00:53:43 2003 @@ -215,7 +215,7 @@ hcd->state = USB_STATE_QUIESCING; dev_dbg (*hcd->controller, "roothub graceful disconnect\n"); - usb_disconnect (&hub); + usb_logical_disconnect (&hub); hcd->driver->stop (hcd); hcd_buffer_destroy (hcd); diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Wed Jan 22 00:53:43 2003 +++ b/drivers/usb/core/hcd.h Wed Jan 22 00:53:43 2003 @@ -239,7 +239,7 @@ /* Enumeration is only for the hub driver, or HCD virtual root hubs */ extern int usb_new_device(struct usb_device *dev, struct device *parent); extern void usb_connect(struct usb_device *dev); -extern void usb_disconnect(struct usb_device **); +extern void usb_logical_disconnect(struct usb_device **); /* exported to hub driver ONLY to support usb_reset_device () */ extern int usb_get_configuration(struct usb_device *dev); diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c Wed Jan 22 00:53:43 2003 +++ b/drivers/usb/core/hub.c Wed Jan 22 00:53:43 2003 @@ -603,7 +603,7 @@ /* Disconnect any attached devices */ for (i = 0; i < hub->descriptor->bNbrPorts; i++) { if (dev->children[i]) - usb_disconnect(&dev->children[i]); + usb_logical_disconnect(&dev->children[i]); } /* Attempt to reset the hub */ @@ -633,7 +633,7 @@ if (parent) { for (i = 0; i < parent->maxchild; i++) { if (parent->children[i] == dev) { - usb_disconnect(&parent->children[i]); + usb_logical_disconnect(&parent->children[i]); return; } } @@ -838,7 +838,7 @@ /* Disconnect any existing devices under this port */ if (hub->children[port]) - usb_disconnect(&hub->children[port]); + usb_logical_disconnect(&hub->children[port]); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { @@ -1198,13 +1198,16 @@ if (port < 0) return -ENOENT; + ret = 0; + down(&dev->serialize); /* to prevent probing other interfaces */ down(&usb_address0_sem); /* Send a reset to the device */ if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) { usb_hub_port_disable(parent, port); up(&usb_address0_sem); + up(&dev->serialize); return(-ENODEV); } @@ -1214,6 +1217,7 @@ err("USB device not accepting new address (error=%d)", ret); usb_hub_port_disable(parent, port); up(&usb_address0_sem); + up(&dev->serialize); return ret; } @@ -1234,7 +1238,7 @@ ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor, sizeof(descriptor)); if (ret < 0) - return ret; + goto err_out; le16_to_cpus(&descriptor.bcdUSB); le16_to_cpus(&descriptor.idVendor); @@ -1257,7 +1261,8 @@ clear_bit(dev->devnum, dev->bus->devmap.devicemap); dev->devnum = -1; - return -EIO; + ret = -EIO; + goto err_out; } ret = usb_get_configuration(dev); @@ -1266,20 +1271,22 @@ usb_destroy_configuration(dev); clear_bit(dev->devnum, dev->bus->devmap.devicemap); dev->devnum = -1; - return 1; + ret = 1; + goto err_out; } dev->actconfig = dev->config; usb_set_maxpacket(dev); - return 1; + ret = 1; + goto err_out; } - ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue); + ret = usb_set_physical_configuration(dev, dev->desired_conf); if (ret < 0) { err("failed to set dev %s active configuration (error=%d)", dev->devpath, ret); - return ret; + goto err_out; } for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { @@ -1293,10 +1300,12 @@ err("failed to set active alternate setting " "for dev %s interface %d (error=%d)", dev->devpath, i, ret); - return ret; + goto err_out; } } - return 0; +err_out: + up(&dev->serialize); + return ret; } diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Wed Jan 22 00:53:43 2003 +++ b/drivers/usb/core/message.c Wed Jan 22 00:53:43 2003 @@ -7,6 +7,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/byteorder.h> #include "hcd.h" /* for usbcore internals */ @@ -838,7 +839,7 @@ } /** - * usb_set_configuration - Makes a particular device setting be current + * usb_set_physical_configuration - Makes a particular device setting be current * @dev: the device whose configuration is being updated * @configuration: the configuration being chosen. * Context: !in_interrupt () @@ -867,11 +868,12 @@ * Returns zero on success, or else the status code returned by the * underlying usb_control_msg() call. */ -int usb_set_configuration(struct usb_device *dev, int configuration) + +int usb_set_physical_configuration(struct usb_device *dev, int configuration) { int i, ret; struct usb_host_config *cp = NULL; - + for (i=0; i<dev->descriptor.bNumConfigurations; i++) { if (dev->config[i].desc.bConfigurationValue == configuration) { cp = &dev->config[i]; @@ -889,6 +891,7 @@ return ret; dev->actconfig = cp; + dev->desired_conf = configuration; dev->toggle[0] = 0; dev->toggle[1] = 0; usb_set_maxpacket(dev); @@ -896,6 +899,22 @@ return 0; } +int usb_set_logical_configuration(struct usb_device *dev, int configuration) +{ + int ret; + + down(&dev->serialize); + lock_kernel(); /* functions now called must be called with BKL held */ + usb_physical_disconnect(dev); + ret = usb_set_physical_configuration(dev, configuration); + usb_bind_device(dev); + unlock_kernel(); + up(&dev->serialize); + + return ret; +} + + /** * usb_string - returns ISO 8859-1 version of a string descriptor @@ -998,6 +1017,7 @@ EXPORT_SYMBOL(usb_get_string); EXPORT_SYMBOL(usb_string); EXPORT_SYMBOL(usb_clear_halt); -EXPORT_SYMBOL(usb_set_configuration); +EXPORT_SYMBOL(usb_set_physical_configuration); +EXPORT_SYMBOL(usb_set_logical_configuration); EXPORT_SYMBOL(usb_set_interface); diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Wed Jan 22 00:53:43 2003 +++ b/drivers/usb/core/usb.c Wed Jan 22 00:53:43 2003 @@ -817,23 +817,20 @@ * * This call is synchronous, and may not be used in an interrupt context. */ -void usb_disconnect(struct usb_device **pdev) +void usb_physical_disconnect(struct usb_device *dev) { - struct usb_device * dev = *pdev; int i; if (!dev) return; - *pdev = NULL; - dev_info (&dev->dev, "USB disconnect, address %d\n", dev->devnum); /* Free up all the children before we remove this device */ for (i = 0; i < USB_MAXCHILDREN; i++) { struct usb_device **child = dev->children + i; if (*child) - usb_disconnect(child); + usb_logical_disconnect(child); } dev_dbg (&dev->dev, "unregistering interfaces\n"); @@ -853,9 +850,16 @@ usbfs_remove_device(dev); } device_unregister(&dev->dev); +} - /* Decrement the reference count, it'll auto free everything when */ - /* it hits 0 which could very well be now */ +void usb_logical_disconnect(struct usb_device **pdev) +{ + struct usb_device * dev = *pdev; + + down(&dev->serialize); + usb_physical_disconnect(dev); + up(&dev->serialize); + usb_put_dev(dev); } @@ -896,7 +900,6 @@ } } - // hub-only!! ... and only exported for reset/reinit path. // otherwise used internally, for usb_new_device() int usb_set_address(struct usb_device *dev) @@ -982,7 +985,7 @@ */ #define NEW_DEVICE_RETRYS 2 #define SET_ADDRESS_RETRYS 2 -int usb_new_device(struct usb_device *dev, struct device *parent) +int usb_bind_device(struct usb_device *dev, struct device *parent) { int err = 0; int i; @@ -1097,7 +1100,8 @@ } /* we set the default configuration here */ - err = usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue); + err = usb_set_physical_configuration(dev, +dev->config[0].desc.bConfigurationValue); + dev->desired_conf = dev->config[0].desc.bConfigurationValue; if (err) { dev_err(&dev->dev, "failed to set device %d default configuration (error=%d)\n", dev->devnum, err); @@ -1162,6 +1166,20 @@ return 0; } + +int usb_new_device(struct usb_device *dev, struct device *parent) +{ + int r; + + down(&dev->serialize); + r = usb_bind_device(dev, parent); + up(&dev->serialize); + + return r; +} + + + /** * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP * @dev: device the buffer will be used with @@ -1487,9 +1505,11 @@ EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_new_device); +EXPORT_SYMBOL(usb_bind_device); EXPORT_SYMBOL(usb_reset_device); EXPORT_SYMBOL(usb_connect); -EXPORT_SYMBOL(usb_disconnect); +EXPORT_SYMBOL(usb_physical_disconnect); +EXPORT_SYMBOL(usb_logical_disconnect); EXPORT_SYMBOL(__usb_get_extra_descriptor); diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Wed Jan 22 00:53:43 2003 +++ b/include/linux/usb.h Wed Jan 22 00:53:43 2003 @@ -218,6 +218,7 @@ int ttport; /* device port on that tt hub */ struct semaphore serialize; + int desired_conf; /* configuration to be restored after reset, +resume, etc. */ unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */ ------------------------------------------------------- This SF.net email is sponsored by: Scholarships for Techies! Can't afford IT training? All 2003 ictp students receive scholarships. Get hands-on training in Microsoft, Cisco, Sun, Linux/UNIX, and more. www.ictp.com/training/sourceforge.asp _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel