From: Greg KH <greg@kroah.com>
To: torvalds@transmeta.com
Cc: linux-usb-devel@lists.sourceforge.net
Subject: [PATCH 2 of 8] USB module ownership change

Hi,

Here's a patch against 2.5.2-pre7 that allows the USB core to control
the module usage count of the USB driver modules.

thanks,

greg k-h



diff -Nru a/drivers/usb/devio.c b/drivers/usb/devio.c
--- a/drivers/usb/devio.c	Thu Jan  3 16:45:34 2002
+++ b/drivers/usb/devio.c	Thu Jan  3 16:45:34 2002
@@ -40,6 +40,7 @@
 #include <linux/smp_lock.h>
 #include <linux/signal.h>
 #include <linux/poll.h>
+#include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <asm/uaccess.h>
@@ -1086,10 +1087,15 @@
 			else if (ifp->driver == 0 || ifp->driver->ioctl == 0)
 				retval = -ENOSYS;
 		}
-		if (retval == 0)
+		if (retval == 0) {
+			if (ifp->driver->owner)
+				__MOD_INC_USE_COUNT(ifp->driver->owner);
 			/* ifno might usefully be passed ... */
 			retval = ifp->driver->ioctl (ps->dev, ctrl.ioctl_code, buf);
 			/* size = min_t(int, size, retval)? */
+			if (ifp->driver->owner)
+				__MOD_DEC_USE_COUNT(ifp->driver->owner);
+		}
 	}
 
 	/* cleanup and return */
diff -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c
--- a/drivers/usb/usb.c	Thu Jan  3 16:45:35 2002
+++ b/drivers/usb/usb.c	Thu Jan  3 16:45:35 2002
@@ -150,9 +150,13 @@
 		struct usb_interface *interface = &dev->actconfig->interface[i];
 		
 		if (interface->driver == driver) {
+			if (driver->owner)
+				__MOD_INC_USE_COUNT(driver->owner);
 			down(&driver->serialize);
 			driver->disconnect(dev, interface->private_data);
 			up(&driver->serialize);
+			if (driver->owner)
+				__MOD_DEC_USE_COUNT(driver->owner);
 			/* if driver->disconnect didn't release the interface */
 			if (interface->driver)
 				usb_driver_release_interface(driver, interface);
@@ -781,6 +785,8 @@
 		driver = list_entry(tmp, struct usb_driver, driver_list);
 		tmp = tmp->next;
 
+		if (driver->owner)
+			__MOD_INC_USE_COUNT(driver->owner);
 		id = driver->id_table;
 		/* new style driver? */
 		if (id) {
@@ -804,6 +810,8 @@
 			private = driver->probe(dev, ifnum, NULL);
 			up(&driver->serialize);
 		}
+		if (driver->owner)
+			__MOD_DEC_USE_COUNT(driver->owner);
 
 		/* probe() may have changed the config on us */
 		interface = dev->actconfig->interface + ifnum;
@@ -1887,9 +1895,13 @@
 			struct usb_interface *interface = &dev->actconfig->interface[i];
 			struct usb_driver *driver = interface->driver;
 			if (driver) {
+				if (driver->owner)
+					__MOD_INC_USE_COUNT(driver->owner);
 				down(&driver->serialize);
 				driver->disconnect(dev, interface->private_data);
 				up(&driver->serialize);
+				if (driver->owner)
+					__MOD_DEC_USE_COUNT(driver->owner);
 				/* if driver->disconnect didn't release the interface */
 				if (interface->driver)
 					usb_driver_release_interface(driver, interface);
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Thu Jan  3 16:45:35 2002
+++ b/include/linux/usb.h	Thu Jan  3 16:45:35 2002
@@ -460,6 +460,7 @@
 
 /**
  * struct usb_driver - identifies USB driver to usbcore
+ * @owner: pointer to the module owner of this driver
  * @name: The driver name should be unique among USB drivers
  * @probe: Called to see if the driver is willing to manage a particular
  *	interface on a device.  The probe routine returns a handle that 
@@ -502,6 +503,7 @@
  * well as cancel any I/O requests that are still pending.
  */
 struct usb_driver {
+	struct module *owner;
 	const char *name;
 
 	void *(*probe)(
