]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/usb/atm/speedtch.c
Linux-2.6.12-rc2
[karo-tx-linux.git] / drivers / usb / atm / speedtch.c
1 /******************************************************************************
2  *  speedtch.c  -  Alcatel SpeedTouch USB xDSL modem driver
3  *
4  *  Copyright (C) 2001, Alcatel
5  *  Copyright (C) 2003, Duncan Sands
6  *  Copyright (C) 2004, David Woodhouse
7  *
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)
11  *  any later version.
12  *
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
16  *  more details.
17  *
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.
21  *
22  ******************************************************************************/
23
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>
44
45 #include "usb_atm.h"
46
47 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
48 #       define USE_FW_LOADER
49 #endif
50
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
54
55 static const char speedtch_driver_name[] = "speedtch";
56
57 #define SPEEDTOUCH_VENDORID             0x06b9
58 #define SPEEDTOUCH_PRODUCTID            0x4061
59
60 /* Timeout in jiffies */
61 #define CTRL_TIMEOUT 2000
62 #define DATA_TIMEOUT 2000
63
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 */
69 #define TOTAL    15
70
71 #define SIZE_7 1
72 #define SIZE_b 8
73 #define SIZE_d 4
74 #define SIZE_e 1
75 #define SIZE_f 1
76
77 static int dl_512_first = 0;
78 static int sw_buffering = 0;
79
80 module_param(dl_512_first, bool, 0444);
81 MODULE_PARM_DESC(dl_512_first, "Read 512 bytes before sending firmware");
82
83 module_param(sw_buffering, uint, 0444);
84 MODULE_PARM_DESC(sw_buffering, "Enable software buffering");
85
86 #define UDSL_IOCTL_LINE_UP              1
87 #define UDSL_IOCTL_LINE_DOWN            2
88
89 #define SPEEDTCH_ENDPOINT_INT           0x81
90 #define SPEEDTCH_ENDPOINT_DATA          0x07
91 #define SPEEDTCH_ENDPOINT_FIRMWARE      0x05
92
93 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
94
95 static struct usb_device_id speedtch_usb_ids[] = {
96         {USB_DEVICE(SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)},
97         {}
98 };
99
100 MODULE_DEVICE_TABLE(usb, speedtch_usb_ids);
101
102 struct speedtch_instance_data {
103         struct udsl_instance_data u;
104
105         /* Status */
106         struct urb *int_urb;
107         unsigned char int_data[16];
108         struct work_struct poll_work;
109         struct timer_list poll_timer;
110 };
111 /* USB */
112
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,
117                               void *user_data);
118 static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs);
119 static void speedtch_poll_status(struct speedtch_instance_data *instance);
120
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,
128 };
129
130 /***************
131 **  firmware  **
132 ***************/
133
134 static void speedtch_got_firmware(struct speedtch_instance_data *instance,
135                                   int got_it)
136 {
137         int err;
138         struct usb_interface *intf;
139
140         down(&instance->u.serialize);   /* vs self, speedtch_firmware_start */
141         if (instance->u.status == UDSL_LOADED_FIRMWARE)
142                 goto out;
143         if (!got_it) {
144                 instance->u.status = UDSL_NO_FIRMWARE;
145                 goto out;
146         }
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;
150                 goto out;
151         }
152
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)) {
156
157                 instance->int_urb = usb_alloc_urb(0, GFP_KERNEL);
158                 if (instance->int_urb) {
159
160                         usb_fill_int_urb(instance->int_urb, instance->u.usb_dev,
161                                          usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT),
162                                          instance->int_data,
163                                          sizeof(instance->int_data),
164                                          speedtch_handle_int, instance, 50);
165                         err = usb_submit_urb(instance->int_urb, GFP_KERNEL);
166                         if (err) {
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);
172                         }
173                 }
174         }
175         /* Start status polling */
176         mod_timer(&instance->poll_timer, jiffies + (1 * HZ));
177
178         instance->u.status = UDSL_LOADED_FIRMWARE;
179         tasklet_schedule(&instance->u.receive_tasklet);
180  out:
181         up(&instance->u.serialize);
182         wake_up_interruptible(&instance->u.firmware_waiters);
183 }
184
185 static int speedtch_set_swbuff(struct speedtch_instance_data *instance,
186                                int state)
187 {
188         struct usb_device *dev = instance->u.usb_dev;
189         int ret;
190
191         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
192                               0x32, 0x40, state ? 0x01 : 0x00,
193                               0x00, NULL, 0, 100);
194         if (ret < 0) {
195                 printk("Warning: %sabling SW buffering: usb_control_msg returned %d\n",
196                      state ? "En" : "Dis", ret);
197                 return ret;
198         }
199
200         dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis");
201         return 0;
202 }
203
204 static void speedtch_test_sequence(struct speedtch_instance_data *instance)
205 {
206         struct usb_device *dev = instance->u.usb_dev;
207         unsigned char buf[10];
208         int ret;
209
210         /* URB 147 */
211         buf[0] = 0x1c;
212         buf[1] = 0x50;
213         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
214                               0x01, 0x40, 0x0b, 0x00, buf, 2, 100);
215         if (ret < 0)
216                 printk(KERN_WARNING "%s failed on URB147: %d\n", __func__, ret);
217
218         /* URB 148 */
219         buf[0] = 0x32;
220         buf[1] = 0x00;
221         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
222                               0x01, 0x40, 0x02, 0x00, buf, 2, 100);
223         if (ret < 0)
224                 printk(KERN_WARNING "%s failed on URB148: %d\n", __func__, ret);
225
226         /* URB 149 */
227         buf[0] = 0x01;
228         buf[1] = 0x00;
229         buf[2] = 0x01;
230         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
231                               0x01, 0x40, 0x03, 0x00, buf, 3, 100);
232         if (ret < 0)
233                 printk(KERN_WARNING "%s failed on URB149: %d\n", __func__, ret);
234
235         /* URB 150 */
236         buf[0] = 0x01;
237         buf[1] = 0x00;
238         buf[2] = 0x01;
239         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
240                               0x01, 0x40, 0x04, 0x00, buf, 3, 100);
241         if (ret < 0)
242                 printk(KERN_WARNING "%s failed on URB150: %d\n", __func__, ret);
243 }
244
245 static int speedtch_start_synchro(struct speedtch_instance_data *instance)
246 {
247         struct usb_device *dev = instance->u.usb_dev;
248         unsigned char buf[2];
249         int ret;
250
251         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
252                               0x12, 0xc0, 0x04, 0x00,
253                               buf, sizeof(buf), CTRL_TIMEOUT);
254         if (ret < 0) {
255                 printk(KERN_WARNING "SpeedTouch: Failed to start ADSL synchronisation: %d\n", ret);
256                 return ret;
257         }
258
259         dbg("speedtch_start_synchro: modem prodded. %d Bytes returned: %02x %02x", ret, buf[0], buf[1]);
260         return 0;
261 }
262
263 static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs)
264 {
265         struct speedtch_instance_data *instance = urb->context;
266         unsigned int count = urb->actual_length;
267         int ret;
268
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 };
273
274         switch (urb->status) {
275         case 0:
276                 /* success */
277                 break;
278         case -ECONNRESET:
279         case -ENOENT:
280         case -ESHUTDOWN:
281                 /* this urb is terminated; clean up */
282                 dbg("%s - urb shutting down with status: %d", __func__, urb->status);
283                 return;
284         default:
285                 dbg("%s - nonzero urb status received: %d", __func__, urb->status);
286                 goto exit;
287         }
288
289         if (count < 6) {
290                 dbg("%s - int packet too short", __func__);
291                 goto exit;
292         }
293
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");
299         } else {
300                 int i;
301
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]);
305                 printk("\n");
306         }
307         schedule_work(&instance->poll_work);
308
309  exit:
310         rmb();
311         if (!instance->int_urb)
312                 return;
313
314         ret = usb_submit_urb(urb, GFP_ATOMIC);
315         if (ret)
316                 err("%s - usb_submit_urb failed with result %d", __func__, ret);
317 }
318
319 static int speedtch_get_status(struct speedtch_instance_data *instance,
320                                unsigned char *buf)
321 {
322         struct usb_device *dev = instance->u.usb_dev;
323         int ret;
324
325         memset(buf, 0, TOTAL);
326
327         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
328                               0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7,
329                               CTRL_TIMEOUT);
330         if (ret < 0) {
331                 dbg("MSG 7 failed");
332                 return ret;
333         }
334
335         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
336                               0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b,
337                               CTRL_TIMEOUT);
338         if (ret < 0) {
339                 dbg("MSG B failed");
340                 return ret;
341         }
342
343         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
344                               0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d,
345                               CTRL_TIMEOUT);
346         if (ret < 0) {
347                 dbg("MSG D failed");
348                 return ret;
349         }
350
351         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
352                               0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e,
353                               CTRL_TIMEOUT);
354         if (ret < 0) {
355                 dbg("MSG E failed");
356                 return ret;
357         }
358
359         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
360                               0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f,
361                               CTRL_TIMEOUT);
362         if (ret < 0) {
363                 dbg("MSG F failed");
364                 return ret;
365         }
366
367         return 0;
368 }
369
370 static void speedtch_poll_status(struct speedtch_instance_data *instance)
371 {
372         unsigned char buf[TOTAL];
373         int ret;
374
375         ret = speedtch_get_status(instance, buf);
376         if (ret) {
377                 printk(KERN_WARNING
378                        "SpeedTouch: Error %d fetching device status\n", ret);
379                 return;
380         }
381
382         dbg("Line state %02x", buf[OFFSET_7]);
383
384         switch (buf[OFFSET_7]) {
385         case 0:
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");
389                 }
390                 break;
391
392         case 0x08:
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");
396                 }
397                 break;
398
399         case 0x10:
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");
403                 }
404                 break;
405
406         case 0x20:
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);
412
413                         if (!(down_speed & 0x0000ffff) &&
414                             !(up_speed & 0x0000ffff)) {
415                                 down_speed >>= 16;
416                                 up_speed >>= 16;
417                         }
418                         instance->u.atm_dev->link_rate = down_speed * 1000 / 424;
419                         instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
420
421                         printk(KERN_NOTICE
422                                "ADSL line is up (%d Kib/s down | %d Kib/s up)\n",
423                                down_speed, up_speed);
424                 }
425                 break;
426
427         default:
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]);
431                 }
432                 break;
433         }
434 }
435
436 static void speedtch_timer_poll(unsigned long data)
437 {
438         struct speedtch_instance_data *instance = (void *)data;
439
440         schedule_work(&instance->poll_work);
441         mod_timer(&instance->poll_timer, jiffies + (5 * HZ));
442 }
443
444 #ifdef USE_FW_LOADER
445 static void speedtch_upload_firmware(struct speedtch_instance_data *instance,
446                                      const struct firmware *fw1,
447                                      const struct firmware *fw2)
448 {
449         unsigned char *buffer;
450         struct usb_device *usb_dev = instance->u.usb_dev;
451         struct usb_interface *intf;
452         int actual_length, ret;
453         int offset;
454
455         dbg("speedtch_upload_firmware");
456
457         if (!(intf = usb_ifnum_to_if(usb_dev, 2))) {
458                 dbg("speedtch_upload_firmware: interface not found!");
459                 goto fail;
460         }
461
462         if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) {
463                 dbg("speedtch_upload_firmware: no memory for buffer!");
464                 goto fail;
465         }
466
467         /* A user-space firmware loader may already have claimed interface #2 */
468         if ((ret =
469              usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) < 0) {
470                 dbg("speedtch_upload_firmware: interface in use (%d)!", ret);
471                 goto fail_free;
472         }
473
474         /* URB 7 */
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);
478
479                 if (ret < 0 && ret != -ETIMEDOUT)
480                         dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret);
481                 else
482                         dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret);
483         }
484
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);
489
490                 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
491                                    buffer, thislen, &actual_length, DATA_TIMEOUT);
492
493                 if (ret < 0) {
494                         dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret);
495                         goto fail_release;
496                 }
497                 dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1->size);
498         }
499
500         /* USB led blinking green, ADSL led off */
501
502         /* URB 11 */
503         ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
504                            buffer, 0x200, &actual_length, DATA_TIMEOUT);
505
506         if (ret < 0) {
507                 dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret);
508                 goto fail_release;
509         }
510         dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length);
511
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);
516
517                 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
518                                    buffer, thislen, &actual_length, DATA_TIMEOUT);
519
520                 if (ret < 0) {
521                         dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret);
522                         goto fail_release;
523                 }
524         }
525         dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2->size);
526
527         /* USB led static green, ADSL led static red */
528
529         /* URB 142 */
530         ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
531                            buffer, 0x200, &actual_length, DATA_TIMEOUT);
532
533         if (ret < 0) {
534                 dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret);
535                 goto fail_release;
536         }
537
538         /* success */
539         dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length);
540
541         /* Delay to allow firmware to start up. We can do this here
542            because we're in our own kernel thread anyway. */
543         msleep(1000);
544
545         /* Enable software buffering, if requested */
546         if (sw_buffering)
547                 speedtch_set_swbuff(instance, 1);
548
549         /* Magic spell; don't ask us what this does */
550         speedtch_test_sequence(instance);
551
552         /* Start modem synchronisation */
553         if (speedtch_start_synchro(instance))
554                 dbg("speedtch_start_synchro: failed");
555
556         speedtch_got_firmware(instance, 1);
557
558         free_page((unsigned long)buffer);
559         return;
560
561  fail_release:
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);
566  fail_free:
567         free_page((unsigned long)buffer);
568  fail:
569         speedtch_got_firmware(instance, 0);
570 }
571
572 static int speedtch_find_firmware(struct speedtch_instance_data
573                                   *instance, int phase,
574                                   const struct firmware **fw_p)
575 {
576         char buf[24];
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;
580
581         sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision);
582         dbg("speedtch_find_firmware: looking for %s", buf);
583
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);
587
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);
591
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);
594                                 return -ENOENT;
595                         }
596                 }
597         }
598
599         dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf);
600
601         return 0;
602 }
603
604 static int speedtch_load_firmware(void *arg)
605 {
606         const struct firmware *fw1, *fw2;
607         struct speedtch_instance_data *instance = arg;
608
609         BUG_ON(!instance);
610
611         daemonize("firmware/speedtch");
612
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);
617                 }
618                 release_firmware(fw1);
619         }
620
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);
626
627         module_put(THIS_MODULE);
628         udsl_put_instance(&instance->u);
629         return 0;
630 }
631 #endif /* USE_FW_LOADER */
632
633 static void speedtch_firmware_start(struct speedtch_instance_data *instance)
634 {
635 #ifdef USE_FW_LOADER
636         int ret;
637 #endif
638
639         dbg("speedtch_firmware_start");
640
641         down(&instance->u.serialize);   /* vs self, speedtch_got_firmware */
642
643         if (instance->u.status >= UDSL_LOADING_FIRMWARE) {
644                 up(&instance->u.serialize);
645                 return;
646         }
647
648         instance->u.status = UDSL_LOADING_FIRMWARE;
649         up(&instance->u.serialize);
650
651 #ifdef USE_FW_LOADER
652         udsl_get_instance(&instance->u);
653         try_module_get(THIS_MODULE);
654
655         ret = kernel_thread(speedtch_load_firmware, instance,
656                             CLONE_FS | CLONE_FILES);
657
658         if (ret >= 0)
659                 return;         /* OK */
660
661         dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret);
662
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 */
667
668         speedtch_got_firmware(instance, 0);
669 }
670
671 static int speedtch_firmware_wait(struct udsl_instance_data *instance)
672 {
673         speedtch_firmware_start((void *)instance);
674
675         if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0)
676                 return -ERESTARTSYS;
677
678         return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN;
679 }
680
681 /**********
682 **  USB  **
683 **********/
684
685 static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
686                               void *user_data)
687 {
688         struct speedtch_instance_data *instance = usb_get_intfdata(intf);
689
690         dbg("speedtch_usb_ioctl entered");
691
692         if (!instance) {
693                 dbg("speedtch_usb_ioctl: NULL instance!");
694                 return -ENODEV;
695         }
696
697         switch (code) {
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;
704                 return 0;
705         default:
706                 return -ENOTTY;
707         }
708 }
709
710 static int speedtch_usb_probe(struct usb_interface *intf,
711                               const struct usb_device_id *id)
712 {
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];
717         int ret, i;
718         char buf7[SIZE_7];
719
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);
723
724         if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || 
725             (ifnum != 1))
726                 return -ENODEV;
727
728         dbg("speedtch_usb_probe: device accepted");
729
730         /* instance init */
731         instance = kmalloc(sizeof(*instance), GFP_KERNEL);
732         if (!instance) {
733                 dbg("speedtch_usb_probe: no memory for instance data!");
734                 return -ENOMEM;
735         }
736
737         memset(instance, 0, sizeof(struct speedtch_instance_data));
738
739         if ((ret = usb_set_interface(dev, 0, 0)) < 0)
740                 goto fail;
741
742         if ((ret = usb_set_interface(dev, 2, 0)) < 0)
743                 goto fail;
744
745         instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA;
746         instance->u.firmware_wait = speedtch_firmware_wait;
747         instance->u.driver_name = speedtch_driver_name;
748
749         ret = udsl_instance_setup(dev, &instance->u);
750         if (ret)
751                 goto fail;
752
753         init_timer(&instance->poll_timer);
754         instance->poll_timer.function = speedtch_timer_poll;
755         instance->poll_timer.data = (unsigned long)instance;
756
757         INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance);
758
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]));
765         }
766
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);
770
771         if (ret == SIZE_7) {
772                 dbg("firmware appears to be already loaded");
773                 speedtch_got_firmware(instance, 1);
774                 speedtch_poll_status(instance);
775         } else {
776                 speedtch_firmware_start(instance);
777         }
778
779         usb_set_intfdata(intf, instance);
780
781         return 0;
782
783  fail:
784         kfree(instance);
785
786         return -ENOMEM;
787 }
788
789 static void speedtch_usb_disconnect(struct usb_interface *intf)
790 {
791         struct speedtch_instance_data *instance = usb_get_intfdata(intf);
792
793         dbg("speedtch_usb_disconnect entered");
794
795         if (!instance) {
796                 dbg("speedtch_usb_disconnect: NULL instance!");
797                 return;
798         }
799
800 /*QQ need to handle disconnects on interface #2 while uploading firmware */
801 /*QQ and what about interface #1? */
802
803         if (instance->int_urb) {
804                 struct urb *int_urb = instance->int_urb;
805                 instance->int_urb = NULL;
806                 wmb();
807                 usb_unlink_urb(int_urb);
808                 usb_free_urb(int_urb);
809         }
810
811         instance->int_data[0] = 1;
812         del_timer_sync(&instance->poll_timer);
813         wmb();
814         flush_scheduled_work();
815
816         udsl_instance_disconnect(&instance->u);
817
818         /* clean up */
819         usb_set_intfdata(intf, NULL);
820         udsl_put_instance(&instance->u);
821 }
822
823 /***********
824 **  init  **
825 ***********/
826
827 static int __init speedtch_usb_init(void)
828 {
829         dbg("speedtch_usb_init: driver version " DRIVER_VERSION);
830
831         return usb_register(&speedtch_usb_driver);
832 }
833
834 static void __exit speedtch_usb_cleanup(void)
835 {
836         dbg("speedtch_usb_cleanup entered");
837
838         usb_deregister(&speedtch_usb_driver);
839 }
840
841 module_init(speedtch_usb_init);
842 module_exit(speedtch_usb_cleanup);
843
844 MODULE_AUTHOR(DRIVER_AUTHOR);
845 MODULE_DESCRIPTION(DRIVER_DESC);
846 MODULE_LICENSE("GPL");
847 MODULE_VERSION(DRIVER_VERSION);