speedtch usbatm.h,1.1,1.2 usbatm2.c,1.7,1.8

Duncan Sands duncan at infradead.org
Mon Jan 24 05:47:11 EST 2005


Update of /home/cvs/speedtch
In directory phoenix.infradead.org:/tmp/cvs-serv21760

Modified Files:
	usbatm.h usbatm2.c 
Log Message:
Shoot down the kernel thread if the device is disconnected.


Index: usbatm.h
===================================================================
RCS file: /home/cvs/speedtch/usbatm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- usbatm.h	24 Jan 2005 09:44:42 -0000	1.1
+++ usbatm.h	24 Jan 2005 10:47:08 -0000	1.2
@@ -54,24 +54,15 @@
 struct usbatm_data;
 
 /*
-*  Assuming all methods exist and succeed, they are called like this (except if
-*  the device is disconnected during heavy_init, see below):
+*  Assuming all methods exist and succeed, they are called like this:
 *
 *  	bind, heavy_init, atm_start, atm_stop, unbind
-*
-*  If heavy_init exists, it is run in its own kernel thread.  If the device is
-*  disconnected while heavy_init is executing, then methods are called as follows:
-*
-*  	bind, heavy_init
-*		unbind
-*
-*  Here unbind may be called while heavy_init is executing. QQ probably heavy_init
-*  should be shot down before calling unbind.
 */
 
 struct usbatm_driver {
-	const char *driver_name;
 	struct module *owner;
+
+	const char *driver_name;
 	const struct usb_device_id *id_table;
 
 	/* init device ... can sleep, or cause probe() failure */
@@ -162,6 +153,9 @@
 	struct usbatm_driver *driver;
 	void *driver_data;
 
+	/* heavy thread part */
+	struct task_struct *kthread;
+
 	/* USB device part */
 	struct usb_device *usb_dev;
 	struct usb_interface *usb_intf;

Index: usbatm2.c
===================================================================
RCS file: /home/cvs/speedtch/usbatm2.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- usbatm2.c	24 Jan 2005 09:44:42 -0000	1.7
+++ usbatm2.c	24 Jan 2005 10:47:08 -0000	1.8
@@ -68,6 +68,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
@@ -100,7 +101,7 @@
 #define DRIVER_VERSION	"1.9"
 #define DRIVER_DESC	"Generic USB ATM/DSL I/O, version " DRIVER_VERSION
 
-static const char driver_name[] = "usbatm";
+static const char usbatm_driver_name[] = "usbatm";
 
 #define UDSL_MAX_RCV_URBS		4
 #define UDSL_MAX_SND_URBS		4
@@ -1018,37 +1019,33 @@
 	struct usbatm_data *instance = arg;
 	int ret;
 
-	daemonize(instance->driver->driver_name);
-
 	ret = instance->driver->heavy_init(instance, instance->usb_intf);
 
 	if (!ret)
 		ret = usbatm_atm_init(instance);
 
-	module_put(instance->driver->owner);
 	udsl_put_instance(instance);	/* taken in usbatm_heavy_init */
 
 	return ret;
 }
 
-static int usbatm_heavy_init(struct usbatm_data *instance)
+static long usbatm_heavy_init(struct usbatm_data *instance)
 {
-	int ret;
-
-	udsl_get_instance(instance);	/* dropped below or in usbatm_do_heavy_init */
-	try_module_get(instance->driver->owner);
-
-	ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_FS | CLONE_FILES);
+	struct task_struct *kthread;
 
-	if (ret >= 0)
-		return 0;	/* OK */
+	kthread = kthread_create(usbatm_do_heavy_init, instance, "%s/%s", usbatm_driver_name, instance->driver->driver_name);
 
-	dbg("usbatm_heavy_init: kernel_thread failed (%d)!", ret);
+	if (IS_ERR(kthread)) {
+		dbg("usbatm_heavy_init: kernel_thread failed (%ld)!", PTR_ERR(kthread));
+		return PTR_ERR(kthread);
+	}
 
-	module_put(instance->driver->owner);
-	udsl_put_instance(instance);	/* taken above */
+	instance->kthread = kthread;
+	udsl_get_instance(instance);	/* dropped in usbatm_do_heavy_init */
+	mb();
+	wake_up_process(kthread);
 
-	return ret;
+	return 0;
 }
 
 static int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
@@ -1064,7 +1061,7 @@
 	dev_dbg(&intf->dev, "trying device with vendor=0x%x, product=0x%x, ifnum %d\n", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
 
 	if (!driver) {
-		dev_dbg(&intf->dev, "blacklisted by %s\n", driver_name);
+		dev_dbg(&intf->dev, "blacklisted by %s\n", usbatm_driver_name);
 		return -ENODEV;
 	}
 
@@ -1196,11 +1193,14 @@
 	else
 		error = usbatm_atm_init(instance);
 
-	if (!error) {
-		usb_get_dev(dev);
-		udsl_get_instance(instance);	/* dropped in usbatm_disconnect */
-		return 0;
-	}
+	if (error)
+		goto fail;
+
+	usb_get_dev(dev);
+	udsl_get_instance(instance);	/* dropped in usbatm_disconnect */
+	usb_set_intfdata(intf, instance);
+
+	return 0;
 
  fail:
 	for (i = 0; i < num_snd_bufs; i++)
@@ -1241,6 +1241,9 @@
 	if (instance->atm_dev && instance->driver->atm_stop)
 		instance->driver->atm_stop(instance, instance->atm_dev);
 
+	if (instance->kthread)
+		kthread_stop(instance->kthread);
+
 	if (instance->driver->unbind)
 		instance->driver->unbind(instance, intf);
 




More information about the Usbatm-commits mailing list