1 /******************************************************************************
2 * speedtch.c - Alcatel SpeedTouch USB xDSL modem driver
4 * Copyright (C) 2001, Alcatel
5 * Copyright (C) 2003, Duncan Sands
6 * Copyright (C) 2004, David Woodhouse
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 ******************************************************************************/
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/gfp.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/timer.h>
30 #include <linux/errno.h>
31 #include <linux/proc_fs.h>
32 #include <linux/slab.h>
33 #include <linux/wait.h>
34 #include <linux/list.h>
35 #include <asm/processor.h>
36 #include <asm/uaccess.h>
37 #include <linux/smp_lock.h>
38 #include <linux/interrupt.h>
39 #include <linux/atm.h>
40 #include <linux/atmdev.h>
41 #include <linux/crc32.h>
42 #include <linux/init.h>
43 #include <linux/firmware.h>
52 #if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
56 #include <linux/usb.h>
58 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
59 # define USE_FW_LOADER
63 static int udsl_print_packet(const unsigned char *data, int len);
64 #define PACKETDEBUG(arg...) udsl_print_packet (arg)
65 #define vdbg(arg...) dbg (arg)
67 #define PACKETDEBUG(arg...)
71 #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
72 #define DRIVER_VERSION "1.8"
73 #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION
75 static const char speedtch_driver_name[] = "speedtch";
77 #define SPEEDTOUCH_VENDORID 0x06b9
78 #define SPEEDTOUCH_PRODUCTID 0x4061
80 /* Timeout in jiffies */
81 #define CTRL_TIMEOUT (2*HZ)
82 #define DATA_TIMEOUT (2*HZ)
84 #define OFFSET_7 0 /* size 1 */
85 #define OFFSET_b 1 /* size 8 */
86 #define OFFSET_d 9 /* size 4 */
87 #define OFFSET_e 13 /* size 1 */
88 #define OFFSET_f 14 /* size 1 */
97 static int dl_512_first = 0;
98 static int sw_buffering = 0;
100 module_param(dl_512_first, bool, 0444);
101 MODULE_PARM_DESC(dl_512_first, "Read 512 bytes before sending firmware");
103 module_param(sw_buffering, uint, 0444);
104 MODULE_PARM_DESC(sw_buffering, "Enable software buffering");
106 #define UDSL_IOCTL_LINE_UP 1
107 #define UDSL_IOCTL_LINE_DOWN 2
109 #define SPEEDTCH_ENDPOINT_INT 0x81
110 #define SPEEDTCH_ENDPOINT_DATA 0x07
111 #define SPEEDTCH_ENDPOINT_FIRMWARE 0x05
113 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
115 static struct usb_device_id speedtch_usb_ids[] = {
116 {USB_DEVICE(SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)},
120 MODULE_DEVICE_TABLE(usb, speedtch_usb_ids);
122 struct speedtch_instance_data {
123 struct udsl_instance_data u;
127 unsigned char int_data[16];
128 struct work_struct poll_work;
129 struct timer_list poll_timer;
133 static int speedtch_usb_probe(struct usb_interface *intf,
134 const struct usb_device_id *id);
135 static void speedtch_usb_disconnect(struct usb_interface *intf);
136 static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
138 static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs);
139 static void speedtch_poll_status(struct speedtch_instance_data *instance);
141 static struct usb_driver speedtch_usb_driver = {
142 .owner = THIS_MODULE,
143 .name = speedtch_driver_name,
144 .probe = speedtch_usb_probe,
145 .disconnect = speedtch_usb_disconnect,
146 .ioctl = speedtch_usb_ioctl,
147 .id_table = speedtch_usb_ids,
154 static void speedtch_got_firmware(struct speedtch_instance_data *instance,
158 struct usb_interface *intf;
160 down(&instance->u.serialize); /* vs self, speedtch_firmware_start */
161 if (instance->u.status == UDSL_LOADED_FIRMWARE)
164 instance->u.status = UDSL_NO_FIRMWARE;
167 if ((err = usb_set_interface(instance->u.usb_dev, 1, 1)) < 0) {
168 dbg("speedtch_got_firmware: usb_set_interface returned %d!", err);
169 instance->u.status = UDSL_NO_FIRMWARE;
173 /* Set up interrupt endpoint */
174 intf = usb_ifnum_to_if(instance->u.usb_dev, 0);
175 if (intf && !usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) {
177 instance->int_urb = usb_alloc_urb(0, GFP_KERNEL);
178 if (instance->int_urb) {
180 usb_fill_int_urb(instance->int_urb, instance->u.usb_dev,
181 usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT),
183 sizeof(instance->int_data),
184 speedtch_handle_int, instance, 50);
185 err = usb_submit_urb(instance->int_urb, GFP_KERNEL);
187 /* Doesn't matter; we'll poll anyway */
188 dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err);
189 usb_free_urb(instance->int_urb);
190 instance->int_urb = NULL;
191 usb_driver_release_interface(&speedtch_usb_driver, intf);
195 /* Start status polling */
196 mod_timer(&instance->poll_timer, jiffies + (1 * HZ));
198 instance->u.status = UDSL_LOADED_FIRMWARE;
199 tasklet_schedule(&instance->u.receive_tasklet);
201 up(&instance->u.serialize);
202 wake_up_interruptible(&instance->u.firmware_waiters);
205 static int speedtch_set_swbuff(struct speedtch_instance_data *instance,
208 struct usb_device *dev = instance->u.usb_dev;
211 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
212 0x32, 0x40, state ? 0x01 : 0x00,
215 printk("Warning: %sabling SW buffering: usb_control_msg returned %d\n",
216 state ? "En" : "Dis", ret);
220 dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis");
224 static void speedtch_test_sequence(struct speedtch_instance_data *instance)
226 struct usb_device *dev = instance->u.usb_dev;
227 unsigned char buf[10];
233 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
234 0x01, 0x40, 0x0b, 0x00, buf, 2, 100);
236 printk(KERN_WARNING "%s failed on URB147: %d\n", __func__, ret);
241 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
242 0x01, 0x40, 0x02, 0x00, buf, 2, 100);
244 printk(KERN_WARNING "%s failed on URB148: %d\n", __func__, ret);
250 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
251 0x01, 0x40, 0x03, 0x00, buf, 3, 100);
253 printk(KERN_WARNING "%s failed on URB149: %d\n", __func__, ret);
259 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
260 0x01, 0x40, 0x04, 0x00, buf, 3, 100);
262 printk(KERN_WARNING "%s failed on URB150: %d\n", __func__, ret);
265 static int speedtch_start_synchro(struct speedtch_instance_data *instance)
267 struct usb_device *dev = instance->u.usb_dev;
268 unsigned char buf[2];
271 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
272 0x12, 0xc0, 0x04, 0x00,
273 buf, sizeof(buf), CTRL_TIMEOUT);
275 printk(KERN_WARNING "SpeedTouch: Failed to start ADSL synchronisation: %d\n", ret);
279 dbg("speedtch_start_synchro: modem prodded. %d Bytes returned: %02x %02x", ret, buf[0], buf[1]);
283 static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs)
285 struct speedtch_instance_data *instance = urb->context;
286 unsigned int count = urb->actual_length;
289 /* The magic interrupt for "up state" */
290 const static unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 };
291 /* The magic interrupt for "down state" */
292 const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 };
294 switch (urb->status) {
301 /* this urb is terminated; clean up */
302 dbg("%s - urb shutting down with status: %d", __func__, urb->status);
305 dbg("%s - nonzero urb status received: %d", __func__, urb->status);
310 dbg("%s - int packet too short", __func__);
314 if (!memcmp(up_int, instance->int_data, 6)) {
315 del_timer(&instance->poll_timer);
316 printk(KERN_NOTICE "DSL line goes up\n");
317 } else if (!memcmp(down_int, instance->int_data, 6)) {
318 printk(KERN_NOTICE "DSL line goes down\n");
322 printk(KERN_DEBUG "Unknown interrupt packet of %d bytes:", count);
323 for (i = 0; i < count; i++)
324 printk(" %02x", instance->int_data[i]);
327 schedule_work(&instance->poll_work);
331 if (!instance->int_urb)
334 ret = usb_submit_urb(urb, GFP_ATOMIC);
336 err("%s - usb_submit_urb failed with result %d", __func__, ret);
339 static int speedtch_get_status(struct speedtch_instance_data *instance,
342 struct usb_device *dev = instance->u.usb_dev;
345 memset(buf, 0, TOTAL);
347 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
348 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7,
355 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
356 0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b,
363 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
364 0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d,
371 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
372 0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e,
379 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
380 0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f,
390 static void speedtch_poll_status(struct speedtch_instance_data *instance)
392 unsigned char buf[TOTAL];
395 ret = speedtch_get_status(instance, buf);
398 "SpeedTouch: Error %d fetching device status\n", ret);
402 dbg("Line state %02x", buf[OFFSET_7]);
404 switch (buf[OFFSET_7]) {
406 if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
407 instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
408 printk(KERN_NOTICE "ADSL line is down\n");
413 if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
414 instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
415 printk(KERN_NOTICE "ADSL line is blocked?\n");
420 if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
421 instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
422 printk(KERN_NOTICE "ADSL line is synchronising\n");
427 if (instance->u.atm_dev->signal != ATM_PHY_SIG_FOUND) {
428 int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
429 | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24);
430 int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
431 | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24);
433 if (!(down_speed & 0x0000ffff) &&
434 !(up_speed & 0x0000ffff)) {
438 instance->u.atm_dev->link_rate = down_speed * 1000 / 424;
439 instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
442 "ADSL line is up (%d Kib/s down | %d Kib/s up)\n",
443 down_speed, up_speed);
448 if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
449 instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
450 printk(KERN_NOTICE "Unknown line state %02x\n", buf[OFFSET_7]);
456 static void speedtch_timer_poll(unsigned long data)
458 struct speedtch_instance_data *instance = (void *)data;
460 schedule_work(&instance->poll_work);
461 mod_timer(&instance->poll_timer, jiffies + (5 * HZ));
465 static void speedtch_upload_firmware(struct speedtch_instance_data *instance,
466 const struct firmware *fw1,
467 const struct firmware *fw2)
469 unsigned char *buffer;
470 struct usb_device *usb_dev = instance->u.usb_dev;
471 struct usb_interface *intf;
472 int actual_length, ret;
475 dbg("speedtch_upload_firmware");
477 if (!(intf = usb_ifnum_to_if(usb_dev, 2))) {
478 dbg("speedtch_upload_firmware: interface not found!");
482 if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) {
483 dbg("speedtch_upload_firmware: no memory for buffer!");
487 /* A user-space firmware loader may already have claimed interface #2 */
489 usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) < 0) {
490 dbg("speedtch_upload_firmware: interface in use (%d)!", ret);
495 if (dl_512_first) { /* some modems need a read before writing the firmware */
496 ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
497 buffer, 0x200, &actual_length, 2 * HZ);
499 if (ret < 0 && ret != -ETIMEDOUT)
500 dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret);
502 dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret);
505 /* URB 8 : both leds are static green */
506 for (offset = 0; offset < fw1->size; offset += PAGE_SIZE) {
507 int thislen = min_t(int, PAGE_SIZE, fw1->size - offset);
508 memcpy(buffer, fw1->data + offset, thislen);
510 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
511 buffer, thislen, &actual_length, DATA_TIMEOUT);
514 dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret);
517 dbg("speedtch_upload_firmware: BLOCK1 uploaded (%d bytes)", fw1->size);
520 /* USB led blinking green, ADSL led off */
523 ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
524 buffer, 0x200, &actual_length, DATA_TIMEOUT);
527 dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret);
530 dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length);
532 /* URBs 12 to 139 - USB led blinking green, ADSL led off */
533 for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) {
534 int thislen = min_t(int, PAGE_SIZE, fw2->size - offset);
535 memcpy(buffer, fw2->data + offset, thislen);
537 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
538 buffer, thislen, &actual_length, DATA_TIMEOUT);
541 dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret);
545 dbg("speedtch_upload_firmware: BLOCK3 uploaded (%d bytes)", fw2->size);
547 /* USB led static green, ADSL led static red */
550 ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
551 buffer, 0x200, &actual_length, DATA_TIMEOUT);
554 dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret);
559 dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length);
561 /* Delay to allow firmware to start up. We can do this here
562 because we're in our own kernel thread anyway. */
565 /* Enable software buffering, if requested */
567 speedtch_set_swbuff(instance, 1);
569 /* Magic spell; don't ask us what this does */
570 speedtch_test_sequence(instance);
572 /* Start modem synchronisation */
573 if (speedtch_start_synchro(instance))
574 dbg("speedtch_start_synchro: failed");
576 speedtch_got_firmware(instance, 1);
578 free_page((unsigned long)buffer);
582 /* Only release interface #2 if uploading failed; we don't release it
583 we succeeded. This prevents the userspace tools from trying to load
584 the firmware themselves */
585 usb_driver_release_interface(&speedtch_usb_driver, intf);
587 free_page((unsigned long)buffer);
589 speedtch_got_firmware(instance, 0);
592 static int speedtch_find_firmware(struct speedtch_instance_data
593 *instance, int phase,
594 const struct firmware **fw_p)
597 const u16 bcdDevice = instance->u.usb_dev->descriptor.bcdDevice;
598 const u8 major_revision = bcdDevice >> 8;
599 const u8 minor_revision = bcdDevice & 0xff;
601 sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision);
602 dbg("speedtch_find_firmware: looking for %s", buf);
604 if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
605 sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision);
606 dbg("speedtch_find_firmware: looking for %s", buf);
608 if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
609 sprintf(buf, "speedtch-%d.bin", phase);
610 dbg("speedtch_find_firmware: looking for %s", buf);
612 if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
613 dev_warn(&instance->u.usb_dev->dev, "no stage %d firmware found!", phase);
619 dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf);
624 static int speedtch_load_firmware(void *arg)
626 const struct firmware *fw1, *fw2;
627 struct speedtch_instance_data *instance = arg;
631 daemonize("firmware/speedtch");
633 if (!speedtch_find_firmware(instance, 1, &fw1)) {
634 if (!speedtch_find_firmware(instance, 2, &fw2)) {
635 speedtch_upload_firmware(instance, fw1, fw2);
636 release_firmware(fw2);
638 release_firmware(fw1);
641 /* In case we failed, set state back to NO_FIRMWARE so that
642 another later attempt may work. Otherwise, we never actually
643 manage to recover if, for example, the firmware is on /usr and
644 we look for it too early. */
645 speedtch_got_firmware(instance, 0);
647 module_put(THIS_MODULE);
648 udsl_put_instance(&instance->u);
651 #endif /* USE_FW_LOADER */
653 static void speedtch_firmware_start(struct speedtch_instance_data *instance)
659 dbg("speedtch_firmware_start");
661 down(&instance->u.serialize); /* vs self, speedtch_got_firmware */
663 if (instance->u.status >= UDSL_LOADING_FIRMWARE) {
664 up(&instance->u.serialize);
668 instance->u.status = UDSL_LOADING_FIRMWARE;
669 up(&instance->u.serialize);
672 udsl_get_instance(&instance->u);
673 try_module_get(THIS_MODULE);
675 ret = kernel_thread(speedtch_load_firmware, instance,
676 CLONE_FS | CLONE_FILES);
681 dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret);
683 module_put(THIS_MODULE);
684 udsl_put_instance(&instance->u);
685 /* Just pretend it never happened... hope modem_run happens */
686 #endif /* USE_FW_LOADER */
688 speedtch_got_firmware(instance, 0);
691 static int speedtch_firmware_wait(struct udsl_instance_data *instance)
693 speedtch_firmware_start((void *)instance);
695 if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0)
698 return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN;
705 static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
708 struct speedtch_instance_data *instance = usb_get_intfdata(intf);
710 dbg("speedtch_usb_ioctl entered");
713 dbg("speedtch_usb_ioctl: NULL instance!");
718 case UDSL_IOCTL_LINE_UP:
719 instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
720 speedtch_got_firmware(instance, 1);
721 return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO;
722 case UDSL_IOCTL_LINE_DOWN:
723 instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
730 static int speedtch_usb_probe(struct usb_interface *intf,
731 const struct usb_device_id *id)
733 struct usb_device *dev = interface_to_usbdev(intf);
734 int ifnum = intf->altsetting->desc.bInterfaceNumber;
735 struct speedtch_instance_data *instance;
736 unsigned char mac_str[13];
740 dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
742 if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
743 (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
744 (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
747 dbg("speedtch_usb_probe: device accepted");
750 instance = kmalloc(sizeof(*instance), GFP_KERNEL);
752 dbg("speedtch_usb_probe: no memory for instance data!");
756 memset(instance, 0, sizeof(struct speedtch_instance_data));
758 if ((ret = usb_set_interface(dev, 0, 0)) < 0)
761 if ((ret = usb_set_interface(dev, 2, 0)) < 0)
764 instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA;
765 instance->u.firmware_wait = speedtch_firmware_wait;
766 instance->u.driver_name = speedtch_driver_name;
768 ret = udsl_instance_setup(dev, &instance->u);
772 init_timer(&instance->poll_timer);
773 instance->poll_timer.function = speedtch_timer_poll;
774 instance->poll_timer.data = (unsigned long)instance;
776 INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance);
778 /* set MAC address, it is stored in the serial number */
779 memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi));
780 if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
781 for (i = 0; i < 6; i++)
782 instance->u.atm_dev->esi[i] =
783 (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1]));
786 /* First check whether the modem already seems to be alive */
787 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
788 0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, HZ / 2);
791 dbg("firmware appears to be already loaded");
792 speedtch_got_firmware(instance, 1);
793 speedtch_poll_status(instance);
795 speedtch_firmware_start(instance);
798 usb_set_intfdata(intf, instance);
808 static void speedtch_usb_disconnect(struct usb_interface *intf)
810 struct speedtch_instance_data *instance = usb_get_intfdata(intf);
812 dbg("speedtch_usb_disconnect entered");
815 dbg("speedtch_usb_disconnect: NULL instance!");
819 /*QQ need to handle disconnects on interface #2 while uploading firmware */
820 /*QQ and what about interface #1? */
822 if (instance->int_urb) {
823 struct urb *int_urb = instance->int_urb;
824 instance->int_urb = NULL;
826 usb_unlink_urb(int_urb);
827 usb_free_urb(int_urb);
830 instance->int_data[0] = 1;
831 del_timer_sync(&instance->poll_timer);
833 flush_scheduled_work();
835 udsl_instance_disconnect(&instance->u);
838 usb_set_intfdata(intf, NULL);
839 udsl_put_instance(&instance->u);
846 static int __init speedtch_usb_init(void)
848 dbg("speedtch_usb_init: driver version " DRIVER_VERSION);
850 return usb_register(&speedtch_usb_driver);
853 static void __exit speedtch_usb_cleanup(void)
855 dbg("speedtch_usb_cleanup entered");
857 usb_deregister(&speedtch_usb_driver);
860 module_init(speedtch_usb_init);
861 module_exit(speedtch_usb_cleanup);
863 MODULE_AUTHOR(DRIVER_AUTHOR);
864 MODULE_DESCRIPTION(DRIVER_DESC);
865 MODULE_LICENSE("GPL");
866 MODULE_VERSION(DRIVER_VERSION);