From: Greg KH 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 #include #include +#include #include #include #include @@ -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)(