speedtch usbatm.h,1.4,1.5 usbatm2.c,1.13,1.14
Roman Kagan
rkagan at mail.ru
Mon Feb 7 04:21:21 EST 2005
> I'll be sending a complete async patch vs current CVS in a minute.
Here you are:
Index: usbatm.h
===================================================================
RCS file: /home/cvs/usbatm/usbatm.h,v
retrieving revision 1.8
diff -u -r1.8 usbatm.h
--- usbatm.h 1 Feb 2005 23:20:49 -0000 1.8
+++ usbatm.h 7 Feb 2005 02:54:25 -0000
@@ -74,9 +74,12 @@
/* additional device initialization that is too slow to be done in probe() */
int (*heavy_init) (struct usbatm_data *, struct usb_interface *);
- /* cleanup device ... can sleep, but can't fail */
+ /* disconnect device ... can sleep, but can't fail */
void (*unbind) (struct usbatm_data *, struct usb_interface *);
+ /* release the resources allocated to the device */
+ void (*cleanup) (struct usbatm_data *);
+
/* init ATM device ... can sleep, or cause ATM initialization failure */
int (*atm_start) (struct usbatm_data *, struct atm_dev *);
@@ -148,17 +151,13 @@
struct usbatm_data {
struct kref refcount;
+ struct kref sub_refcount;
struct semaphore serialize;
/* mini driver part */
struct usbatm_driver *driver;
void *driver_data;
- /* heavy init part */
- int thread_pid;
- struct completion thread_started;
- struct completion thread_exited;
-
/* USB device part */
struct usb_device *usb_dev;
struct usb_interface *usb_intf;
Index: usbatm.c
===================================================================
RCS file: /home/cvs/usbatm/usbatm.c,v
retrieving revision 1.4
diff -u -r1.4 usbatm.c
--- usbatm.c 1 Feb 2005 23:20:49 -0000 1.4
+++ usbatm.c 7 Feb 2005 02:54:25 -0000
@@ -763,6 +763,23 @@
kref_put(&instance->refcount, usbatm_destroy_instance);
}
+static void usbatm_destroy_sub_instance(struct kref *kref)
+{
+ struct usbatm_data *instance = container_of(kref, struct usbatm_data, sub_refcount);
+
+ if (instance->driver->cleanup)
+ instance->driver->cleanup(instance);
+}
+
+void usbatm_get_sub_instance(struct usbatm_data *instance)
+{
+ kref_get(&instance->sub_refcount);
+}
+
+void usbatm_put_sub_instance(struct usbatm_data *instance)
+{
+ kref_put(&instance->sub_refcount, usbatm_destroy_sub_instance);
+}
/**********
** ATM **
@@ -994,38 +1011,39 @@
int ret;
daemonize("%s/%s", usbatm_driver_name, instance->driver->driver_name);
- allow_signal(SIGTERM);
-
- complete(&instance->thread_started);
ret = instance->driver->heavy_init(instance, instance->usb_intf);
if (!ret)
ret = usbatm_atm_init(instance);
- down(&instance->serialize);
- instance->thread_pid = -1;
- up(&instance->serialize);
+ usbatm_put_sub_instance(instance);
+ module_put(instance->driver->owner);
+ usbatm_put_instance(instance);
- complete_and_exit(&instance->thread_exited, ret);
+ return ret;
}
static int usbatm_heavy_init(struct usbatm_data *instance)
{
- int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_KERNEL);
-
- if (ret < 0) {
- dbg("usbatm_heavy_init: failed to create kernel_thread (%d)!", ret);
- return ret;
- }
-
- down(&instance->serialize);
- instance->thread_pid = ret;
- up(&instance->serialize);
+ int ret;
- wait_for_completion(&instance->thread_started);
+ usbatm_get_instance(instance);
+ try_module_get(instance->driver->owner);
+ usbatm_get_sub_instance(instance);
+
+ ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_KERNEL);
+
+ if (ret >= 0)
+ return 0; /* OK */
+
+ dbg("usbatm_heavy_init: failed to create kernel_thread (%d)!", ret);
+
+ usbatm_put_sub_instance(instance);
+ module_put(instance->driver->owner);
+ usbatm_put_instance(instance);
- return 0;
+ return ret;
}
int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id,
@@ -1035,11 +1053,12 @@
struct usbatm_data *instance;
char *buf;
int error = -ENOMEM;
- int ifnum = intf->altsetting->desc.bInterfaceNumber;
int i, length;
int need_heavy;
- dev_dbg(&intf->dev, "trying device with vendor=0x%x, product=0x%x, ifnum %d\n", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+ dev_dbg(&intf->dev, "trying device with vendor=0x%x, product=0x%x, ifnum %d\n",
+ dev->descriptor.idVendor, dev->descriptor.idProduct,
+ intf->altsetting->desc.bInterfaceNumber);
/* instance init */
if (!(instance = kmalloc(sizeof(*instance), GFP_KERNEL))) {
@@ -1049,16 +1068,12 @@
memset(instance, 0, sizeof(*instance));
- kref_init(&instance->refcount); /* one for USB */
+ kref_init(&instance->refcount); /* dropped in usbatm_usb_disconnect */
init_MUTEX(&instance->serialize);
instance->driver = driver;
- instance->thread_pid = -1;
- init_completion(&instance->thread_started);
- init_completion(&instance->thread_exited);
-
instance->usb_dev = dev;
instance->usb_intf = intf;
instance->tx_endpoint = usb_sndbulkpipe(dev, driver->out);
@@ -1164,20 +1179,24 @@
bind:
need_heavy = 1;
if (driver->bind && (error = driver->bind(instance, intf, &need_heavy)) < 0)
- goto fail;
+ goto fail;
+
+ kref_init(&instance->sub_refcount); /* dropped in usbatm_usb_disconnect after ->unbind */
if (need_heavy && driver->heavy_init)
error = usbatm_heavy_init(instance);
- else {
- complete(&instance->thread_exited); /* pretend that heavy_init was run */
+ else
error = usbatm_atm_init(instance);
- }
- if (error)
+ if (error) {
+ if (instance->driver->unbind)
+ instance->driver->unbind(instance, intf);
+
+ usbatm_put_sub_instance(instance);
goto fail;
+ }
usb_get_dev(dev);
- usbatm_get_instance(instance); /* dropped in usbatm_usb_disconnect */
usb_set_intfdata(intf, instance);
return 0;
@@ -1215,19 +1234,14 @@
usb_set_intfdata(intf, NULL);
- down(&instance->serialize);
- if (instance->thread_pid >= 0)
- kill_proc(instance->thread_pid, SIGTERM, 1);
- up(&instance->serialize);
-
- wait_for_completion(&instance->thread_exited);
-
if (instance->atm_dev && instance->driver->atm_stop)
instance->driver->atm_stop(instance, instance->atm_dev);
if (instance->driver->unbind)
instance->driver->unbind(instance, intf);
+ usbatm_put_sub_instance(instance);
+
/* receive finalize */
tasklet_disable(&instance->receive_tasklet);
Index: cxacru.c
===================================================================
RCS file: /home/cvs/usbatm/cxacru.c,v
retrieving revision 1.8
diff -u -r1.8 cxacru.c
--- cxacru.c 1 Feb 2005 23:20:49 -0000 1.8
+++ cxacru.c 7 Feb 2005 02:54:25 -0000
@@ -763,6 +763,18 @@
del_timer_sync(&instance->poll_timer);
wmb();
flush_scheduled_work();
+}
+
+static void cxacru_cleanup(struct usbatm_data *usbatm_instance)
+{
+ struct cxacru_data *instance = usbatm_instance->driver_data;
+
+ dbg("cxacru_cleanup entered");
+
+ if (!instance) {
+ dbg("cxacru_cleanup: NULL instance!");
+ return;
+ }
usb_kill_urb(instance->snd_urb);
usb_kill_urb(instance->rcv_urb);
@@ -828,6 +840,7 @@
.bind = cxacru_bind,
.heavy_init = cxacru_heavy_init,
.unbind = cxacru_unbind,
+ .cleanup = cxacru_cleanup,
.atm_start = cxacru_atm_start,
.in = CXACRU_EP_DATA,
.out = CXACRU_EP_DATA,
@@ -853,13 +866,13 @@
return usb_register(&cxacru_usb_driver);
}
-static void __exit cxacru_cleanup(void)
+static void __exit cxacru_exit(void)
{
usb_deregister(&cxacru_usb_driver);
}
module_init(cxacru_init);
-module_exit(cxacru_cleanup);
+module_exit(cxacru_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
More information about the Usbatm
mailing list