Hi list,
here is a patch against pre-7 to prevent races with module unload.
It adds a field 'module' to the usb_driver structure. Thus all applicable
drivers are touched. These are too numerous to contact all maintainers.
It does not work for storage and microtek as it would interfere with scsi
unregistering. It also does not work with serial, as it and possibly hid and
videodev, which I still have to look into, use submodules.
I'll make a seperate patch for serial tomorrow.
Regards
Oliver
diff -u --recursive --new-file linuxvanilla/drivers/usb/CDCEther.c
linux/drivers/usb/CDCEther.c
--- linuxvanilla/drivers/usb/CDCEther.c Mon Sep 10 23:39:59 2001
+++ linux/drivers/usb/CDCEther.c Tue Sep 11 00:01:10 2001
@@ -1245,6 +1245,7 @@
probe: CDCEther_probe,
disconnect: CDCEther_disconnect,
id_table: CDCEther_ids,
+ module : THIS_MODULE,
};
/////////////////////////////////////////////////////////////////////////////
/
diff -u --recursive --new-file linuxvanilla/drivers/usb/acm.c
linux/drivers/usb/acm.c
--- linuxvanilla/drivers/usb/acm.c Mon Sep 10 23:39:30 2001
+++ linux/drivers/usb/acm.c Mon Sep 10 23:59:00 2001
@@ -658,6 +658,7 @@
probe: acm_probe,
disconnect: acm_disconnect,
id_table: acm_ids,
+ module : THIS_MODULE,
};
/*
diff -u --recursive --new-file linuxvanilla/drivers/usb/audio.c
linux/drivers/usb/audio.c
--- linuxvanilla/drivers/usb/audio.c Mon Sep 10 23:38:56 2001
+++ linux/drivers/usb/audio.c Mon Sep 10 23:59:32 2001
@@ -2720,6 +2720,7 @@
disconnect: usb_audio_disconnect,
driver_list: LIST_HEAD_INIT(usb_audio_driver.driver_list),
id_table: usb_audio_ids,
+ module : THIS_MODULE,
};
static void *find_descriptor(void *descstart, unsigned int desclen, void
*after,
diff -u --recursive --new-file linuxvanilla/drivers/usb/bluetooth.c
linux/drivers/usb/bluetooth.c
--- linuxvanilla/drivers/usb/bluetooth.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/bluetooth.c Tue Sep 11 00:00:05 2001
@@ -236,6 +236,7 @@
probe: usb_bluetooth_probe,
disconnect: usb_bluetooth_disconnect,
id_table: usb_bluetooth_ids,
+ module : THIS_MODULE,
};
static int bluetooth_refcount;
diff -u --recursive --new-file linuxvanilla/drivers/usb/catc.c
linux/drivers/usb/catc.c
--- linuxvanilla/drivers/usb/catc.c Mon Sep 10 23:38:56 2001
+++ linux/drivers/usb/catc.c Tue Sep 11 00:00:37 2001
@@ -740,6 +740,7 @@
probe: catc_probe,
disconnect: catc_disconnect,
id_table: catc_id_table,
+ module : THIS_MODULE,
};
static int __init catc_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/dabusb.c
linux/drivers/usb/dabusb.c
--- linuxvanilla/drivers/usb/dabusb.c Mon Sep 10 23:39:59 2001
+++ linux/drivers/usb/dabusb.c Tue Sep 11 00:01:41 2001
@@ -804,6 +804,7 @@
fops: &dabusb_fops,
minor: DABUSB_MINOR,
id_table: dabusb_ids,
+ module : THIS_MODULE,
};
/* --------------------------------------------------------------------- */
diff -u --recursive --new-file linuxvanilla/drivers/usb/dc2xx.c
linux/drivers/usb/dc2xx.c
--- linuxvanilla/drivers/usb/dc2xx.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/dc2xx.c Tue Sep 11 00:02:17 2001
@@ -509,6 +509,7 @@
disconnect: camera_disconnect,
fops: &usb_camera_fops,
+ module : THIS_MODULE,
minor: USB_CAMERA_MINOR_BASE
};
diff -u --recursive --new-file linuxvanilla/drivers/usb/dsbr100.c
linux/drivers/usb/dsbr100.c
--- linuxvanilla/drivers/usb/dsbr100.c Mon Sep 10 23:39:30 2001
+++ linux/drivers/usb/dsbr100.c Tue Sep 11 00:02:48 2001
@@ -124,6 +124,7 @@
fops: NULL,
minor: 0,
id_table: usb_dsbr100_table,
+ module : THIS_MODULE,
};
diff -u --recursive --new-file linuxvanilla/drivers/usb/hid.c
linux/drivers/usb/hid.c
--- linuxvanilla/drivers/usb/hid.c Mon Sep 10 23:38:56 2001
+++ linux/drivers/usb/hid.c Tue Sep 11 00:03:24 2001
@@ -1554,6 +1554,7 @@
probe: hid_probe,
disconnect: hid_disconnect,
id_table: hid_usb_ids,
+ module : THIS_MODULE,
};
static int __init hid_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/hub.c
linux/drivers/usb/hub.c
--- linuxvanilla/drivers/usb/hub.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/hub.c Tue Sep 11 00:03:59 2001
@@ -855,6 +855,7 @@
ioctl: hub_ioctl,
disconnect: hub_disconnect,
id_table: hub_id_table,
+ module : THIS_MODULE,
};
/*
diff -u --recursive --new-file linuxvanilla/drivers/usb/ibmcam.c
linux/drivers/usb/ibmcam.c
--- linuxvanilla/drivers/usb/ibmcam.c Mon Sep 10 23:39:45 2001
+++ linux/drivers/usb/ibmcam.c Tue Sep 11 00:04:25 2001
@@ -3133,6 +3133,7 @@
probe: usb_ibmcam_probe,
disconnect: usb_ibmcam_disconnect,
id_table: ibmcam_table,
+ module : THIS_MODULE,
};
/*
diff -u --recursive --new-file linuxvanilla/drivers/usb/kaweth.c
linux/drivers/usb/kaweth.c
--- linuxvanilla/drivers/usb/kaweth.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/kaweth.c Tue Sep 11 00:04:53 2001
@@ -158,6 +158,7 @@
probe: kaweth_probe,
disconnect: kaweth_disconnect,
id_table: usb_klsi_table,
+ module : THIS_MODULE,
};
typedef __u8 eth_addr_t[6];
diff -u --recursive --new-file linuxvanilla/drivers/usb/mdc800.c
linux/drivers/usb/mdc800.c
--- linuxvanilla/drivers/usb/mdc800.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/mdc800.c Tue Sep 11 00:05:31 2001
@@ -902,6 +902,7 @@
disconnect: mdc800_usb_disconnect,
fops: &mdc800_device_ops,
minor: MDC800_DEVICE_MINOR_BASE,
+ module : THIS_MODULE,
id_table: mdc800_table
};
diff -u --recursive --new-file linuxvanilla/drivers/usb/ov511.c
linux/drivers/usb/ov511.c
--- linuxvanilla/drivers/usb/ov511.c Mon Sep 10 23:39:45 2001
+++ linux/drivers/usb/ov511.c Tue Sep 11 00:06:06 2001
@@ -3422,7 +3422,8 @@
name: "ov511",
id_table: device_table,
probe: ov511_probe,
- disconnect: ov511_disconnect
+ disconnect: ov511_disconnect,
+ module : THIS_MODULE,
};
diff -u --recursive --new-file linuxvanilla/drivers/usb/pegasus.c
linux/drivers/usb/pegasus.c
--- linuxvanilla/drivers/usb/pegasus.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/pegasus.c Tue Sep 11 00:06:30 2001
@@ -930,6 +930,7 @@
probe: pegasus_probe,
disconnect: pegasus_disconnect,
id_table: pegasus_ids,
+ module : THIS_MODULE,
};
int __init pegasus_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/printer.c
linux/drivers/usb/printer.c
--- linuxvanilla/drivers/usb/printer.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/printer.c Tue Sep 11 00:06:58 2001
@@ -718,6 +718,7 @@
fops: &usblp_fops,
minor: USBLP_MINOR_BASE,
id_table: usblp_ids,
+ module : THIS_MODULE,
};
static int __init usblp_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/rio500.c
linux/drivers/usb/rio500.c
--- linuxvanilla/drivers/usb/rio500.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/rio500.c Tue Sep 11 00:07:28 2001
@@ -518,6 +518,7 @@
fops: &usb_rio_fops,
minor: RIO_MINOR,
id_table: rio_table,
+ module : THIS_MODULE,
};
int usb_rio_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/scanner.c
linux/drivers/usb/scanner.c
--- linuxvanilla/drivers/usb/scanner.c Mon Sep 10 23:39:45 2001
+++ linux/drivers/usb/scanner.c Tue Sep 11 00:08:01 2001
@@ -940,6 +940,7 @@
id_table: NULL, /* This would be scanner_device_ids, but we
need to check every USB device, in case
we match a user defined vendor/product ID. */
+ module : THIS_MODULE,
};
void __exit
diff -u --recursive --new-file linuxvanilla/drivers/usb/se401.c
linux/drivers/usb/se401.c
--- linuxvanilla/drivers/usb/se401.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/se401.c Tue Sep 11 00:08:28 2001
@@ -1629,7 +1629,8 @@
id_table: device_table,
#endif
probe: se401_probe,
- disconnect: se401_disconnect
+ disconnect: se401_disconnect,
+ module : THIS_MODULE,
};
diff -u --recursive --new-file linuxvanilla/drivers/usb/usb-skeleton.c
linux/drivers/usb/usb-skeleton.c
--- linuxvanilla/drivers/usb/usb-skeleton.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/usb-skeleton.c Tue Sep 11 00:08:58 2001
@@ -154,6 +154,7 @@
fops: &skel_fops,
minor: USB_SKEL_MINOR_BASE,
id_table: skel_table,
+ module : THIS_MODULE,
};
diff -u --recursive --new-file linuxvanilla/drivers/usb/usb.c
linux/drivers/usb/usb.c
--- linuxvanilla/drivers/usb/usb.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/usb.c Mon Sep 10 23:55:20 2001
@@ -123,6 +123,20 @@
read_unlock_irq (&usb_bus_list_lock);
}
+static void do_driver_disconnect(struct usb_driver *driver,struct usb_device
*dev, void* priv)
+{
+ /* make sure that the driver is not unloaded */
+ if (driver->module != NULL)
+ __MOD_INC_USE_COUNT(driver->module);
+
+ down(&driver->serialize);
+ driver->disconnect(dev,priv);
+ up(&driver->serialize);
+
+ if (driver->module != NULL)
+ __MOD_DEC_USE_COUNT(driver->module);
+}
+
/*
* This function is part of a depth-first search down the device tree,
* removing any instances of a device driver.
@@ -142,14 +156,12 @@
if (!dev->actconfig)
return;
-
+
for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
struct usb_interface *interface = &dev->actconfig->interface[i];
-
+
if (interface->driver == driver) {
- down(&driver->serialize);
- driver->disconnect(dev, interface->private_data);
- up(&driver->serialize);
+ do_driver_disconnect(driver, dev, interface->private_data);
/* if driver->disconnect didn't release the interface */
if (interface->driver)
usb_driver_release_interface(driver, interface);
@@ -668,6 +680,25 @@
return NULL;
}
+static inline void* do_probe_driver(struct usb_driver* driver,struct
usb_device *dev,unsigned int ifnum,struct usb_device_id *id)
+{
+
+ void * retval;
+
+ /* make sure that the driver is not unloaded */
+ if (driver->module != NULL)
+ __MOD_INC_USE_COUNT(driver->module);
+
+ down(&driver->serialize);
+ retval = driver->probe(dev,ifnum,id);
+ up(&driver->serialize);
+
+ if (driver->module != NULL)
+ __MOD_DEC_USE_COUNT(driver->module);
+
+ return retval;
+}
+
/*
* This entrypoint gets called for each new device.
*
@@ -717,9 +748,7 @@
interface->act_altsetting = i;
id = usb_match_id(dev, interface, id);
if (id) {
- down(&driver->serialize);
- private = driver->probe(dev,ifnum,id);
- up(&driver->serialize);
+ do_probe_driver(driver,dev,ifnum,id);
if (private != NULL)
break;
}
@@ -729,9 +758,7 @@
if (private == NULL)
interface->act_altsetting = 0;
} else { /* "old style" driver */
- down(&driver->serialize);
- private = driver->probe(dev, ifnum, NULL);
- up(&driver->serialize);
+ do_probe_driver(driver,dev,ifnum,NULL);
}
/* probe() may have changed the config on us */
@@ -1013,8 +1040,7 @@
*/
void usb_free_urb(urb_t* urb)
{
- if (urb)
- kfree(urb);
+ kfree(urb);
}
/*-------------------------------------------------------------------*/
int usb_submit_urb(urb_t *urb)
@@ -1044,8 +1070,7 @@
{
api_wrapper_data *awd = (api_wrapper_data *)urb->context;
- if (waitqueue_active(awd->wakeup))
- wake_up(awd->wakeup);
+ wake_up(awd->wakeup);
#if 0
else
dbg("(blocking_completion): waitqueue empty!");
@@ -1702,9 +1727,7 @@
struct usb_interface *interface =
&dev->actconfig->interface[i];
struct usb_driver *driver = interface->driver;
if (driver) {
- down(&driver->serialize);
- driver->disconnect(dev, interface->private_data);
- up(&driver->serialize);
+ do_driver_disconnect(driver, dev,
+interface->private_data);
/* if driver->disconnect didn't release the interface
*/
if (interface->driver)
usb_driver_release_interface(driver,
interface);
diff -u --recursive --new-file linuxvanilla/drivers/usb/usbkbd.c
linux/drivers/usb/usbkbd.c
--- linuxvanilla/drivers/usb/usbkbd.c Mon Sep 10 23:39:45 2001
+++ linux/drivers/usb/usbkbd.c Tue Sep 11 00:09:30 2001
@@ -275,6 +275,7 @@
probe: usb_kbd_probe,
disconnect: usb_kbd_disconnect,
id_table: usb_kbd_id_table,
+ module : THIS_MODULE,
};
static int __init usb_kbd_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/usbmouse.c
linux/drivers/usb/usbmouse.c
--- linuxvanilla/drivers/usb/usbmouse.c Mon Sep 10 23:38:56 2001
+++ linux/drivers/usb/usbmouse.c Tue Sep 11 00:09:56 2001
@@ -189,6 +189,7 @@
probe: usb_mouse_probe,
disconnect: usb_mouse_disconnect,
id_table: usb_mouse_id_table,
+ module : THIS_MODULE,
};
static int __init usb_mouse_init(void)
diff -u --recursive --new-file linuxvanilla/drivers/usb/usbnet.c
linux/drivers/usb/usbnet.c
--- linuxvanilla/drivers/usb/usbnet.c Mon Sep 10 23:40:12 2001
+++ linux/drivers/usb/usbnet.c Tue Sep 11 00:10:22 2001
@@ -1537,6 +1537,7 @@
id_table: products,
probe: usbnet_probe,
disconnect: usbnet_disconnect,
+ module : THIS_MODULE,
};
/*-------------------------------------------------------------------------*/
diff -u --recursive --new-file linuxvanilla/drivers/usb/uss720.c
linux/drivers/usb/uss720.c
--- linuxvanilla/drivers/usb/uss720.c Mon Sep 10 23:38:56 2001
+++ linux/drivers/usb/uss720.c Tue Sep 11 00:10:48 2001
@@ -647,6 +647,7 @@
probe: uss720_probe,
disconnect: uss720_disconnect,
id_table: uss720_table,
+ module : THIS_MODULE,
};
/* --------------------------------------------------------------------- */
diff -u --recursive --new-file linuxvanilla/include/linux/usb.h
linux/include/linux/usb.h
--- linuxvanilla/include/linux/usb.h Mon Sep 10 23:40:14 2001
+++ linux/include/linux/usb.h Mon Sep 10 23:57:31 2001
@@ -399,6 +399,8 @@
struct semaphore serialize;
+ struct module * module; /* to manage usage counts while probing and
disconnecting */
+
/* ioctl -- userspace apps can talk to drivers through usbdevfs */
int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf);
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel