speedtch cxacru2.h, 1.1, 1.2 speedtch2.c, 1.2, 1.3 speedtch2.h, 1.1, 1.2 usbatm2.c, 1.2, 1.3

Duncan Sands duncan at infradead.org
Fri Jan 21 04:50:35 EST 2005


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

Modified Files:
	cxacru2.h speedtch2.c speedtch2.h usbatm2.c 
Log Message:
Added generic support for "heavy initialization", i.e. firmware loading in a kernel thread.


Index: cxacru2.h
===================================================================
RCS file: /home/cvs/speedtch/cxacru2.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cxacru2.h	20 Jan 2005 16:04:20 -0000	1.1
+++ cxacru2.h	21 Jan 2005 09:50:31 -0000	1.2
@@ -27,7 +27,7 @@
 #include "usbatm.h"
 
 static const struct usbatm_driver cxacru_driver = {
-	.driver_name = "Conexant AccessRunner",
+	.driver_name = "cxacru"
 };
 
 #endif	/* _CXACRU_H_ */

Index: speedtch2.c
===================================================================
RCS file: /home/cvs/speedtch/speedtch2.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- speedtch2.c	20 Jan 2005 21:58:06 -0000	1.2
+++ speedtch2.c	21 Jan 2005 09:50:31 -0000	1.3
@@ -87,13 +87,12 @@
 #define UDSL_IOCTL_LINE_DOWN		2
 
 #define SPEEDTCH_ENDPOINT_INT		0x81
-#define SPEEDTCH_ENDPOINT_DATA		0x07
 #define SPEEDTCH_ENDPOINT_FIRMWARE	0x05
 
 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
 
 struct speedtch_instance_data {
-	struct usbatm_data u;
+	struct usbatm_data usbatm;
 
 	/* Status */
 	struct urb *int_urb;
@@ -104,81 +103,78 @@
 
 /* USB */
 
-static int speedtch_usb_probe(struct usb_interface *intf,
-			      const struct usb_device_id *id);
-static void speedtch_usb_disconnect(struct usb_interface *intf);
-static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
-			      void *user_data);
+static int speedtch_firmware_probe(struct usb_interface *intf, const struct usb_device_id *id);
+//QQstatic void speedtch_usb_disconnect(struct usb_interface *intf);
+static void speedtch_firmware_disconnect(struct usb_interface *intf);
 static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs);
 static void speedtch_poll_status(struct speedtch_instance_data *instance);
 
