Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 (2*HZ)
 62 #define DATA_TIMEOUT (2*HZ)
 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 >= '') && (c <= '9') ? (c - '') : ((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, 2 * HZ);
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, HZ / 2);
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);
848 
  This page was automatically generated by the LXR engine.