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 /* It'll never resync again unless we ask it to... */ 390 speedtch_start_synchro(instance); 391 } 392 break; 393 394 case 0x08: 395 if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { 396 instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 397 printk(KERN_NOTICE "ADSL line is blocked?\n"); 398 } 399 break; 400 401 case 0x10: 402 if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { 403 instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; 404 printk(KERN_NOTICE "ADSL line is synchronising\n"); 405 } 406 break; 407 408 case 0x20: 409 if (instance->u.atm_dev->signal != ATM_PHY_SIG_FOUND) { 410 int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8) 411 | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); 412 int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) 413 | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); 414 415 if (!(down_speed & 0x0000ffff) && 416 !(up_speed & 0x0000ffff)) { 417 down_speed >>= 16; 418 up_speed >>= 16; 419 } 420 instance->u.atm_dev->link_rate = down_speed * 1000 / 424; 421 instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND; 422 423 printk(KERN_NOTICE 424 "ADSL line is up (%d Kib/s down | %d Kib/s up)\n", 425 down_speed, up_speed); 426 } 427 break; 428 429 default: 430 if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { 431 instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 432 printk(KERN_NOTICE "Unknown line state %02x\n", buf[OFFSET_7]); 433 } 434 break; 435 } 436 } 437 438 static void speedtch_timer_poll(unsigned long data) 439 { 440 struct speedtch_instance_data *instance = (void *)data; 441 442 schedule_work(&instance->poll_work); 443 mod_timer(&instance->poll_timer, jiffies + (5 * HZ)); 444 } 445 446 #ifdef USE_FW_LOADER 447 static void speedtch_upload_firmware(struct speedtch_instance_data *instance, 448 const struct firmware *fw1, 449 const struct firmware *fw2) 450 { 451 unsigned char *buffer; 452 struct usb_device *usb_dev = instance->u.usb_dev; 453 struct usb_interface *intf; 454 int actual_length, ret; 455 int offset; 456 457 dbg("speedtch_upload_firmware"); 458 459 if (!(intf = usb_ifnum_to_if(usb_dev, 2))) { 460 dbg("speedtch_upload_firmware: interface not found!"); 461 goto fail; 462 } 463 464 if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) { 465 dbg("speedtch_upload_firmware: no memory for buffer!"); 466 goto fail; 467 } 468 469 /* A user-space firmware loader may already have claimed interface #2 */ 470 if ((ret = 471 usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) < 0) { 472 dbg("speedtch_upload_firmware: interface in use (%d)!", ret); 473 goto fail_free; 474 } 475 476 /* URB 7 */ 477 if (dl_512_first) { /* some modems need a read before writing the firmware */ 478 ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 479 buffer, 0x200, &actual_length, 2000); 480 481 if (ret < 0 && ret != -ETIMEDOUT) 482 dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret); 483 else 484 dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret); 485 } 486 487 /* URB 8 : both leds are static green */ 488 for (offset = 0; offset < fw1->size; offset += PAGE_SIZE) { 489 int thislen = min_t(int, PAGE_SIZE, fw1->size - offset); 490 memcpy(buffer, fw1->data + offset, thislen); 491 492 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 493 buffer, thislen, &actual_length, DATA_TIMEOUT); 494 495 if (ret < 0) { 496 dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret); 497 goto fail_release; 498 } 499 dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1->size); 500 } 501 502 /* USB led blinking green, ADSL led off */ 503 504 /* URB 11 */ 505 ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 506 buffer, 0x200, &actual_length, DATA_TIMEOUT); 507 508 if (ret < 0) { 509 dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret); 510 goto fail_release; 511 } 512 dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length); 513 514 /* URBs 12 to 139 - USB led blinking green, ADSL led off */ 515 for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) { 516 int thislen = min_t(int, PAGE_SIZE, fw2->size - offset); 517 memcpy(buffer, fw2->data + offset, thislen); 518 519 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 520 buffer, thislen, &actual_length, DATA_TIMEOUT); 521 522 if (ret < 0) { 523 dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret); 524 goto fail_release; 525 } 526 } 527 dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2->size); 528 529 /* USB led static green, ADSL led static red */ 530 531 /* URB 142 */ 532 ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 533 buffer, 0x200, &actual_length, DATA_TIMEOUT); 534 535 if (ret < 0) { 536 dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret); 537 goto fail_release; 538 } 539 540 /* success */ 541 dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length); 542 543 /* Delay to allow firmware to start up. We can do this here 544 because we're in our own kernel thread anyway. */ 545 msleep(1000); 546 547 /* Enable software buffering, if requested */ 548 if (sw_buffering) 549 speedtch_set_swbuff(instance, 1); 550 551 /* Magic spell; don't ask us what this does */ 552 speedtch_test_sequence(instance); 553 554 /* Start modem synchronisation */ 555 if (speedtch_start_synchro(instance)) 556 dbg("speedtch_start_synchro: failed"); 557 558 speedtch_got_firmware(instance, 1); 559 560 free_page((unsigned long)buffer); 561 return; 562 563 fail_release: 564 /* Only release interface #2 if uploading failed; we don't release it 565 we succeeded. This prevents the userspace tools from trying to load 566 the firmware themselves */ 567 usb_driver_release_interface(&speedtch_usb_driver, intf); 568 fail_free: 569 free_page((unsigned long)buffer); 570 fail: 571 speedtch_got_firmware(instance, 0); 572 } 573 574 static int speedtch_find_firmware(struct speedtch_instance_data 575 *instance, int phase, 576 const struct firmware **fw_p) 577 { 578 char buf[24]; 579 const u16 bcdDevice = le16_to_cpu(instance->u.usb_dev->descriptor.bcdDevice); 580 const u8 major_revision = bcdDevice >> 8; 581 const u8 minor_revision = bcdDevice & 0xff; 582 583 sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); 584 dbg("speedtch_find_firmware: looking for %s", buf); 585 586 if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { 587 sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); 588 dbg("speedtch_find_firmware: looking for %s", buf); 589 590 if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { 591 sprintf(buf, "speedtch-%d.bin", phase); 592 dbg("speedtch_find_firmware: looking for %s", buf); 593 594 if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { 595 dev_warn(&instance->u.usb_dev->dev, "no stage %d firmware found!", phase); 596 return -ENOENT; 597 } 598 } 599 } 600 601 dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf); 602 603 return 0; 604 } 605 606 static int speedtch_load_firmware(void *arg) 607 { 608 const struct firmware *fw1, *fw2; 609 struct speedtch_instance_data *instance = arg; 610 611 BUG_ON(!instance); 612 613 daemonize("firmware/speedtch"); 614 615 if (!speedtch_find_firmware(instance, 1, &fw1)) { 616 if (!speedtch_find_firmware(instance, 2, &fw2)) { 617 speedtch_upload_firmware(instance, fw1, fw2); 618 release_firmware(fw2); 619 } 620 release_firmware(fw1); 621 } 622 623 /* In case we failed, set state back to NO_FIRMWARE so that 624 another later attempt may work. Otherwise, we never actually 625 manage to recover if, for example, the firmware is on /usr and 626 we look for it too early. */ 627 speedtch_got_firmware(instance, 0); 628 629 module_put(THIS_MODULE); 630 udsl_put_instance(&instance->u); 631 return 0; 632 } 633 #endif /* USE_FW_LOADER */ 634 635 static void speedtch_firmware_start(struct speedtch_instance_data *instance) 636 { 637 #ifdef USE_FW_LOADER 638 int ret; 639 #endif 640 641 dbg("speedtch_firmware_start"); 642 643 down(&instance->u.serialize); /* vs self, speedtch_got_firmware */ 644 645 if (instance->u.status >= UDSL_LOADING_FIRMWARE) { 646 up(&instance->u.serialize); 647 return; 648 } 649 650 instance->u.status = UDSL_LOADING_FIRMWARE; 651 up(&instance->u.serialize); 652 653 #ifdef USE_FW_LOADER 654 udsl_get_instance(&instance->u); 655 try_module_get(THIS_MODULE); 656 657 ret = kernel_thread(speedtch_load_firmware, instance, 658 CLONE_FS | CLONE_FILES); 659 660 if (ret >= 0) 661 return; /* OK */ 662 663 dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret); 664 665 module_put(THIS_MODULE); 666 udsl_put_instance(&instance->u); 667 /* Just pretend it never happened... hope modem_run happens */ 668 #endif /* USE_FW_LOADER */ 669 670 speedtch_got_firmware(instance, 0); 671 } 672 673 static int speedtch_firmware_wait(struct udsl_instance_data *instance) 674 { 675 speedtch_firmware_start((void *)instance); 676 677 if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0) 678 return -ERESTARTSYS; 679 680 return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN; 681 } 682 683 /********** 684 ** USB ** 685 **********/ 686 687 static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code, 688 void *user_data) 689 { 690 struct speedtch_instance_data *instance = usb_get_intfdata(intf); 691 692 dbg("speedtch_usb_ioctl entered"); 693 694 if (!instance) { 695 dbg("speedtch_usb_ioctl: NULL instance!"); 696 return -ENODEV; 697 } 698 699 switch (code) { 700 case UDSL_IOCTL_LINE_UP: 701 instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND; 702 speedtch_got_firmware(instance, 1); 703 return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO; 704 case UDSL_IOCTL_LINE_DOWN: 705 instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; 706 return 0; 707 default: 708 return -ENOTTY; 709 } 710 } 711 712 static int speedtch_usb_probe(struct usb_interface *intf, 713 const struct usb_device_id *id) 714 { 715 struct usb_device *dev = interface_to_usbdev(intf); 716 int ifnum = intf->altsetting->desc.bInterfaceNumber; 717 struct speedtch_instance_data *instance; 718 unsigned char mac_str[13]; 719 int ret, i; 720 char buf7[SIZE_7]; 721 722 dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", 723 le16_to_cpu(dev->descriptor.idVendor), 724 le16_to_cpu(dev->descriptor.idProduct), ifnum); 725 726 if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || 727 (ifnum != 1)) 728 return -ENODEV; 729 730 dbg("speedtch_usb_probe: device accepted"); 731 732 /* instance init */ 733 instance = kmalloc(sizeof(*instance), GFP_KERNEL); 734 if (!instance) { 735 dbg("speedtch_usb_probe: no memory for instance data!"); 736 return -ENOMEM; 737 } 738 739 memset(instance, 0, sizeof(struct speedtch_instance_data)); 740 741 if ((ret = usb_set_interface(dev, 0, 0)) < 0) 742 goto fail; 743 744 if ((ret = usb_set_interface(dev, 2, 0)) < 0) 745 goto fail; 746 747 instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA; 748 instance->u.firmware_wait = speedtch_firmware_wait; 749 instance->u.driver_name = speedtch_driver_name; 750 751 ret = udsl_instance_setup(dev, &instance->u); 752 if (ret) 753 goto fail; 754 755 init_timer(&instance->poll_timer); 756 instance->poll_timer.function = speedtch_timer_poll; 757 instance->poll_timer.data = (unsigned long)instance; 758 759 INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance); 760 761 /* set MAC address, it is stored in the serial number */ 762 memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi)); 763 if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { 764 for (i = 0; i < 6; i++) 765 instance->u.atm_dev->esi[i] = 766 (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1])); 767 } 768 769 /* First check whether the modem already seems to be alive */ 770 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 771 0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, 500); 772 773 if (ret == SIZE_7) { 774 dbg("firmware appears to be already loaded"); 775 speedtch_got_firmware(instance, 1); 776 speedtch_poll_status(instance); 777 } else { 778 speedtch_firmware_start(instance); 779 } 780 781 usb_set_intfdata(intf, instance); 782 783 return 0; 784 785 fail: 786 kfree(instance); 787 788 return -ENOMEM; 789 } 790 791 static void speedtch_usb_disconnect(struct usb_interface *intf) 792 { 793 struct speedtch_instance_data *instance = usb_get_intfdata(intf); 794 795 dbg("speedtch_usb_disconnect entered"); 796 797 if (!instance) { 798 dbg("speedtch_usb_disconnect: NULL instance!"); 799 return; 800 } 801 802 /*QQ need to handle disconnects on interface #2 while uploading firmware */ 803 /*QQ and what about interface #1? */ 804 805 if (instance->int_urb) { 806 struct urb *int_urb = instance->int_urb; 807 instance->int_urb = NULL; 808 wmb(); 809 usb_unlink_urb(int_urb); 810 usb_free_urb(int_urb); 811 } 812 813 instance->int_data[0] = 1; 814 del_timer_sync(&instance->poll_timer); 815 wmb(); 816 flush_scheduled_work(); 817 818 udsl_instance_disconnect(&instance->u); 819 820 /* clean up */ 821 usb_set_intfdata(intf, NULL); 822 udsl_put_instance(&instance->u); 823 } 824 825 /*********** 826 ** init ** 827 ***********/ 828 829 static int __init speedtch_usb_init(void) 830 { 831 dbg("speedtch_usb_init: driver version " DRIVER_VERSION); 832 833 return usb_register(&speedtch_usb_driver); 834 } 835 836 static void __exit speedtch_usb_cleanup(void) 837 { 838 dbg("speedtch_usb_cleanup entered"); 839 840 usb_deregister(&speedtch_usb_driver); 841 } 842 843 module_init(speedtch_usb_init); 844 module_exit(speedtch_usb_cleanup); 845 846 MODULE_AUTHOR(DRIVER_AUTHOR); 847 MODULE_DESCRIPTION(DRIVER_DESC); 848 MODULE_LICENSE("GPL"); 849 MODULE_VERSION(DRIVER_VERSION); 850