-static struct usb_driver speedtch_usb_driver = {
-	.owner		= THIS_MODULE,
-	.name		= speedtch_driver_name,
-	.probe		= speedtch_usb_probe,
-	.disconnect	= speedtch_usb_disconnect,
-	.ioctl		= speedtch_usb_ioctl
+struct usb_driver speedtch_firmware_driver = {
+        .owner =        THIS_MODULE,
+        .name =         "speedtch_firmware",
+        .probe =        speedtch_firmware_probe,
+        .disconnect =   speedtch_firmware_disconnect,
 };
 
 /***************
 **  firmware  **
 ***************/
 
-static void speedtch_got_firmware(struct speedtch_instance_data *instance,
-				  int got_it)
-{
-	int err;
-	struct usb_interface *intf;
-
-	down(&instance->u.serialize);	/* vs self, speedtch_firmware_start */
-	if (instance->u.status == UDSL_LOADED_FIRMWARE)
-		goto out;
-	if (!got_it) {
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
-	if ((err = usb_set_interface(instance->u.usb_dev, 1, 1)) < 0) {
-		dbg("speedtch_got_firmware: usb_set_interface returned %d!", err);
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
-
-	/* Set up interrupt endpoint */
-	intf = usb_ifnum_to_if(instance->u.usb_dev, 0);
-	if (intf && !usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) {
-
-		instance->int_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (instance->int_urb) {
-
-			usb_fill_int_urb(instance->int_urb, instance->u.usb_dev,
-					 usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT),
-					 instance->int_data,
-					 sizeof(instance->int_data),
-					 speedtch_handle_int, instance, 50);
-			err = usb_submit_urb(instance->int_urb, GFP_KERNEL);
-			if (err) {
-				/* Doesn't matter; we'll poll anyway */
-				dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err);
-				usb_free_urb(instance->int_urb);
-				instance->int_urb = NULL;
-				usb_driver_release_interface(&speedtch_usb_driver, intf);
-			}
-		}
-	}
-	/* Start status polling */
-	mod_timer(&instance->poll_timer, jiffies + (1 * HZ));
-
-	instance->u.status = UDSL_LOADED_FIRMWARE;
-	tasklet_schedule(&instance->u.receive_tasklet);
- out:
-	up(&instance->u.serialize);
-	wake_up_interruptible(&instance->u.firmware_waiters);
-}
+//QQstatic void speedtch_got_firmware(struct speedtch_instance_data *instance,
+//QQ				  int got_it)
+//QQ{
+//QQ	int err;
+//QQ	struct usb_interface *intf;
+//QQ
+//QQ	down(&instance->u.serialize);	/* vs self, speedtch_firmware_start */
+//QQ	if (instance->u.status == UDSL_LOADED_FIRMWARE)
+//QQ		goto out;
+//QQ	if (!got_it) {
+//QQ		instance->u.status = UDSL_NO_FIRMWARE;
+//QQ		goto out;
+//QQ	}
+//QQ	if ((err = usb_set_interface(instance->u.usb_dev, 1, 1)) < 0) {
+//QQ		dbg("speedtch_got_firmware: usb_set_interface returned %d!", err);
+//QQ		instance->u.status = UDSL_NO_FIRMWARE;
+//QQ		goto out;
+//QQ	}
+//QQ
+//QQ	/* Set up interrupt endpoint */
+//QQ	intf = usb_ifnum_to_if(instance->u.usb_dev, 0);
+//QQ	if (intf && !usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) {
+//QQ
+//QQ		instance->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+//QQ		if (instance->int_urb) {
+//QQ
+//QQ			usb_fill_int_urb(instance->int_urb, instance->u.usb_dev,
+//QQ					 usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT),
+//QQ					 instance->int_data,
+//QQ					 sizeof(instance->int_data),
+//QQ					 speedtch_handle_int, instance, 50);
+//QQ			err = usb_submit_urb(instance->int_urb, GFP_KERNEL);
+//QQ			if (err) {
+//QQ				/* Doesn't matter; we'll poll anyway */
+//QQ				dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err);
+//QQ				usb_free_urb(instance->int_urb);
+//QQ				instance->int_urb = NULL;
+//QQ				usb_driver_release_interface(&speedtch_usb_driver, intf);
+//QQ			}
+//QQ		}
+//QQ	}
+//QQ	/* Start status polling */
+//QQ	mod_timer(&instance->poll_timer, jiffies + (1 * HZ));
+//QQ
+//QQ	instance->u.status = UDSL_LOADED_FIRMWARE;
+//QQ	tasklet_schedule(&instance->u.receive_tasklet);
+//QQ out:
+//QQ	up(&instance->u.serialize);
+//QQ	wake_up_interruptible(&instance->u.firmware_waiters);
+//QQ}
 
 static int speedtch_set_swbuff(struct speedtch_instance_data *instance,
 			       int state)
 {
-	struct usb_device *dev = instance->u.usb_dev;
+	struct usb_device *dev = instance->usbatm.usb_dev;
 	int ret;
 
 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -196,7 +192,7 @@
 
 static void speedtch_test_sequence(struct speedtch_instance_data *instance)
 {
-	struct usb_device *dev = instance->u.usb_dev;
+	struct usb_device *dev = instance->usbatm.usb_dev;
 	unsigned char buf[10];
 	int ret;
 
@@ -237,7 +233,7 @@
 
 static int speedtch_start_synchro(struct speedtch_instance_data *instance)
 {
-	struct usb_device *dev = instance->u.usb_dev;
+	struct usb_device *dev = instance->usbatm.usb_dev;
 	unsigned char buf[2];
 	int ret;
 
@@ -312,7 +308,7 @@
 static int speedtch_get_status(struct speedtch_instance_data *instance,
 			       unsigned char *buf)
 {
-	struct usb_device *dev = instance->u.usb_dev;
+	struct usb_device *dev = instance->usbatm.usb_dev;
 	int ret;
 
 	memset(buf, 0, TOTAL);
@@ -376,28 +372,28 @@
 
 	switch (buf[OFFSET_7]) {
 	case 0:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
+		if (instance->usbatm.atm_dev->signal != ATM_PHY_SIG_LOST) {
+			instance->usbatm.atm_dev->signal = ATM_PHY_SIG_LOST;
 			printk(KERN_NOTICE "ADSL line is down\n");
 		}
 		break;
 
 	case 0x08:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+		if (instance->usbatm.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
+			instance->usbatm.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
 			printk(KERN_NOTICE "ADSL line is blocked?\n");
 		}
 		break;
 
 	case 0x10:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
+		if (instance->usbatm.atm_dev->signal != ATM_PHY_SIG_LOST) {
+			instance->usbatm.atm_dev->signal = ATM_PHY_SIG_LOST;
 			printk(KERN_NOTICE "ADSL line is synchronising\n");
 		}
 		break;
 
 	case 0x20:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_FOUND) {
+		if (instance->usbatm.atm_dev->signal != ATM_PHY_SIG_FOUND) {
 			int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
 				| (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24);
 			int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
@@ -408,8 +404,8 @@
 				down_speed >>= 16;
 				up_speed >>= 16;
 			}
-			instance->u.atm_dev->link_rate = down_speed * 1000 / 424;
-			instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
+			instance->usbatm.atm_dev->link_rate = down_speed * 1000 / 424;
+			instance->usbatm.atm_dev->signal = ATM_PHY_SIG_FOUND;
 
 			printk(KERN_NOTICE
 			       "ADSL line is up (%d Kib/s down | %d Kib/s up)\n",
@@ -418,8 +414,8 @@
 		break;
 
 	default:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+		if (instance->usbatm.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
+			instance->usbatm.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
 			printk(KERN_NOTICE "Unknown line state %02x\n", buf[OFFSET_7]);
 		}
 		break;
@@ -435,32 +431,34 @@
 }
 
 #ifdef USE_FW_LOADER
-static void speedtch_upload_firmware(struct speedtch_instance_data *instance,
+static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
 				     const struct firmware *fw1,
 				     const struct firmware *fw2)
 {
 	unsigned char *buffer;
-	struct usb_device *usb_dev = instance->u.usb_dev;
+	struct usb_device *usb_dev = instance->usbatm.usb_dev;
 	struct usb_interface *intf;
-	int actual_length, ret;
+	int actual_length;
+	int ret;
 	int offset;
 
 	dbg("speedtch_upload_firmware");
 
 	if (!(intf = usb_ifnum_to_if(usb_dev, 2))) {
 		dbg("speedtch_upload_firmware: interface not found!");
-		goto fail;
+		return -ENODEV;
 	}
 
 	if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) {
 		dbg("speedtch_upload_firmware: no memory for buffer!");
-		goto fail;
+		return -ENOMEM;
 	}
 
 	/* A user-space firmware loader may already have claimed interface #2 */
 	if ((ret =
-	     usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) < 0) {
+	     usb_driver_claim_interface(&speedtch_firmware_driver, intf, NULL)) < 0) {
 		dbg("speedtch_upload_firmware: interface in use (%d)!", ret);
+		ret = -EBUSY;
 		goto fail_free;
 	}
 
@@ -546,20 +544,19 @@
 	if (speedtch_start_synchro(instance))
 		dbg("speedtch_start_synchro: failed");
 
-	speedtch_got_firmware(instance, 1);
+//QQ	speedtch_got_firmware(instance, 1);
 
 	free_page((unsigned long)buffer);
-	return;
+	return 0;
 
  fail_release:
-	/* Only release interface #2 if uploading failed; we don't release it
+	/* Only release interface #2 if uploading failed; we don't release it if
 	   we succeeded.  This prevents the userspace tools from trying to load
 	   the firmware themselves */
-	usb_driver_release_interface(&speedtch_usb_driver, intf);
+	usb_driver_release_interface(&speedtch_firmware_driver, intf);
  fail_free:
 	free_page((unsigned long)buffer);
- fail:
-	speedtch_got_firmware(instance, 0);
+	return ret;
 }
 
 static int speedtch_find_firmware(struct speedtch_instance_data
@@ -567,162 +564,88 @@
 				  const struct firmware **fw_p)
 {
 	char buf[24];
-	const u16 bcdDevice = instance->u.usb_dev->descriptor.bcdDevice;
+	const u16 bcdDevice = instance->usbatm.usb_dev->descriptor.bcdDevice;
 	const u8 major_revision = bcdDevice >> 8;
 	const u8 minor_revision = bcdDevice & 0xff;
 
 	sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision);
 	dbg("speedtch_find_firmware: looking for %s", buf);
 
-	if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
+	if (request_firmware(fw_p, buf, &instance->usbatm.usb_dev->dev)) {
 		sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision);
 		dbg("speedtch_find_firmware: looking for %s", buf);
 
-		if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
+		if (request_firmware(fw_p, buf, &instance->usbatm.usb_dev->dev)) {
 			sprintf(buf, "speedtch-%d.bin", phase);
 			dbg("speedtch_find_firmware: looking for %s", buf);
 
-			if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
-				dev_warn(&instance->u.usb_dev->dev, "no stage %d firmware found!", phase);
+			if (request_firmware(fw_p, buf, &instance->usbatm.usb_dev->dev)) {
+				dev_warn(&instance->usbatm.usb_dev->dev, "no stage %d firmware found!", phase);
 				return -ENOENT;
 			}
 		}
 	}
 
-	dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf);
+	dev_info(&instance->usbatm.usb_dev->dev, "found stage %d firmware %s\n", phase, buf);
 
 	return 0;
 }
 
-static int speedtch_load_firmware(void *arg)
+int speedtch_load_firmware(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
 	const struct firmware *fw1, *fw2;
-	struct speedtch_instance_data *instance = arg;
+	struct speedtch_instance_data *instance = usbatm->driver_data;
+	int ret = -ENOENT;
 
 	BUG_ON(!instance);
 
-	daemonize("firmware/speedtch");
-
 	if (!speedtch_find_firmware(instance, 1, &fw1)) {
 		if (!speedtch_find_firmware(instance, 2, &fw2)) {
-			speedtch_upload_firmware(instance, fw1, fw2);
+			ret = speedtch_upload_firmware(instance, fw1, fw2);
 			release_firmware(fw2);
 		}
 		release_firmware(fw1);
 	}
 
-	/* In case we failed, set state back to NO_FIRMWARE so that
-	   another later attempt may work. Otherwise, we never actually
-	   manage to recover if, for example, the firmware is on /usr and
-	   we look for it too early. */
-	speedtch_got_firmware(instance, 0);
-
-	module_put(THIS_MODULE);
-	udsl_put_instance(&instance->u);
-	return 0;
+	return ret;
 }
-#endif /* USE_FW_LOADER */
 
-static void speedtch_firmware_start(struct speedtch_instance_data *instance)
+static int speedtch_firmware_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-#ifdef USE_FW_LOADER
-	int ret;
-#endif
-
-	dbg("speedtch_firmware_start");
-
-	down(&instance->u.serialize);	/* vs self, speedtch_got_firmware */
-
-	if (instance->u.status >= UDSL_LOADING_FIRMWARE) {
-		up(&instance->u.serialize);
-		return;
-	}
-
-	instance->u.status = UDSL_LOADING_FIRMWARE;
-	up(&instance->u.serialize);
-
-#ifdef USE_FW_LOADER
-	udsl_get_instance(&instance->u);
-	try_module_get(THIS_MODULE);
-
-	ret = kernel_thread(speedtch_load_firmware, instance,
-			    CLONE_FS | CLONE_FILES);
-
-	if (ret >= 0)
-		return;		/* OK */
-
-	dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret);
-
-	module_put(THIS_MODULE);
-	udsl_put_instance(&instance->u);
-	/* Just pretend it never happened... hope modem_run happens */
-#endif				/* USE_FW_LOADER */
-
-	speedtch_got_firmware(instance, 0);
+	return -ENODEV;
 }
 
