Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] USB ATM: port speedtch to new usbatm core

Port the speedtch driver to the new usbatm core. The code is much
the same as before, just reorganized, though I threw in some minor
improvements (a new module parameter for choosing the altsetting,
more robust urb failure handling, ...) while I was there.

Signed-off-by: Duncan Sands <baldrick@free.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Duncan Sands and committed by
Greg Kroah-Hartman
48da7267 9574507c

+549 -568
+549 -568
drivers/usb/atm/speedtch.c
··· 5 5 * Copyright (C) 2003, Duncan Sands 6 6 * Copyright (C) 2004, David Woodhouse 7 7 * 8 + * Based on "modem_run.c", copyright (C) 2001, Benoit Papillault 9 + * 8 10 * This program is free software; you can redistribute it and/or modify it 9 11 * under the terms of the GNU General Public License as published by the Free 10 12 * Software Foundation; either version 2 of the License, or (at your option) ··· 23 21 * 24 22 ******************************************************************************/ 25 23 24 + #include <asm/page.h> 25 + #include <linux/device.h> 26 + #include <linux/errno.h> 27 + #include <linux/firmware.h> 28 + #include <linux/gfp.h> 29 + #include <linux/init.h> 30 + #include <linux/kernel.h> 26 31 #include <linux/module.h> 27 32 #include <linux/moduleparam.h> 28 - #include <linux/gfp.h> 29 - #include <linux/kernel.h> 30 - #include <linux/sched.h> 31 - #include <linux/timer.h> 32 - #include <linux/errno.h> 33 - #include <linux/proc_fs.h> 34 33 #include <linux/slab.h> 35 - #include <linux/wait.h> 36 - #include <linux/list.h> 37 - #include <asm/processor.h> 38 - #include <asm/uaccess.h> 39 - #include <linux/smp_lock.h> 40 - #include <linux/interrupt.h> 41 - #include <linux/atm.h> 42 - #include <linux/atmdev.h> 43 - #include <linux/crc32.h> 44 - #include <linux/init.h> 45 - #include <linux/firmware.h> 34 + #include <linux/stat.h> 35 + #include <linux/timer.h> 36 + #include <linux/workqueue.h> 46 37 47 - #include "usb_atm.h" 48 - 49 - #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) 50 - # define USE_FW_LOADER 51 - #endif 38 + #include "usbatm.h" 52 39 53 40 #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>" 54 - #define DRIVER_VERSION "1.8" 41 + #define DRIVER_VERSION "1.9" 55 42 #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION 56 43 57 44 static const char speedtch_driver_name[] = "speedtch"; 58 45 59 - #define SPEEDTOUCH_VENDORID 0x06b9 60 - #define SPEEDTOUCH_PRODUCTID 0x4061 46 + #define CTRL_TIMEOUT 2000 /* milliseconds */ 47 + #define DATA_TIMEOUT 2000 /* milliseconds */ 61 48 62 - /* Timeout in jiffies */ 63 - #define CTRL_TIMEOUT 2000 64 - #define DATA_TIMEOUT 2000 49 + #define OFFSET_7 0 /* size 1 */ 50 + #define OFFSET_b 1 /* size 8 */ 51 + #define OFFSET_d 9 /* size 4 */ 52 + #define OFFSET_e 13 /* size 1 */ 53 + #define OFFSET_f 14 /* size 1 */ 54 + #define TOTAL 15 65 55 66 - #define OFFSET_7 0 /* size 1 */ 67 - #define OFFSET_b 1 /* size 8 */ 68 - #define OFFSET_d 9 /* size 4 */ 69 - #define OFFSET_e 13 /* size 1 */ 70 - #define OFFSET_f 14 /* size 1 */ 71 - #define TOTAL 15 56 + #define SIZE_7 1 57 + #define SIZE_b 8 58 + #define SIZE_d 4 59 + #define SIZE_e 1 60 + #define SIZE_f 1 72 61 73 - #define SIZE_7 1 74 - #define SIZE_b 8 75 - #define SIZE_d 4 76 - #define SIZE_e 1 77 - #define SIZE_f 1 62 + #define MIN_POLL_DELAY 5000 /* milliseconds */ 63 + #define MAX_POLL_DELAY 60000 /* milliseconds */ 78 64 79 - static int dl_512_first = 0; 80 - static int sw_buffering = 0; 65 + #define RESUBMIT_DELAY 1000 /* milliseconds */ 81 66 82 - module_param(dl_512_first, bool, 0444); 83 - MODULE_PARM_DESC(dl_512_first, "Read 512 bytes before sending firmware"); 67 + #define DEFAULT_ALTSETTING 1 68 + #define DEFAULT_DL_512_FIRST 0 69 + #define DEFAULT_SW_BUFFERING 0 84 70 85 - module_param(sw_buffering, uint, 0444); 86 - MODULE_PARM_DESC(sw_buffering, "Enable software buffering"); 71 + static int altsetting = DEFAULT_ALTSETTING; 72 + static int dl_512_first = DEFAULT_DL_512_FIRST; 73 + static int sw_buffering = DEFAULT_SW_BUFFERING; 87 74 88 - #define UDSL_IOCTL_LINE_UP 1 89 - #define UDSL_IOCTL_LINE_DOWN 2 75 + module_param(altsetting, int, S_IRUGO | S_IWUSR); 76 + MODULE_PARM_DESC(altsetting, 77 + "Alternative setting for data interface (default: " 78 + __MODULE_STRING(DEFAULT_ALTSETTING) ")"); 90 79 91 - #define SPEEDTCH_ENDPOINT_INT 0x81 92 - #define SPEEDTCH_ENDPOINT_DATA 0x07 93 - #define SPEEDTCH_ENDPOINT_FIRMWARE 0x05 80 + module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); 81 + MODULE_PARM_DESC(dl_512_first, 82 + "Read 512 bytes before sending firmware (default: " 83 + __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); 84 + 85 + module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); 86 + MODULE_PARM_DESC(sw_buffering, 87 + "Enable software buffering (default: " 88 + __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); 89 + 90 + #define ENDPOINT_INT 0x81 91 + #define ENDPOINT_DATA 0x07 92 + #define ENDPOINT_FIRMWARE 0x05 94 93 95 94 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) 96 95 97 - static struct usb_device_id speedtch_usb_ids[] = { 98 - {USB_DEVICE(SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)}, 99 - {} 100 - }; 101 - 102 - MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); 103 - 104 96 struct speedtch_instance_data { 105 - struct udsl_instance_data u; 97 + struct usbatm_data *usbatm; 106 98 107 - /* Status */ 99 + struct work_struct status_checker; 100 + 101 + int poll_delay; /* milliseconds */ 102 + 103 + struct timer_list resubmit_timer; 108 104 struct urb *int_urb; 109 105 unsigned char int_data[16]; 110 - struct work_struct poll_work; 111 - struct timer_list poll_timer; 112 - }; 113 - /* USB */ 114 106 115 - static int speedtch_usb_probe(struct usb_interface *intf, 116 - const struct usb_device_id *id); 117 - static void speedtch_usb_disconnect(struct usb_interface *intf); 118 - static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code, 119 - void *user_data); 120 - static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs); 121 - static void speedtch_poll_status(struct speedtch_instance_data *instance); 122 - 123 - static struct usb_driver speedtch_usb_driver = { 124 - .owner = THIS_MODULE, 125 - .name = speedtch_driver_name, 126 - .probe = speedtch_usb_probe, 127 - .disconnect = speedtch_usb_disconnect, 128 - .ioctl = speedtch_usb_ioctl, 129 - .id_table = speedtch_usb_ids, 107 + unsigned char scratch_buffer[TOTAL]; 130 108 }; 131 109 132 110 /*************** 133 111 ** firmware ** 134 112 ***************/ 135 113 136 - static void speedtch_got_firmware(struct speedtch_instance_data *instance, 137 - int got_it) 114 + static void speedtch_set_swbuff(struct speedtch_instance_data *instance, int state) 138 115 { 139 - int err; 140 - struct usb_interface *intf; 141 - 142 - down(&instance->u.serialize); /* vs self, speedtch_firmware_start */ 143 - if (instance->u.status == UDSL_LOADED_FIRMWARE) 144 - goto out; 145 - if (!got_it) { 146 - instance->u.status = UDSL_NO_FIRMWARE; 147 - goto out; 148 - } 149 - if ((err = usb_set_interface(instance->u.usb_dev, 1, 1)) < 0) { 150 - dbg("speedtch_got_firmware: usb_set_interface returned %d!", err); 151 - instance->u.status = UDSL_NO_FIRMWARE; 152 - goto out; 153 - } 154 - 155 - /* Set up interrupt endpoint */ 156 - intf = usb_ifnum_to_if(instance->u.usb_dev, 0); 157 - if (intf && !usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) { 158 - 159 - instance->int_urb = usb_alloc_urb(0, GFP_KERNEL); 160 - if (instance->int_urb) { 161 - 162 - usb_fill_int_urb(instance->int_urb, instance->u.usb_dev, 163 - usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT), 164 - instance->int_data, 165 - sizeof(instance->int_data), 166 - speedtch_handle_int, instance, 50); 167 - err = usb_submit_urb(instance->int_urb, GFP_KERNEL); 168 - if (err) { 169 - /* Doesn't matter; we'll poll anyway */ 170 - dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err); 171 - usb_free_urb(instance->int_urb); 172 - instance->int_urb = NULL; 173 - usb_driver_release_interface(&speedtch_usb_driver, intf); 174 - } 175 - } 176 - } 177 - /* Start status polling */ 178 - mod_timer(&instance->poll_timer, jiffies + (1 * HZ)); 179 - 180 - instance->u.status = UDSL_LOADED_FIRMWARE; 181 - tasklet_schedule(&instance->u.receive_tasklet); 182 - out: 183 - up(&instance->u.serialize); 184 - wake_up_interruptible(&instance->u.firmware_waiters); 185 - } 186 - 187 - static int speedtch_set_swbuff(struct speedtch_instance_data *instance, 188 - int state) 189 - { 190 - struct usb_device *dev = instance->u.usb_dev; 116 + struct usbatm_data *usbatm = instance->usbatm; 117 + struct usb_device *usb_dev = usbatm->usb_dev; 191 118 int ret; 192 119 193 - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 194 - 0x32, 0x40, state ? 0x01 : 0x00, 195 - 0x00, NULL, 0, 100); 196 - if (ret < 0) { 197 - printk("Warning: %sabling SW buffering: usb_control_msg returned %d\n", 198 - state ? "En" : "Dis", ret); 199 - return ret; 200 - } 201 - 202 - dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis"); 203 - return 0; 120 + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 121 + 0x32, 0x40, state ? 0x01 : 0x00, 0x00, NULL, 0, CTRL_TIMEOUT); 122 + if (ret < 0) 123 + usb_warn(usbatm, 124 + "%sabling SW buffering: usb_control_msg returned %d\n", 125 + state ? "En" : "Dis", ret); 126 + else 127 + dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis"); 204 128 } 205 129 206 130 static void speedtch_test_sequence(struct speedtch_instance_data *instance) 207 131 { 208 - struct usb_device *dev = instance->u.usb_dev; 209 - unsigned char buf[10]; 132 + struct usbatm_data *usbatm = instance->usbatm; 133 + struct usb_device *usb_dev = usbatm->usb_dev; 134 + unsigned char *buf = instance->scratch_buffer; 210 135 int ret; 211 136 212 137 /* URB 147 */ 213 138 buf[0] = 0x1c; 214 139 buf[1] = 0x50; 215 - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 216 - 0x01, 0x40, 0x0b, 0x00, buf, 2, 100); 140 + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 141 + 0x01, 0x40, 0x0b, 0x00, buf, 2, CTRL_TIMEOUT); 217 142 if (ret < 0) 218 - printk(KERN_WARNING "%s failed on URB147: %d\n", __func__, ret); 143 + usb_warn(usbatm, "%s failed on URB147: %d\n", __func__, ret); 219 144 220 145 /* URB 148 */ 221 146 buf[0] = 0x32; 222 147 buf[1] = 0x00; 223 - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 224 - 0x01, 0x40, 0x02, 0x00, buf, 2, 100); 148 + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 149 + 0x01, 0x40, 0x02, 0x00, buf, 2, CTRL_TIMEOUT); 225 150 if (ret < 0) 226 - printk(KERN_WARNING "%s failed on URB148: %d\n", __func__, ret); 151 + usb_warn(usbatm, "%s failed on URB148: %d\n", __func__, ret); 227 152 228 153 /* URB 149 */ 229 154 buf[0] = 0x01; 230 155 buf[1] = 0x00; 231 156 buf[2] = 0x01; 232 - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 233 - 0x01, 0x40, 0x03, 0x00, buf, 3, 100); 157 + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 158 + 0x01, 0x40, 0x03, 0x00, buf, 3, CTRL_TIMEOUT); 234 159 if (ret < 0) 235 - printk(KERN_WARNING "%s failed on URB149: %d\n", __func__, ret); 160 + usb_warn(usbatm, "%s failed on URB149: %d\n", __func__, ret); 236 161 237 162 /* URB 150 */ 238 163 buf[0] = 0x01; 239 164 buf[1] = 0x00; 240 165 buf[2] = 0x01; 241 - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 242 - 0x01, 0x40, 0x04, 0x00, buf, 3, 100); 166 + ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 167 + 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); 243 168 if (ret < 0) 244 - printk(KERN_WARNING "%s failed on URB150: %d\n", __func__, ret); 169 + usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); 245 170 } 246 171 247 - static int speedtch_start_synchro(struct speedtch_instance_data *instance) 248 - { 249 - struct usb_device *dev = instance->u.usb_dev; 250 - unsigned char buf[2]; 251 - int ret; 252 - 253 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 254 - 0x12, 0xc0, 0x04, 0x00, 255 - buf, sizeof(buf), CTRL_TIMEOUT); 256 - if (ret < 0) { 257 - printk(KERN_WARNING "SpeedTouch: Failed to start ADSL synchronisation: %d\n", ret); 258 - return ret; 259 - } 260 - 261 - dbg("speedtch_start_synchro: modem prodded. %d Bytes returned: %02x %02x", ret, buf[0], buf[1]); 262 - return 0; 263 - } 264 - 265 - static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs) 266 - { 267 - struct speedtch_instance_data *instance = urb->context; 268 - unsigned int count = urb->actual_length; 269 - int ret; 270 - 271 - /* The magic interrupt for "up state" */ 272 - const static unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; 273 - /* The magic interrupt for "down state" */ 274 - const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 }; 275 - 276 - switch (urb->status) { 277 - case 0: 278 - /* success */ 279 - break; 280 - case -ECONNRESET: 281 - case -ENOENT: 282 - case -ESHUTDOWN: 283 - /* this urb is terminated; clean up */ 284 - dbg("%s - urb shutting down with status: %d", __func__, urb->status); 285 - return; 286 - default: 287 - dbg("%s - nonzero urb status received: %d", __func__, urb->status); 288 - goto exit; 289 - } 290 - 291 - if (count < 6) { 292 - dbg("%s - int packet too short", __func__); 293 - goto exit; 294 - } 295 - 296 - if (!memcmp(up_int, instance->int_data, 6)) { 297 - del_timer(&instance->poll_timer); 298 - printk(KERN_NOTICE "DSL line goes up\n"); 299 - } else if (!memcmp(down_int, instance->int_data, 6)) { 300 - printk(KERN_NOTICE "DSL line goes down\n"); 301 - } else { 302 - int i; 303 - 304 - printk(KERN_DEBUG "Unknown interrupt packet of %d bytes:", count); 305 - for (i = 0; i < count; i++) 306 - printk(" %02x", instance->int_data[i]); 307 - printk("\n"); 308 - } 309 - schedule_work(&instance->poll_work); 310 - 311 - exit: 312 - rmb(); 313 - if (!instance->int_urb) 314 - return; 315 - 316 - ret = usb_submit_urb(urb, GFP_ATOMIC); 317 - if (ret) 318 - err("%s - usb_submit_urb failed with result %d", __func__, ret); 319 - } 320 - 321 - static int speedtch_get_status(struct speedtch_instance_data *instance, 322 - unsigned char *buf) 323 - { 324 - struct usb_device *dev = instance->u.usb_dev; 325 - int ret; 326 - 327 - memset(buf, 0, TOTAL); 328 - 329 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 330 - 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, 331 - CTRL_TIMEOUT); 332 - if (ret < 0) { 333 - dbg("MSG 7 failed"); 334 - return ret; 335 - } 336 - 337 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 338 - 0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b, 339 - CTRL_TIMEOUT); 340 - if (ret < 0) { 341 - dbg("MSG B failed"); 342 - return ret; 343 - } 344 - 345 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 346 - 0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d, 347 - CTRL_TIMEOUT); 348 - if (ret < 0) { 349 - dbg("MSG D failed"); 350 - return ret; 351 - } 352 - 353 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 354 - 0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e, 355 - CTRL_TIMEOUT); 356 - if (ret < 0) { 357 - dbg("MSG E failed"); 358 - return ret; 359 - } 360 - 361 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 362 - 0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f, 363 - CTRL_TIMEOUT); 364 - if (ret < 0) { 365 - dbg("MSG F failed"); 366 - return ret; 367 - } 368 - 369 - return 0; 370 - } 371 - 372 - static void speedtch_poll_status(struct speedtch_instance_data *instance) 373 - { 374 - unsigned char buf[TOTAL]; 375 - int ret; 376 - 377 - ret = speedtch_get_status(instance, buf); 378 - if (ret) { 379 - printk(KERN_WARNING 380 - "SpeedTouch: Error %d fetching device status\n", ret); 381 - return; 382 - } 383 - 384 - dbg("Line state %02x", buf[OFFSET_7]); 385 - 386 - switch (buf[OFFSET_7]) { 387 - case 0: 388 - if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { 389 - instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; 390 - printk(KERN_NOTICE "ADSL line is down\n"); 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, 172 + static int speedtch_upload_firmware(struct speedtch_instance_data *instance, 448 173 const struct firmware *fw1, 449 174 const struct firmware *fw2) 450 175 { 451 176 unsigned char *buffer; 452 - struct usb_device *usb_dev = instance->u.usb_dev; 177 + struct usbatm_data *usbatm = instance->usbatm; 453 178 struct usb_interface *intf; 454 - int actual_length, ret; 179 + struct usb_device *usb_dev = usbatm->usb_dev; 180 + int actual_length; 181 + int ret = 0; 455 182 int offset; 456 183 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 - } 184 + usb_dbg(usbatm, "%s entered\n", __func__); 463 185 464 186 if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) { 465 - dbg("speedtch_upload_firmware: no memory for buffer!"); 466 - goto fail; 187 + ret = -ENOMEM; 188 + usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__); 189 + goto out; 467 190 } 468 191 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; 192 + if (!(intf = usb_ifnum_to_if(usb_dev, 2))) { 193 + ret = -ENODEV; 194 + usb_dbg(usbatm, "%s: interface not found!\n", __func__); 195 + goto out_free; 474 196 } 475 197 476 198 /* URB 7 */ 477 199 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), 200 + ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), 479 201 buffer, 0x200, &actual_length, 2000); 480 202 481 203 if (ret < 0 && ret != -ETIMEDOUT) 482 - dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret); 204 + usb_dbg(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); 483 205 else 484 - dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret); 206 + usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret); 485 207 } 486 208 487 209 /* URB 8 : both leds are static green */ ··· 213 487 int thislen = min_t(int, PAGE_SIZE, fw1->size - offset); 214 488 memcpy(buffer, fw1->data + offset, thislen); 215 489 216 - ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 490 + ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE), 217 491 buffer, thislen, &actual_length, DATA_TIMEOUT); 218 492 219 493 if (ret < 0) { 220 - dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret); 221 - goto fail_release; 494 + usb_dbg(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); 495 + goto out_free; 222 496 } 223 - dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1->size); 497 + usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size); 224 498 } 225 499 226 500 /* USB led blinking green, ADSL led off */ 227 501 228 502 /* URB 11 */ 229 - ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 503 + ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), 230 504 buffer, 0x200, &actual_length, DATA_TIMEOUT); 231 505 232 506 if (ret < 0) { 233 - dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret); 234 - goto fail_release; 507 + usb_dbg(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); 508 + goto out_free; 235 509 } 236 - dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length); 510 + usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length); 237 511 238 512 /* URBs 12 to 139 - USB led blinking green, ADSL led off */ 239 513 for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) { 240 514 int thislen = min_t(int, PAGE_SIZE, fw2->size - offset); 241 515 memcpy(buffer, fw2->data + offset, thislen); 242 516 243 - ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 517 + ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE), 244 518 buffer, thislen, &actual_length, DATA_TIMEOUT); 245 519 246 520 if (ret < 0) { 247 - dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret); 248 - goto fail_release; 521 + usb_dbg(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); 522 + goto out_free; 249 523 } 250 524 } 251 - dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2->size); 525 + usb_dbg(usbatm, "%s: BLOCK3 uploaded (%zu bytes)\n", __func__, fw2->size); 252 526 253 527 /* USB led static green, ADSL led static red */ 254 528 255 529 /* URB 142 */ 256 - ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE), 530 + ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE), 257 531 buffer, 0x200, &actual_length, DATA_TIMEOUT); 258 532 259 533 if (ret < 0) { 260 - dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret); 261 - goto fail_release; 534 + usb_dbg(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); 535 + goto out_free; 262 536 } 263 537 264 538 /* success */ 265 - dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length); 539 + usb_dbg(usbatm, "%s: BLOCK4 downloaded (%d bytes)\n", __func__, actual_length); 266 540 267 541 /* Delay to allow firmware to start up. We can do this here 268 542 because we're in our own kernel thread anyway. */ 269 - msleep(1000); 543 + msleep_interruptible(1000); 270 544 271 545 /* Enable software buffering, if requested */ 272 546 if (sw_buffering) ··· 275 549 /* Magic spell; don't ask us what this does */ 276 550 speedtch_test_sequence(instance); 277 551 278 - /* Start modem synchronisation */ 279 - if (speedtch_start_synchro(instance)) 280 - dbg("speedtch_start_synchro: failed"); 552 + ret = 0; 281 553 282 - speedtch_got_firmware(instance, 1); 283 - 554 + out_free: 284 555 free_page((unsigned long)buffer); 285 - return; 286 - 287 - fail_release: 288 - /* Only release interface #2 if uploading failed; we don't release it 289 - we succeeded. This prevents the userspace tools from trying to load 290 - the firmware themselves */ 291 - usb_driver_release_interface(&speedtch_usb_driver, intf); 292 - fail_free: 293 - free_page((unsigned long)buffer); 294 - fail: 295 - speedtch_got_firmware(instance, 0); 556 + out: 557 + return ret; 296 558 } 297 559 298 - static int speedtch_find_firmware(struct speedtch_instance_data 299 - *instance, int phase, 560 + static int speedtch_find_firmware(struct usb_interface *intf, int phase, 300 561 const struct firmware **fw_p) 301 562 { 302 - char buf[24]; 303 - const u16 bcdDevice = le16_to_cpu(instance->u.usb_dev->descriptor.bcdDevice); 563 + struct device *dev = &intf->dev; 564 + const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice); 304 565 const u8 major_revision = bcdDevice >> 8; 305 566 const u8 minor_revision = bcdDevice & 0xff; 567 + char buf[24]; 306 568 307 569 sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); 308 - dbg("speedtch_find_firmware: looking for %s", buf); 570 + dev_dbg(dev, "%s: looking for %s\n", __func__, buf); 309 571 310 - if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { 572 + if (request_firmware(fw_p, buf, dev)) { 311 573 sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); 312 - dbg("speedtch_find_firmware: looking for %s", buf); 574 + dev_dbg(dev, "%s: looking for %s\n", __func__, buf); 313 575 314 - if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { 576 + if (request_firmware(fw_p, buf, dev)) { 315 577 sprintf(buf, "speedtch-%d.bin", phase); 316 - dbg("speedtch_find_firmware: looking for %s", buf); 578 + dev_dbg(dev, "%s: looking for %s\n", __func__, buf); 317 579 318 - if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) { 319 - dev_warn(&instance->u.usb_dev->dev, "no stage %d firmware found!", phase); 580 + if (request_firmware(fw_p, buf, dev)) { 581 + dev_warn(dev, "no stage %d firmware found!\n", phase); 320 582 return -ENOENT; 321 583 } 322 584 } 323 585 } 324 586 325 - dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf); 587 + dev_info(dev, "found stage %d firmware %s\n", phase, buf); 326 588 327 589 return 0; 328 590 } 329 591 330 - static int speedtch_load_firmware(void *arg) 592 + static int speedtch_heavy_init(struct usbatm_data *usbatm, struct usb_interface *intf) 331 593 { 332 594 const struct firmware *fw1, *fw2; 333 - struct speedtch_instance_data *instance = arg; 595 + struct speedtch_instance_data *instance = usbatm->driver_data; 596 + int ret; 334 597 335 - BUG_ON(!instance); 598 + if ((ret = speedtch_find_firmware(intf, 1, &fw1)) < 0) 599 + return ret; 336 600 337 - daemonize("firmware/speedtch"); 338 - 339 - if (!speedtch_find_firmware(instance, 1, &fw1)) { 340 - if (!speedtch_find_firmware(instance, 2, &fw2)) { 341 - speedtch_upload_firmware(instance, fw1, fw2); 342 - release_firmware(fw2); 343 - } 601 + if ((ret = speedtch_find_firmware(intf, 2, &fw2)) < 0) { 344 602 release_firmware(fw1); 603 + return ret; 345 604 } 346 605 347 - /* In case we failed, set state back to NO_FIRMWARE so that 348 - another later attempt may work. Otherwise, we never actually 349 - manage to recover if, for example, the firmware is on /usr and 350 - we look for it too early. */ 351 - speedtch_got_firmware(instance, 0); 606 + ret = speedtch_upload_firmware(instance, fw1, fw2); 352 607 353 - module_put(THIS_MODULE); 354 - udsl_put_instance(&instance->u); 608 + release_firmware(fw2); 609 + release_firmware(fw1); 610 + 611 + return ret; 612 + } 613 + 614 + 615 + /********** 616 + ** ATM ** 617 + **********/ 618 + 619 + static int speedtch_read_status(struct speedtch_instance_data *instance) 620 + { 621 + struct usbatm_data *usbatm = instance->usbatm; 622 + struct usb_device *usb_dev = usbatm->usb_dev; 623 + unsigned char *buf = instance->scratch_buffer; 624 + int ret; 625 + 626 + memset(buf, 0, TOTAL); 627 + 628 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 629 + 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, 630 + CTRL_TIMEOUT); 631 + if (ret < 0) { 632 + atm_dbg(usbatm, "%s: MSG 7 failed\n", __func__); 633 + return ret; 634 + } 635 + 636 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 637 + 0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b, 638 + CTRL_TIMEOUT); 639 + if (ret < 0) { 640 + atm_dbg(usbatm, "%s: MSG B failed\n", __func__); 641 + return ret; 642 + } 643 + 644 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 645 + 0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d, 646 + CTRL_TIMEOUT); 647 + if (ret < 0) { 648 + atm_dbg(usbatm, "%s: MSG D failed\n", __func__); 649 + return ret; 650 + } 651 + 652 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 653 + 0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e, 654 + CTRL_TIMEOUT); 655 + if (ret < 0) { 656 + atm_dbg(usbatm, "%s: MSG E failed\n", __func__); 657 + return ret; 658 + } 659 + 660 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 661 + 0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f, 662 + CTRL_TIMEOUT); 663 + if (ret < 0) { 664 + atm_dbg(usbatm, "%s: MSG F failed\n", __func__); 665 + return ret; 666 + } 667 + 355 668 return 0; 356 669 } 357 - #endif /* USE_FW_LOADER */ 358 670 359 - static void speedtch_firmware_start(struct speedtch_instance_data *instance) 671 + static int speedtch_start_synchro(struct speedtch_instance_data *instance) 360 672 { 361 - #ifdef USE_FW_LOADER 673 + struct usbatm_data *usbatm = instance->usbatm; 674 + struct usb_device *usb_dev = usbatm->usb_dev; 675 + unsigned char *buf = instance->scratch_buffer; 362 676 int ret; 363 - #endif 364 677 365 - dbg("speedtch_firmware_start"); 678 + atm_dbg(usbatm, "%s entered\n", __func__); 366 679 367 - down(&instance->u.serialize); /* vs self, speedtch_got_firmware */ 680 + memset(buf, 0, 2); 368 681 369 - if (instance->u.status >= UDSL_LOADING_FIRMWARE) { 370 - up(&instance->u.serialize); 682 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 683 + 0x12, 0xc0, 0x04, 0x00, 684 + buf, 2, CTRL_TIMEOUT); 685 + 686 + if (ret < 0) 687 + atm_warn(usbatm, "failed to start ADSL synchronisation: %d\n", ret); 688 + else 689 + atm_dbg(usbatm, "%s: modem prodded. %d bytes returned: %02x %02x\n", 690 + __func__, ret, buf[0], buf[1]); 691 + 692 + return ret; 693 + } 694 + 695 + static void speedtch_check_status(struct speedtch_instance_data *instance) 696 + { 697 + struct usbatm_data *usbatm = instance->usbatm; 698 + struct atm_dev *atm_dev = usbatm->atm_dev; 699 + unsigned char *buf = instance->scratch_buffer; 700 + int ret; 701 + 702 + atm_dbg(usbatm, "%s entered\n", __func__); 703 + 704 + ret = speedtch_read_status(instance); 705 + if (ret < 0) { 706 + atm_warn(usbatm, "error %d fetching device status\n", ret); 707 + if (instance->poll_delay < MAX_POLL_DELAY) 708 + instance->poll_delay *= 2; 371 709 return; 372 710 } 373 711 374 - instance->u.status = UDSL_LOADING_FIRMWARE; 375 - up(&instance->u.serialize); 712 + if (instance->poll_delay > MIN_POLL_DELAY) 713 + instance->poll_delay /= 2; 376 714 377 - #ifdef USE_FW_LOADER 378 - udsl_get_instance(&instance->u); 379 - try_module_get(THIS_MODULE); 715 + atm_dbg(usbatm, "%s: line state %02x\n", __func__, buf[OFFSET_7]); 380 716 381 - ret = kernel_thread(speedtch_load_firmware, instance, 382 - CLONE_FS | CLONE_FILES); 717 + switch (buf[OFFSET_7]) { 718 + case 0: 719 + if (atm_dev->signal != ATM_PHY_SIG_LOST) { 720 + atm_dev->signal = ATM_PHY_SIG_LOST; 721 + atm_info(usbatm, "ADSL line is down\n"); 722 + /* It'll never resync again unless we ask it to... */ 723 + ret = speedtch_start_synchro(instance); 724 + } 725 + break; 383 726 384 - if (ret >= 0) 385 - return; /* OK */ 727 + case 0x08: 728 + if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { 729 + atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 730 + atm_info(usbatm, "ADSL line is blocked?\n"); 731 + } 732 + break; 386 733 387 - dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret); 734 + case 0x10: 735 + if (atm_dev->signal != ATM_PHY_SIG_LOST) { 736 + atm_dev->signal = ATM_PHY_SIG_LOST; 737 + atm_info(usbatm, "ADSL line is synchronising\n"); 738 + } 739 + break; 388 740 389 - module_put(THIS_MODULE); 390 - udsl_put_instance(&instance->u); 391 - /* Just pretend it never happened... hope modem_run happens */ 392 - #endif /* USE_FW_LOADER */ 741 + case 0x20: 742 + if (atm_dev->signal != ATM_PHY_SIG_FOUND) { 743 + int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8) 744 + | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); 745 + int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) 746 + | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); 393 747 394 - speedtch_got_firmware(instance, 0); 748 + if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) { 749 + down_speed >>= 16; 750 + up_speed >>= 16; 751 + } 752 + 753 + atm_dev->link_rate = down_speed * 1000 / 424; 754 + atm_dev->signal = ATM_PHY_SIG_FOUND; 755 + 756 + atm_info(usbatm, 757 + "ADSL line is up (%d Kib/s down | %d Kib/s up)\n", 758 + down_speed, up_speed); 759 + } 760 + break; 761 + 762 + default: 763 + if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { 764 + atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 765 + atm_info(usbatm, "Unknown line state %02x\n", buf[OFFSET_7]); 766 + } 767 + break; 768 + } 395 769 } 396 770 397 - static int speedtch_firmware_wait(struct udsl_instance_data *instance) 771 + static void speedtch_status_poll(unsigned long data) 398 772 { 399 - speedtch_firmware_start((void *)instance); 773 + struct speedtch_instance_data *instance = (void *)data; 400 774 401 - if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0) 402 - return -ERESTARTSYS; 775 + schedule_work(&instance->status_checker); 403 776 404 - return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN; 777 + /* The following check is racy, but the race is harmless */ 778 + if (instance->poll_delay < MAX_POLL_DELAY) 779 + mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(instance->poll_delay)); 780 + else 781 + atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n"); 405 782 } 783 + 784 + static void speedtch_resubmit_int(unsigned long data) 785 + { 786 + struct speedtch_instance_data *instance = (void *)data; 787 + struct urb *int_urb = instance->int_urb; 788 + int ret; 789 + 790 + atm_dbg(instance->usbatm, "%s entered\n", __func__); 791 + 792 + if (int_urb) { 793 + ret = usb_submit_urb(int_urb, GFP_ATOMIC); 794 + if (!ret) 795 + schedule_work(&instance->status_checker); 796 + else { 797 + atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); 798 + mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); 799 + } 800 + } 801 + } 802 + 803 + static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs) 804 + { 805 + struct speedtch_instance_data *instance = int_urb->context; 806 + struct usbatm_data *usbatm = instance->usbatm; 807 + unsigned int count = int_urb->actual_length; 808 + int ret = int_urb->status; 809 + 810 + /* The magic interrupt for "up state" */ 811 + const static unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; 812 + /* The magic interrupt for "down state" */ 813 + const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 }; 814 + 815 + atm_dbg(usbatm, "%s entered\n", __func__); 816 + 817 + if (ret < 0) { 818 + atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret); 819 + goto fail; 820 + } 821 + 822 + if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) { 823 + del_timer(&instance->status_checker.timer); 824 + atm_info(usbatm, "DSL line goes up\n"); 825 + } else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) { 826 + atm_info(usbatm, "DSL line goes down\n"); 827 + } else { 828 + int i; 829 + 830 + atm_dbg(usbatm, "%s: unknown interrupt packet of length %d:", __func__, count); 831 + for (i = 0; i < count; i++) 832 + printk(" %02x", instance->int_data[i]); 833 + printk("\n"); 834 + goto fail; 835 + } 836 + 837 + if ((int_urb = instance->int_urb)) { 838 + ret = usb_submit_urb(int_urb, GFP_ATOMIC); 839 + schedule_work(&instance->status_checker); 840 + if (ret < 0) { 841 + atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); 842 + goto fail; 843 + } 844 + } 845 + 846 + return; 847 + 848 + fail: 849 + if ((int_urb = instance->int_urb)) 850 + mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); 851 + } 852 + 853 + static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_dev) 854 + { 855 + struct usb_device *usb_dev = usbatm->usb_dev; 856 + struct speedtch_instance_data *instance = usbatm->driver_data; 857 + int i, ret; 858 + unsigned char mac_str[13]; 859 + 860 + atm_dbg(usbatm, "%s entered\n", __func__); 861 + 862 + if ((ret = usb_set_interface(usb_dev, 1, altsetting)) < 0) { 863 + atm_dbg(usbatm, "%s: usb_set_interface returned %d!\n", __func__, ret); 864 + return ret; 865 + } 866 + 867 + /* Set MAC address, it is stored in the serial number */ 868 + memset(atm_dev->esi, 0, sizeof(atm_dev->esi)); 869 + if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { 870 + for (i = 0; i < 6; i++) 871 + atm_dev->esi[i] = (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1])); 872 + } 873 + 874 + /* Start modem synchronisation */ 875 + ret = speedtch_start_synchro(instance); 876 + 877 + /* Set up interrupt endpoint */ 878 + if (instance->int_urb) { 879 + ret = usb_submit_urb(instance->int_urb, GFP_KERNEL); 880 + if (ret < 0) { 881 + /* Doesn't matter; we'll poll anyway */ 882 + atm_dbg(usbatm, "%s: submission of interrupt URB failed (%d)!\n", __func__, ret); 883 + usb_free_urb(instance->int_urb); 884 + instance->int_urb = NULL; 885 + } 886 + } 887 + 888 + /* Start status polling */ 889 + mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(1000)); 890 + 891 + return 0; 892 + } 893 + 894 + static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_dev) 895 + { 896 + struct speedtch_instance_data *instance = usbatm->driver_data; 897 + struct urb *int_urb = instance->int_urb; 898 + 899 + atm_dbg(usbatm, "%s entered\n", __func__); 900 + 901 + del_timer_sync(&instance->status_checker.timer); 902 + 903 + /* 904 + * Since resubmit_timer and int_urb can schedule themselves and 905 + * each other, shutting them down correctly takes some care 906 + */ 907 + instance->int_urb = NULL; /* signal shutdown */ 908 + mb(); 909 + usb_kill_urb(int_urb); 910 + del_timer_sync(&instance->resubmit_timer); 911 + /* 912 + * At this point, speedtch_handle_int and speedtch_resubmit_int 913 + * can run or be running, but instance->int_urb == NULL means that 914 + * they will not reschedule 915 + */ 916 + usb_kill_urb(int_urb); 917 + del_timer_sync(&instance->resubmit_timer); 918 + usb_free_urb(int_urb); 919 + 920 + flush_scheduled_work(); 921 + } 922 + 406 923 407 924 /********** 408 925 ** USB ** 409 926 **********/ 410 927 411 - static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code, 412 - void *user_data) 413 - { 414 - struct speedtch_instance_data *instance = usb_get_intfdata(intf); 928 + static struct usb_device_id speedtch_usb_ids[] = { 929 + {USB_DEVICE(0x06b9, 0x4061)}, 930 + {} 931 + }; 415 932 416 - dbg("speedtch_usb_ioctl entered"); 933 + MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); 417 934 418 - if (!instance) { 419 - dbg("speedtch_usb_ioctl: NULL instance!"); 420 - return -ENODEV; 421 - } 935 + static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); 422 936 423 - switch (code) { 424 - case UDSL_IOCTL_LINE_UP: 425 - instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND; 426 - speedtch_got_firmware(instance, 1); 427 - return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO; 428 - case UDSL_IOCTL_LINE_DOWN: 429 - instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; 430 - return 0; 431 - default: 432 - return -ENOTTY; 433 - } 937 + static struct usb_driver speedtch_usb_driver = { 938 + .owner = THIS_MODULE, 939 + .name = speedtch_driver_name, 940 + .probe = speedtch_usb_probe, 941 + .disconnect = usbatm_usb_disconnect, 942 + .id_table = speedtch_usb_ids 943 + }; 944 + 945 + static void speedtch_release_interfaces(struct usb_device *usb_dev, int num_interfaces) { 946 + struct usb_interface *cur_intf; 947 + int i; 948 + 949 + for(i = 0; i < num_interfaces; i++) 950 + if ((cur_intf = usb_ifnum_to_if(usb_dev, i))) { 951 + usb_set_intfdata(cur_intf, NULL); 952 + usb_driver_release_interface(&speedtch_usb_driver, cur_intf); 953 + } 434 954 } 435 955 436 - static int speedtch_usb_probe(struct usb_interface *intf, 437 - const struct usb_device_id *id) 956 + static int speedtch_bind(struct usbatm_data *usbatm, 957 + struct usb_interface *intf, 958 + const struct usb_device_id *id, 959 + int *need_heavy_init) 438 960 { 439 - struct usb_device *dev = interface_to_usbdev(intf); 440 - int ifnum = intf->altsetting->desc.bInterfaceNumber; 961 + struct usb_device *usb_dev = interface_to_usbdev(intf); 962 + struct usb_interface *cur_intf; 441 963 struct speedtch_instance_data *instance; 442 - unsigned char mac_str[13]; 443 - int ret, i; 444 - char buf7[SIZE_7]; 964 + int ifnum = intf->altsetting->desc.bInterfaceNumber; 965 + int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; 966 + int i, ret; 445 967 446 - dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", 447 - le16_to_cpu(dev->descriptor.idVendor), 448 - le16_to_cpu(dev->descriptor.idProduct), ifnum); 968 + usb_dbg(usbatm, "%s entered\n", __func__); 449 969 450 - if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || 451 - (ifnum != 1)) 970 + if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { 971 + usb_dbg(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass); 452 972 return -ENODEV; 973 + } 453 974 454 - dbg("speedtch_usb_probe: device accepted"); 975 + /* claim all interfaces */ 455 976 456 - /* instance init */ 977 + for (i=0; i < num_interfaces; i++) { 978 + cur_intf = usb_ifnum_to_if(usb_dev, i); 979 + 980 + if ((i != ifnum) && cur_intf) { 981 + ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm); 982 + 983 + if (ret < 0) { 984 + usb_dbg(usbatm, "%s: failed to claim interface %d (%d)\n", __func__, i, ret); 985 + speedtch_release_interfaces(usb_dev, i); 986 + return ret; 987 + } 988 + } 989 + } 990 + 457 991 instance = kmalloc(sizeof(*instance), GFP_KERNEL); 992 + 458 993 if (!instance) { 459 - dbg("speedtch_usb_probe: no memory for instance data!"); 460 - return -ENOMEM; 994 + usb_dbg(usbatm, "%s: no memory for instance data!\n", __func__); 995 + ret = -ENOMEM; 996 + goto fail_release; 461 997 } 462 998 463 999 memset(instance, 0, sizeof(struct speedtch_instance_data)); 464 1000 465 - if ((ret = usb_set_interface(dev, 0, 0)) < 0) 466 - goto fail; 1001 + instance->usbatm = usbatm; 467 1002 468 - if ((ret = usb_set_interface(dev, 2, 0)) < 0) 469 - goto fail; 1003 + INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); 470 1004 471 - instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA; 472 - instance->u.firmware_wait = speedtch_firmware_wait; 473 - instance->u.driver_name = speedtch_driver_name; 1005 + instance->status_checker.timer.function = speedtch_status_poll; 1006 + instance->status_checker.timer.data = (unsigned long)instance; 1007 + instance->poll_delay = MIN_POLL_DELAY; 474 1008 475 - ret = udsl_instance_setup(dev, &instance->u); 476 - if (ret) 477 - goto fail; 1009 + init_timer(&instance->resubmit_timer); 1010 + instance->resubmit_timer.function = speedtch_resubmit_int; 1011 + instance->resubmit_timer.data = (unsigned long)instance; 478 1012 479 - init_timer(&instance->poll_timer); 480 - instance->poll_timer.function = speedtch_timer_poll; 481 - instance->poll_timer.data = (unsigned long)instance; 1013 + instance->int_urb = usb_alloc_urb(0, GFP_KERNEL); 482 1014 483 - INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance); 1015 + if (instance->int_urb) 1016 + usb_fill_int_urb(instance->int_urb, usb_dev, 1017 + usb_rcvintpipe(usb_dev, ENDPOINT_INT), 1018 + instance->int_data, sizeof(instance->int_data), 1019 + speedtch_handle_int, instance, 50); 1020 + else 1021 + usb_dbg(usbatm, "%s: no memory for interrupt urb!\n", __func__); 484 1022 485 - /* set MAC address, it is stored in the serial number */ 486 - memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi)); 487 - if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { 488 - for (i = 0; i < 6; i++) 489 - instance->u.atm_dev->esi[i] = 490 - (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1])); 491 - } 1023 + /* check whether the modem already seems to be alive */ 1024 + ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 1025 + 0x12, 0xc0, 0x07, 0x00, 1026 + instance->scratch_buffer + OFFSET_7, SIZE_7, 500); 492 1027 493 - /* First check whether the modem already seems to be alive */ 494 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 495 - 0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, 500); 1028 + *need_heavy_init = (ret != SIZE_7); 496 1029 497 - if (ret == SIZE_7) { 498 - dbg("firmware appears to be already loaded"); 499 - speedtch_got_firmware(instance, 1); 500 - speedtch_poll_status(instance); 501 - } else { 502 - speedtch_firmware_start(instance); 503 - } 1030 + usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already"); 504 1031 505 - usb_set_intfdata(intf, instance); 1032 + if (*need_heavy_init) 1033 + if ((ret = usb_reset_device(usb_dev)) < 0) 1034 + goto fail_free; 1035 + 1036 + usbatm->driver_data = instance; 506 1037 507 1038 return 0; 508 1039 509 - fail: 1040 + fail_free: 1041 + usb_free_urb(instance->int_urb); 510 1042 kfree(instance); 511 - 512 - return -ENOMEM; 1043 + fail_release: 1044 + speedtch_release_interfaces(usb_dev, num_interfaces); 1045 + return ret; 513 1046 } 514 1047 515 - static void speedtch_usb_disconnect(struct usb_interface *intf) 1048 + static void speedtch_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) 516 1049 { 517 - struct speedtch_instance_data *instance = usb_get_intfdata(intf); 1050 + struct usb_device *usb_dev = interface_to_usbdev(intf); 1051 + struct speedtch_instance_data *instance = usbatm->driver_data; 518 1052 519 - dbg("speedtch_usb_disconnect entered"); 1053 + usb_dbg(usbatm, "%s entered\n", __func__); 520 1054 521 - if (!instance) { 522 - dbg("speedtch_usb_disconnect: NULL instance!"); 523 - return; 524 - } 525 - 526 - /*QQ need to handle disconnects on interface #2 while uploading firmware */ 527 - /*QQ and what about interface #1? */ 528 - 529 - if (instance->int_urb) { 530 - struct urb *int_urb = instance->int_urb; 531 - instance->int_urb = NULL; 532 - wmb(); 533 - usb_unlink_urb(int_urb); 534 - usb_free_urb(int_urb); 535 - } 536 - 537 - instance->int_data[0] = 1; 538 - del_timer_sync(&instance->poll_timer); 539 - wmb(); 540 - flush_scheduled_work(); 541 - 542 - udsl_instance_disconnect(&instance->u); 543 - 544 - /* clean up */ 545 - usb_set_intfdata(intf, NULL); 546 - udsl_put_instance(&instance->u); 1055 + speedtch_release_interfaces(usb_dev, usb_dev->actconfig->desc.bNumInterfaces); 1056 + usb_free_urb(instance->int_urb); 1057 + kfree(instance); 547 1058 } 1059 + 548 1060 549 1061 /*********** 550 1062 ** init ** 551 1063 ***********/ 552 1064 1065 + static struct usbatm_driver speedtch_usbatm_driver = { 1066 + .owner = THIS_MODULE, 1067 + .driver_name = speedtch_driver_name, 1068 + .bind = speedtch_bind, 1069 + .heavy_init = speedtch_heavy_init, 1070 + .unbind = speedtch_unbind, 1071 + .atm_start = speedtch_atm_start, 1072 + .atm_stop = speedtch_atm_stop, 1073 + .in = ENDPOINT_DATA, 1074 + .out = ENDPOINT_DATA 1075 + }; 1076 + 1077 + static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 1078 + { 1079 + return usbatm_usb_probe(intf, id, &speedtch_usbatm_driver); 1080 + } 1081 + 553 1082 static int __init speedtch_usb_init(void) 554 1083 { 555 - dbg("speedtch_usb_init: driver version " DRIVER_VERSION); 1084 + dbg("%s: driver version %s", __func__, DRIVER_VERSION); 556 1085 557 1086 return usb_register(&speedtch_usb_driver); 558 1087 } 559 1088 560 1089 static void __exit speedtch_usb_cleanup(void) 561 1090 { 562 - dbg("speedtch_usb_cleanup entered"); 1091 + dbg("%s", __func__); 563 1092 564 1093 usb_deregister(&speedtch_usb_driver); 565 1094 }