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>
47 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
48 # define USE_FW_LOADER
51 #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
52 #define DRIVER_VERSION "1.8"
53 #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION
55 static const char speedtch_driver_name
[] = "speedtch";
57 #define SPEEDTOUCH_VENDORID 0x06b9
58 #define SPEEDTOUCH_PRODUCTID 0x4061
60 /* Timeout in jiffies */
61 #define CTRL_TIMEOUT 2000
62 #define DATA_TIMEOUT 2000
64 #define OFFSET_7 0 /* size 1 */
65 #define OFFSET_b 1 /* size 8 */
66 #define OFFSET_d 9 /* size 4 */
67 #define OFFSET_e 13 /* size 1 */
68 #define OFFSET_f 14 /* size 1 */
77 static int dl_512_first
= 0;
78 static int sw_buffering
= 0;
80 module_param(dl_512_first
, bool, 0444);
81 MODULE_PARM_DESC(dl_512_first
, "Read 512 bytes before sending firmware");
83 module_param(sw_buffering
, uint
, 0444);
84 MODULE_PARM_DESC(sw_buffering
, "Enable software buffering");
86 #define UDSL_IOCTL_LINE_UP 1
87 #define UDSL_IOCTL_LINE_DOWN 2
89 #define SPEEDTCH_ENDPOINT_INT 0x81
90 #define SPEEDTCH_ENDPOINT_DATA 0x07
91 #define SPEEDTCH_ENDPOINT_FIRMWARE 0x05
93 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
95 static struct usb_device_id speedtch_usb_ids
[] = {
96 {USB_DEVICE(SPEEDTOUCH_VENDORID
, SPEEDTOUCH_PRODUCTID
)},
100 MODULE_DEVICE_TABLE(usb
, speedtch_usb_ids
);
102 struct speedtch_instance_data
{
103 struct udsl_instance_data u
;
107 unsigned char int_data
[16];
108 struct work_struct poll_work
;
109 struct timer_list poll_timer
;
113 static int speedtch_usb_probe(struct usb_interface
*intf
,
114 const struct usb_device_id
*id
);
115 static void speedtch_usb_disconnect(struct usb_interface
*intf
);
116 static int speedtch_usb_ioctl(struct usb_interface
*intf
, unsigned int code
,
118 static void speedtch_handle_int(struct urb
*urb
, struct pt_regs
*regs
);
119 static void speedtch_poll_status(struct speedtch_instance_data
*instance
);
121 static struct usb_driver speedtch_usb_driver
= {
122 .owner
= THIS_MODULE
,
123 .name
= speedtch_driver_name
,
124 .probe
= speedtch_usb_probe
,
125 .disconnect
= speedtch_usb_disconnect
,
126 .ioctl
= speedtch_usb_ioctl
,
127 .id_table
= speedtch_usb_ids
,
134 static void speedtch_got_firmware(struct speedtch_instance_data
*instance
,
138 struct usb_interface
*intf
;
140 down(&instance
->u
.serialize
); /* vs self, speedtch_firmware_start */
141 if (instance
->u
.status
== UDSL_LOADED_FIRMWARE
)
144 instance
->u
.status
= UDSL_NO_FIRMWARE
;
147 if ((err
= usb_set_interface(instance
->u
.usb_dev
, 1, 1)) < 0) {
148 dbg("speedtch_got_firmware: usb_set_interface returned %d!", err
);
149 instance
->u
.status
= UDSL_NO_FIRMWARE
;
153 /* Set up interrupt endpoint */
154 intf
= usb_ifnum_to_if(instance
->u
.usb_dev
, 0);
155 if (intf
&& !usb_driver_claim_interface(&speedtch_usb_driver
, intf
, NULL
)) {
157 instance
->int_urb
= usb_alloc_urb(0, GFP_KERNEL
);
158 if (instance
->int_urb
) {
160 usb_fill_int_urb(instance
->int_urb
, instance
->u
.usb_dev
,
161 usb_rcvintpipe(instance
->u
.usb_dev
, SPEEDTCH_ENDPOINT_INT
),
163 sizeof(instance
->int_data
),
164 speedtch_handle_int
, instance
, 50);
165 err
= usb_submit_urb(instance
->int_urb
, GFP_KERNEL
);
167 /* Doesn't matter; we'll poll anyway */
168 dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err
);
169 usb_free_urb(instance
->int_urb
);
170 instance
->int_urb
= NULL
;
171 usb_driver_release_interface(&speedtch_usb_driver
, intf
);
175 /* Start status polling */
176 mod_timer(&instance
->poll_timer
, jiffies
+ (1 * HZ
));
178 instance
->u
.status
= UDSL_LOADED_FIRMWARE
;
179 tasklet_schedule(&instance
->u
.receive_tasklet
);
181 up(&instance
->u
.serialize
);
182 wake_up_interruptible(&instance
->u
.firmware_waiters
);
185 static int speedtch_set_swbuff(struct speedtch_instance_data
*instance
,
188 struct usb_device
*dev
= instance
->u
.usb_dev
;
191 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
192 0x32, 0x40, state
? 0x01 : 0x00,
195 printk("Warning: %sabling SW buffering: usb_control_msg returned %d\n",
196 state
? "En" : "Dis", ret
);
200 dbg("speedtch_set_swbuff: %sbled SW buffering", state
? "En" : "Dis");
204 static void speedtch_test_sequence(struct speedtch_instance_data
*instance
)
206 struct usb_device
*dev
= instance
->u
.usb_dev
;
207 unsigned char buf
[10];
213 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
214 0x01, 0x40, 0x0b, 0x00, buf
, 2, 100);
216 printk(KERN_WARNING
"%s failed on URB147: %d\n", __func__
, ret
);
221 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
222 0x01, 0x40, 0x02, 0x00, buf
, 2, 100);
224 printk(KERN_WARNING
"%s failed on URB148: %d\n", __func__
, ret
);
230 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
231 0x01, 0x40, 0x03, 0x00, buf
, 3, 100);
233 printk(KERN_WARNING
"%s failed on URB149: %d\n", __func__
, ret
);
239 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
240 0x01, 0x40, 0x04, 0x00, buf
, 3, 100);
242 printk(KERN_WARNING
"%s failed on URB150: %d\n", __func__
, ret
);
245 static int speedtch_start_synchro(struct speedtch_instance_data
*instance
)
247 struct usb_device
*dev
= instance
->u
.usb_dev
;
248 unsigned char buf
[2];
251 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
252 0x12, 0xc0, 0x04, 0x00,
253 buf
, sizeof(buf
), CTRL_TIMEOUT
);
255 printk(KERN_WARNING
"SpeedTouch: Failed to start ADSL synchronisation: %d\n", ret
);
259 dbg("speedtch_start_synchro: modem prodded. %d Bytes returned: %02x %02x", ret
, buf
[0], buf
[1]);
263 static void speedtch_handle_int(struct urb
*urb
, struct pt_regs
*regs
)
265 struct speedtch_instance_data
*instance
= urb
->context
;
266 unsigned int count
= urb
->actual_length
;
269 /* The magic interrupt for "up state" */
270 const static unsigned char up_int
[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 };
271 /* The magic interrupt for "down state" */
272 const static unsigned char down_int
[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 };
274 switch (urb
->status
) {
281 /* this urb is terminated; clean up */
282 dbg("%s - urb shutting down with status: %d", __func__
, urb
->status
);
285 dbg("%s - nonzero urb status received: %d", __func__
, urb
->status
);
290 dbg("%s - int packet too short", __func__
);
294 if (!memcmp(up_int
, instance
->int_data
, 6)) {
295 del_timer(&instance
->poll_timer
);
296 printk(KERN_NOTICE
"DSL line goes up\n");
297 } else if (!memcmp(down_int
, instance
->int_data
, 6)) {
298 printk(KERN_NOTICE
"DSL line goes down\n");
302 printk(KERN_DEBUG
"Unknown interrupt packet of %d bytes:", count
);
303 for (i
= 0; i
< count
; i
++)
304 printk(" %02x", instance
->int_data
[i
]);
307 schedule_work(&instance
->poll_work
);
311 if (!instance
->int_urb
)
314 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
316 err("%s - usb_submit_urb failed with result %d", __func__
, ret
);
319 static int speedtch_get_status(struct speedtch_instance_data
*instance
,
322 struct usb_device
*dev
= instance
->u
.usb_dev
;
325 memset(buf
, 0, TOTAL
);
327 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
328 0x12, 0xc0, 0x07, 0x00, buf
+ OFFSET_7
, SIZE_7
,
335 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
336 0x12, 0xc0, 0x0b, 0x00, buf
+ OFFSET_b
, SIZE_b
,
343 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
344 0x12, 0xc0, 0x0d, 0x00, buf
+ OFFSET_d
, SIZE_d
,
351 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
352 0x01, 0xc0, 0x0e, 0x00, buf
+ OFFSET_e
, SIZE_e
,
359 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
360 0x01, 0xc0, 0x0f, 0x00, buf
+ OFFSET_f
, SIZE_f
,
370 static void speedtch_poll_status(struct speedtch_instance_data
*instance
)
372 unsigned char buf
[TOTAL
];
375 ret
= speedtch_get_status(instance
, buf
);
378 "SpeedTouch: Error %d fetching device status\n", ret
);
382 dbg("Line state %02x", buf
[OFFSET_7
]);
384 switch (buf
[OFFSET_7
]) {
386 if (instance
->u
.atm_dev
->signal
!= ATM_PHY_SIG_LOST
) {
387 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_LOST
;
388 printk(KERN_NOTICE
"ADSL line is down\n");
393 if (instance
->u
.atm_dev
->signal
!= ATM_PHY_SIG_UNKNOWN
) {
394 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_UNKNOWN
;
395 printk(KERN_NOTICE
"ADSL line is blocked?\n");
400 if (instance
->u
.atm_dev
->signal
!= ATM_PHY_SIG_LOST
) {
401 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_LOST
;
402 printk(KERN_NOTICE
"ADSL line is synchronising\n");
407 if (instance
->u
.atm_dev
->signal
!= ATM_PHY_SIG_FOUND
) {
408 int down_speed
= buf
[OFFSET_b
] | (buf
[OFFSET_b
+ 1] << 8)
409 | (buf
[OFFSET_b
+ 2] << 16) | (buf
[OFFSET_b
+ 3] << 24);
410 int up_speed
= buf
[OFFSET_b
+ 4] | (buf
[OFFSET_b
+ 5] << 8)
411 | (buf
[OFFSET_b
+ 6] << 16) | (buf
[OFFSET_b
+ 7] << 24);
413 if (!(down_speed
& 0x0000ffff) &&
414 !(up_speed
& 0x0000ffff)) {
418 instance
->u
.atm_dev
->link_rate
= down_speed
* 1000 / 424;
419 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_FOUND
;
422 "ADSL line is up (%d Kib/s down | %d Kib/s up)\n",
423 down_speed
, up_speed
);
428 if (instance
->u
.atm_dev
->signal
!= ATM_PHY_SIG_UNKNOWN
) {
429 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_UNKNOWN
;
430 printk(KERN_NOTICE
"Unknown line state %02x\n", buf
[OFFSET_7
]);
436 static void speedtch_timer_poll(unsigned long data
)
438 struct speedtch_instance_data
*instance
= (void *)data
;
440 schedule_work(&instance
->poll_work
);
441 mod_timer(&instance
->poll_timer
, jiffies
+ (5 * HZ
));
445 static void speedtch_upload_firmware(struct speedtch_instance_data
*instance
,
446 const struct firmware
*fw1
,
447 const struct firmware
*fw2
)
449 unsigned char *buffer
;
450 struct usb_device
*usb_dev
= instance
->u
.usb_dev
;
451 struct usb_interface
*intf
;
452 int actual_length
, ret
;
455 dbg("speedtch_upload_firmware");
457 if (!(intf
= usb_ifnum_to_if(usb_dev
, 2))) {
458 dbg("speedtch_upload_firmware: interface not found!");
462 if (!(buffer
= (unsigned char *)__get_free_page(GFP_KERNEL
))) {
463 dbg("speedtch_upload_firmware: no memory for buffer!");
467 /* A user-space firmware loader may already have claimed interface #2 */
469 usb_driver_claim_interface(&speedtch_usb_driver
, intf
, NULL
)) < 0) {
470 dbg("speedtch_upload_firmware: interface in use (%d)!", ret
);
475 if (dl_512_first
) { /* some modems need a read before writing the firmware */
476 ret
= usb_bulk_msg(usb_dev
, usb_rcvbulkpipe(usb_dev
, SPEEDTCH_ENDPOINT_FIRMWARE
),
477 buffer
, 0x200, &actual_length
, 2000);
479 if (ret
< 0 && ret
!= -ETIMEDOUT
)
480 dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret
);
482 dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret
);
485 /* URB 8 : both leds are static green */
486 for (offset
= 0; offset
< fw1
->size
; offset
+= PAGE_SIZE
) {
487 int thislen
= min_t(int, PAGE_SIZE
, fw1
->size
- offset
);
488 memcpy(buffer
, fw1
->data
+ offset
, thislen
);
490 ret
= usb_bulk_msg(usb_dev
, usb_sndbulkpipe(usb_dev
, SPEEDTCH_ENDPOINT_FIRMWARE
),
491 buffer
, thislen
, &actual_length
, DATA_TIMEOUT
);
494 dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret
);
497 dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1
->size
);
500 /* USB led blinking green, ADSL led off */
503 ret
= usb_bulk_msg(usb_dev
, usb_rcvbulkpipe(usb_dev
, SPEEDTCH_ENDPOINT_FIRMWARE
),
504 buffer
, 0x200, &actual_length
, DATA_TIMEOUT
);
507 dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret
);
510 dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length
);
512 /* URBs 12 to 139 - USB led blinking green, ADSL led off */
513 for (offset
= 0; offset
< fw2
->size
; offset
+= PAGE_SIZE
) {
514 int thislen
= min_t(int, PAGE_SIZE
, fw2
->size
- offset
);
515 memcpy(buffer
, fw2
->data
+ offset
, thislen
);
517 ret
= usb_bulk_msg(usb_dev
, usb_sndbulkpipe(usb_dev
, SPEEDTCH_ENDPOINT_FIRMWARE
),
518 buffer
, thislen
, &actual_length
, DATA_TIMEOUT
);
521 dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret
);
525 dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2
->size
);
527 /* USB led static green, ADSL led static red */
530 ret
= usb_bulk_msg(usb_dev
, usb_rcvbulkpipe(usb_dev
, SPEEDTCH_ENDPOINT_FIRMWARE
),
531 buffer
, 0x200, &actual_length
, DATA_TIMEOUT
);
534 dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret
);
539 dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length
);
541 /* Delay to allow firmware to start up. We can do this here
542 because we're in our own kernel thread anyway. */
545 /* Enable software buffering, if requested */
547 speedtch_set_swbuff(instance
, 1);
549 /* Magic spell; don't ask us what this does */
550 speedtch_test_sequence(instance
);
552 /* Start modem synchronisation */
553 if (speedtch_start_synchro(instance
))
554 dbg("speedtch_start_synchro: failed");
556 speedtch_got_firmware(instance
, 1);
558 free_page((unsigned long)buffer
);
562 /* Only release interface #2 if uploading failed; we don't release it
563 we succeeded. This prevents the userspace tools from trying to load
564 the firmware themselves */
565 usb_driver_release_interface(&speedtch_usb_driver
, intf
);
567 free_page((unsigned long)buffer
);
569 speedtch_got_firmware(instance
, 0);
572 static int speedtch_find_firmware(struct speedtch_instance_data
573 *instance
, int phase
,
574 const struct firmware
**fw_p
)
577 const u16 bcdDevice
= le16_to_cpu(instance
->u
.usb_dev
->descriptor
.bcdDevice
);
578 const u8 major_revision
= bcdDevice
>> 8;
579 const u8 minor_revision
= bcdDevice
& 0xff;
581 sprintf(buf
, "speedtch-%d.bin.%x.%02x", phase
, major_revision
, minor_revision
);
582 dbg("speedtch_find_firmware: looking for %s", buf
);
584 if (request_firmware(fw_p
, buf
, &instance
->u
.usb_dev
->dev
)) {
585 sprintf(buf
, "speedtch-%d.bin.%x", phase
, major_revision
);
586 dbg("speedtch_find_firmware: looking for %s", buf
);
588 if (request_firmware(fw_p
, buf
, &instance
->u
.usb_dev
->dev
)) {
589 sprintf(buf
, "speedtch-%d.bin", phase
);
590 dbg("speedtch_find_firmware: looking for %s", buf
);
592 if (request_firmware(fw_p
, buf
, &instance
->u
.usb_dev
->dev
)) {
593 dev_warn(&instance
->u
.usb_dev
->dev
, "no stage %d firmware found!", phase
);
599 dev_info(&instance
->u
.usb_dev
->dev
, "found stage %d firmware %s\n", phase
, buf
);
604 static int speedtch_load_firmware(void *arg
)
606 const struct firmware
*fw1
, *fw2
;
607 struct speedtch_instance_data
*instance
= arg
;
611 daemonize("firmware/speedtch");
613 if (!speedtch_find_firmware(instance
, 1, &fw1
)) {
614 if (!speedtch_find_firmware(instance
, 2, &fw2
)) {
615 speedtch_upload_firmware(instance
, fw1
, fw2
);
616 release_firmware(fw2
);
618 release_firmware(fw1
);
621 /* In case we failed, set state back to NO_FIRMWARE so that
622 another later attempt may work. Otherwise, we never actually
623 manage to recover if, for example, the firmware is on /usr and
624 we look for it too early. */
625 speedtch_got_firmware(instance
, 0);
627 module_put(THIS_MODULE
);
628 udsl_put_instance(&instance
->u
);
631 #endif /* USE_FW_LOADER */
633 static void speedtch_firmware_start(struct speedtch_instance_data
*instance
)
639 dbg("speedtch_firmware_start");
641 down(&instance
->u
.serialize
); /* vs self, speedtch_got_firmware */
643 if (instance
->u
.status
>= UDSL_LOADING_FIRMWARE
) {
644 up(&instance
->u
.serialize
);
648 instance
->u
.status
= UDSL_LOADING_FIRMWARE
;
649 up(&instance
->u
.serialize
);
652 udsl_get_instance(&instance
->u
);
653 try_module_get(THIS_MODULE
);
655 ret
= kernel_thread(speedtch_load_firmware
, instance
,
656 CLONE_FS
| CLONE_FILES
);
661 dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret
);
663 module_put(THIS_MODULE
);
664 udsl_put_instance(&instance
->u
);
665 /* Just pretend it never happened... hope modem_run happens */
666 #endif /* USE_FW_LOADER */
668 speedtch_got_firmware(instance
, 0);
671 static int speedtch_firmware_wait(struct udsl_instance_data
*instance
)
673 speedtch_firmware_start((void *)instance
);
675 if (wait_event_interruptible(instance
->firmware_waiters
, instance
->status
!= UDSL_LOADING_FIRMWARE
) < 0)
678 return (instance
->status
== UDSL_LOADED_FIRMWARE
) ? 0 : -EAGAIN
;
685 static int speedtch_usb_ioctl(struct usb_interface
*intf
, unsigned int code
,
688 struct speedtch_instance_data
*instance
= usb_get_intfdata(intf
);
690 dbg("speedtch_usb_ioctl entered");
693 dbg("speedtch_usb_ioctl: NULL instance!");
698 case UDSL_IOCTL_LINE_UP
:
699 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_FOUND
;
700 speedtch_got_firmware(instance
, 1);
701 return (instance
->u
.status
== UDSL_LOADED_FIRMWARE
) ? 0 : -EIO
;
702 case UDSL_IOCTL_LINE_DOWN
:
703 instance
->u
.atm_dev
->signal
= ATM_PHY_SIG_LOST
;
710 static int speedtch_usb_probe(struct usb_interface
*intf
,
711 const struct usb_device_id
*id
)
713 struct usb_device
*dev
= interface_to_usbdev(intf
);
714 int ifnum
= intf
->altsetting
->desc
.bInterfaceNumber
;
715 struct speedtch_instance_data
*instance
;
716 unsigned char mac_str
[13];
720 dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d",
721 le16_to_cpu(dev
->descriptor
.idVendor
),
722 le16_to_cpu(dev
->descriptor
.idProduct
), ifnum
);
724 if ((dev
->descriptor
.bDeviceClass
!= USB_CLASS_VENDOR_SPEC
) ||
728 dbg("speedtch_usb_probe: device accepted");
731 instance
= kmalloc(sizeof(*instance
), GFP_KERNEL
);
733 dbg("speedtch_usb_probe: no memory for instance data!");
737 memset(instance
, 0, sizeof(struct speedtch_instance_data
));
739 if ((ret
= usb_set_interface(dev
, 0, 0)) < 0)
742 if ((ret
= usb_set_interface(dev
, 2, 0)) < 0)
745 instance
->u
.data_endpoint
= SPEEDTCH_ENDPOINT_DATA
;
746 instance
->u
.firmware_wait
= speedtch_firmware_wait
;
747 instance
->u
.driver_name
= speedtch_driver_name
;
749 ret
= udsl_instance_setup(dev
, &instance
->u
);
753 init_timer(&instance
->poll_timer
);
754 instance
->poll_timer
.function
= speedtch_timer_poll
;
755 instance
->poll_timer
.data
= (unsigned long)instance
;
757 INIT_WORK(&instance
->poll_work
, (void *)speedtch_poll_status
, instance
);
759 /* set MAC address, it is stored in the serial number */
760 memset(instance
->u
.atm_dev
->esi
, 0, sizeof(instance
->u
.atm_dev
->esi
));
761 if (usb_string(dev
, dev
->descriptor
.iSerialNumber
, mac_str
, sizeof(mac_str
)) == 12) {
762 for (i
= 0; i
< 6; i
++)
763 instance
->u
.atm_dev
->esi
[i
] =
764 (hex2int(mac_str
[i
* 2]) * 16) + (hex2int(mac_str
[i
* 2 + 1]));
767 /* First check whether the modem already seems to be alive */
768 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
769 0x12, 0xc0, 0x07, 0x00, buf7
, SIZE_7
, 500);
772 dbg("firmware appears to be already loaded");
773 speedtch_got_firmware(instance
, 1);
774 speedtch_poll_status(instance
);
776 speedtch_firmware_start(instance
);
779 usb_set_intfdata(intf
, instance
);
789 static void speedtch_usb_disconnect(struct usb_interface
*intf
)
791 struct speedtch_instance_data
*instance
= usb_get_intfdata(intf
);
793 dbg("speedtch_usb_disconnect entered");
796 dbg("speedtch_usb_disconnect: NULL instance!");
800 /*QQ need to handle disconnects on interface #2 while uploading firmware */
801 /*QQ and what about interface #1? */
803 if (instance
->int_urb
) {
804 struct urb
*int_urb
= instance
->int_urb
;
805 instance
->int_urb
= NULL
;
807 usb_unlink_urb(int_urb
);
808 usb_free_urb(int_urb
);
811 instance
->int_data
[0] = 1;
812 del_timer_sync(&instance
->poll_timer
);
814 flush_scheduled_work();
816 udsl_instance_disconnect(&instance
->u
);
819 usb_set_intfdata(intf
, NULL
);
820 udsl_put_instance(&instance
->u
);
827 static int __init
speedtch_usb_init(void)
829 dbg("speedtch_usb_init: driver version " DRIVER_VERSION
);
831 return usb_register(&speedtch_usb_driver
);
834 static void __exit
speedtch_usb_cleanup(void)
836 dbg("speedtch_usb_cleanup entered");
838 usb_deregister(&speedtch_usb_driver
);
841 module_init(speedtch_usb_init
);
842 module_exit(speedtch_usb_cleanup
);
844 MODULE_AUTHOR(DRIVER_AUTHOR
);
845 MODULE_DESCRIPTION(DRIVER_DESC
);
846 MODULE_LICENSE("GPL");
847 MODULE_VERSION(DRIVER_VERSION
);