-static int speedtch_firmware_wait(struct usbatm_data *instance)
+static void speedtch_firmware_disconnect(struct usb_interface *intf)
 {
-	speedtch_firmware_start((void *)instance);
+//QQ
+}
 
-	if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0)
-		return -ERESTARTSYS;
+#endif /* USE_FW_LOADER */
 
-	return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN;
-}
 
 /**********
 **  USB  **
 **********/
 
-static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
-			      void *user_data)
-{
-	struct speedtch_instance_data *instance = usb_get_intfdata(intf);
-
-	dbg("speedtch_usb_ioctl entered");
-
-	if (!instance) {
-		dbg("speedtch_usb_ioctl: NULL instance!");
-		return -ENODEV;
-	}
-
-	switch (code) {
-	case UDSL_IOCTL_LINE_UP:
-		instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
-		speedtch_got_firmware(instance, 1);
-		return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO;
-	case UDSL_IOCTL_LINE_DOWN:
-		instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
-		return 0;
-	default:
-		return -ENOTTY;
-	}
-}
-
-static int speedtch_usb_probe(struct usb_interface *intf,
-			      const struct usb_device_id *id)
+int speedtch_bind(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	int ifnum = intf->altsetting->desc.bInterfaceNumber;
 	struct speedtch_instance_data *instance;
-	unsigned char mac_str[13];
-	int ret, i;
-	char buf7[SIZE_7];
-
-	dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
-
-	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
-	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
-	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
+//QQ	unsigned char mac_str[13];
+//QQ	int i;
+	int ret;
+//QQ	char buf7[SIZE_7];
+
+	if (ifnum != 1)
 		return -ENODEV;
 
-	dbg("speedtch_usb_probe: device accepted");
+	dbg("speedtch_bind: device accepted");
 
 	/* instance init */
 	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
 	if (!instance) {
-		dbg("speedtch_usb_probe: no memory for instance data!");
+		dbg("speedtch_bind: no memory for instance data!");
 		return -ENOMEM;
 	}
 
@@ -734,41 +657,33 @@
 	if ((ret = usb_set_interface(dev, 2, 0)) < 0)
 		goto fail;
 
-	instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA;
-	instance->u.firmware_wait = speedtch_firmware_wait;
-	instance->u.driver_name = speedtch_driver_name;
-
-	ret = udsl_instance_setup(dev, &instance->u);
-	if (ret)
-		goto fail;
-
 	init_timer(&instance->poll_timer);
 	instance->poll_timer.function = speedtch_timer_poll;
 	instance->poll_timer.data = (unsigned long)instance;
 
 	INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance);
 
-	/* set MAC address, it is stored in the serial number */
-	memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi));
-	if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
-		for (i = 0; i < 6; i++)
-			instance->u.atm_dev->esi[i] =
-				(hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1]));
-	}
-
-	/* First check whether the modem already seems to be alive */
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, HZ / 2);
-
-	if (ret == SIZE_7) {
-		dbg("firmware appears to be already loaded");
-		speedtch_got_firmware(instance, 1);
-		speedtch_poll_status(instance);
-	} else {
-		speedtch_firmware_start(instance);
-	}
+//QQ	/* set MAC address, it is stored in the serial number */
+//QQ	memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi));
+//QQ	if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
+//QQ		for (i = 0; i < 6; i++)
+//QQ			instance->u.atm_dev->esi[i] =
+//QQ				(hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1]));
+//QQ	}
+//QQ
+//QQ	/* First check whether the modem already seems to be alive */
+//QQ	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+//QQ			      0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, HZ / 2);
+//QQ
+//QQ	if (ret == SIZE_7) {
+//QQ		dbg("firmware appears to be already loaded");
+//QQ		speedtch_got_firmware(instance, 1);
+//QQ		speedtch_poll_status(instance);
+//QQ	} else {
+//QQ		speedtch_firmware_start(instance);
+//QQ	}
 
-	usb_set_intfdata(intf, instance);
+	usbatm->driver_data = instance;
 
 	return 0;
 
@@ -778,33 +693,33 @@
 	return -ENOMEM;
 }
 
-static void speedtch_usb_disconnect(struct usb_interface *intf)
-{
-	struct speedtch_instance_data *instance = usb_get_intfdata(intf);
-
-	dbg("speedtch_usb_disconnect entered");
-
-	if (!instance) {
-		dbg("speedtch_usb_disconnect: NULL instance!");
-		return;
-	}
-
-	if (instance->int_urb) {
-		struct urb *int_urb = instance->int_urb;
-		instance->int_urb = NULL;
-		wmb();
-		usb_unlink_urb(int_urb);
-		usb_free_urb(int_urb);
-	}
-
-	instance->int_data[0] = 1;
-	del_timer_sync(&instance->poll_timer);
-	wmb();
-	flush_scheduled_work();
-
-	udsl_instance_disconnect(&instance->u);
-
-	/* clean up */
-	usb_set_intfdata(intf, NULL);
-	udsl_put_instance(&instance->u);
-}
+//QQstatic void speedtch_usb_disconnect(struct usb_interface *intf)
+//QQ{
+//QQ	struct speedtch_instance_data *instance = usb_get_intfdata(intf);
+//QQ
+//QQ	dbg("speedtch_usb_disconnect entered");
+//QQ
+//QQ	if (!instance) {
+//QQ		dbg("speedtch_usb_disconnect: NULL instance!");
+//QQ		return;
+//QQ	}
+//QQ
+//QQ	if (instance->int_urb) {
+//QQ		struct urb *int_urb = instance->int_urb;
+//QQ		instance->int_urb = NULL;
+//QQ		wmb();
+//QQ		usb_unlink_urb(int_urb);
+//QQ		usb_free_urb(int_urb);
+//QQ	}
+//QQ
+//QQ	instance->int_data[0] = 1;
+//QQ	del_timer_sync(&instance->poll_timer);
+//QQ	wmb();
+//QQ	flush_scheduled_work();
+//QQ
+//QQ	udsl_instance_disconnect(&instance->u);
+//QQ
+//QQ	/* clean up */
+//QQ	usb_set_intfdata(intf, NULL);
+//QQ	udsl_put_instance(&instance->u);
+//QQ}

Index: speedtch2.h
===================================================================
RCS file: /home/cvs/speedtch/speedtch2.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- speedtch2.h	20 Jan 2005 16:04:20 -0000	1.1
+++ speedtch2.h	21 Jan 2005 09:50:31 -0000	1.2
@@ -24,10 +24,19 @@
 #ifndef	_SPEEDTCH_H_
 #define	_SPEEDTCH_H_
 
+#include <linux/config.h>
 #include "usbatm.h"
 
+int speedtch_bind(struct usbatm_data *usbatm, struct usb_interface *intf);
+int speedtch_load_firmware(struct usbatm_data *usbatm, struct usb_interface *intf);
+
 static const struct usbatm_driver speedtch_driver = {
-	.driver_name = "SpeedTouch USB",
+	.driver_name = "speedtch",
+	.bind = speedtch_bind,
+#ifdef	CONFIG_FW_LOADER
+	.heavy_init = speedtch_load_firmware,
+#endif
+	.in = 7, .out = 7
 };
 
 #endif	/* _SPEEDTCH_H_ */

Index: usbatm2.c
===================================================================
RCS file: /home/cvs/speedtch/usbatm2.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- usbatm2.c	20 Jan 2005 21:58:06 -0000	1.2
+++ usbatm2.c	21 Jan 2005 09:50:31 -0000	1.3
@@ -87,16 +87,6 @@
 
 #include "usbatm.h"
 
-#ifdef	CONFIG_USB_SPEEDTOUCH
-#include "speedtch2.h"
-#define HAVE_HARDWARE
-#endif
-
-#ifdef	CONFIG_USB_CXACRU
-#include "cxacru2.h"
-#define HAVE_HARDWARE
-#endif
-
 #ifdef VERBOSE_DEBUG
 static int udsl_print_packet(const unsigned char *data, int len);
 #define PACKETDEBUG(arg...)	udsl_print_packet (arg)
@@ -979,7 +969,7 @@
 static int usbatm_atm_init(struct usbatm_data *instance)
 {
 	/* ATM init */
-	instance->atm_dev = atm_dev_register(instance->driver_name,
+	instance->atm_dev = atm_dev_register(instance->driver->driver_name,
 					     &udsl_atm_devops, -1, NULL);
 	if (!instance->atm_dev) {
 		dbg("usbatm_atm_init: failed to register ATM device!");
@@ -1005,9 +995,39 @@
 **  USB  **
 **********/
 
-static void usbatm_heavy_init(struct usbatm_data *instance)
+static int usbatm_do_heavy_init(void *arg)
+{
+	struct usbatm_data *instance = arg;
+	int ret;
+
+	daemonize(instance->driver->driver_name);
+
+	ret = instance->driver->heavy_init(instance, instance->usb_intf);
+
+	module_put(THIS_MODULE);
+	udsl_put_instance(instance);
+
+	return ret;
+}
+
+static int usbatm_heavy_init(struct usbatm_data *instance)
 {
-/* to be done later QQ */
+	int ret;
+
+	udsl_get_instance(instance);
+	try_module_get(THIS_MODULE);
+
+	ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_FS | CLONE_FILES);
+
+	if (ret >= 0)
+		return 0;	/* OK */
+
+	dbg("usbatm_heavy_init: kernel_thread failed (%d)!", ret);
+
+	module_put(THIS_MODULE);
+	udsl_put_instance(instance);
+
+	return ret;
 }
 
 static int usbatm_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
@@ -1036,13 +1056,14 @@
 	memset(instance, 0, sizeof(*instance));
 
 	kref_init(&instance->refcount);	/* one for USB */
-	udsl_get_instance(instance);	/* one for ATM */
+//QQset later	udsl_get_instance(instance);	/* one for ATM */
 
 	init_MUTEX(&instance->serialize);
 
 	instance->driver = driver;
 
 	instance->usb_dev = dev;
+	instance->usb_intf = intf;
 	instance->tx_endpoint = usb_sndbulkpipe(dev, driver->out);
 	instance->rx_endpoint = usb_rcvbulkpipe(dev, driver->in);
 	instance->tx_padding = driver->tx_padding;
@@ -1130,7 +1151,7 @@
 	length = sizeof(instance->description);
 
 	if ((i = usb_string(dev, dev->descriptor.iProduct, buf, length)) < 0)
-		goto finish;
+		goto bind;
 
 	buf += i;
 	length -= i;
@@ -1140,27 +1161,28 @@
 	length -= i;
 
 	if (length <= 0 || (i = usb_make_path(dev, buf, length)) < 0)
-		goto finish;
+		goto bind;
 
 	buf += i;
 	length -= i;
 
 	snprintf(buf, length, ")");
 
- finish:
+ bind:
 	if (driver->bind && (error = driver->bind(instance, intf)) < 0)
 			goto fail;
 
 	usb_get_dev(dev);
 
 	if (driver->heavy_init)
-		usbatm_heavy_init(instance);
-	else if ((error = usbatm_atm_init(instance)) < 0) {
-		usb_put_dev(dev);
-		goto fail;
-	}
+		error = usbatm_heavy_init(instance);
+	else
+		error = usbatm_atm_init(instance);
 
-	return 0;
+	if (!error)
+		return 0;
+
+	usb_put_dev(dev);
 
  fail:
 	for (i = 0; i < num_snd_bufs; i++)
@@ -1233,9 +1255,19 @@
 }
 
 
-/***********
-**  init  **
-***********/
+/*******************
+**  mini drivers  **
+*******************/
+
+#ifdef	CONFIG_USB_CXACRU
+#include "cxacru2.h"
+#define HAVE_HARDWARE
+#endif
+
+#ifdef	CONFIG_USB_SPEEDTOUCH
+#include "speedtch2.h"
+#define HAVE_HARDWARE
+#endif
 
 #ifndef HAVE_HARDWARE
 #error You need to configure some hardware for this driver
@@ -1296,11 +1328,16 @@
 
 MODULE_DEVICE_TABLE (usb, products);
 
+
+/***********
+**  init  **
+***********/
+
 static struct usb_driver usbatm_driver = {
         .owner          = THIS_MODULE,
         .name           = driver_name,
         .probe          = usbatm_usb_probe,
-        .disconnect     = usbatm_disconnect,
+//QQ        .disconnect     = usbatm_disconnect,
         .id_table       = products,
 };
 




More information about the Usbatm-commits mailing list