diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-03 11:48:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-03 11:48:58 -0500 |
commit | 7f5b09c15ab989ed5ce4adda0be42c1302df70b7 (patch) | |
tree | 9695b00983d1bd077ff91c463abcb136330cf344 /drivers/usb/atm | |
parent | 94468080220162f74dc6ce5c3e95e5fec8022902 (diff) | |
parent | cedf8a78421943441b9011ce7bcdab55f07d2ea6 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (220 commits)
USB: backlight, appledisplay: fix incomplete registration failure handling
USB: pl2303: remove unnecessary reset of usb_device in urbs
USB: ftdi_sio: remove obsolete check in unthrottle
USB: ftdi_sio: remove unused tx_bytes counter
USB: qcaux: driver for auxiliary serial ports on Qualcomm devices
USB: pl2303: initial TIOCGSERIAL support
USB: option: add Longcheer/Longsung vendor ID
USB: fix I2C API usage in ohci-pnx4008.
USB: usbmon: mask seconds properly in text API
USB: sisusbvga: no unnecessary GFP_ATOMIC
USB: storage: onetouch: unnecessary GFP_ATOMIC
USB: serial: ftdi: add CONTEC vendor and product id
USB: remove references to port->port.count from the serial drivers
USB: tty: Prune uses of tty_request_room in the USB layer
USB: tty: Add a function to insert a string of characters with the same flag
USB: don't read past config->interface[] if usb_control_msg() fails in usb_reset_configuration()
USB: tty: kill request_room for USB ACM class
USB: tty: sort out the request_room handling for whiteheat
USB: storage: fix misplaced parenthesis
USB: vstusb.c: removal of driver for Vernier Software & Technology, Inc., devices and spectrometers
...
Diffstat (limited to 'drivers/usb/atm')
-rw-r--r-- | drivers/usb/atm/cxacru.c | 192 | ||||
-rw-r--r-- | drivers/usb/atm/usbatm.c | 3 | ||||
-rw-r--r-- | drivers/usb/atm/usbatm.h | 15 |
3 files changed, 154 insertions, 56 deletions
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 56802d2e994b..c89990f5e018 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan | 5 | * Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan |
6 | * Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru) | 6 | * Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru) |
7 | * Copyright (C) 2007 Simon Arlott | 7 | * Copyright (C) 2007 Simon Arlott |
8 | * Copyright (C) 2009 Simon Arlott | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
@@ -43,7 +44,7 @@ | |||
43 | #include "usbatm.h" | 44 | #include "usbatm.h" |
44 | 45 | ||
45 | #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" | 46 | #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" |
46 | #define DRIVER_VERSION "0.3" | 47 | #define DRIVER_VERSION "0.4" |
47 | #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" | 48 | #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" |
48 | 49 | ||
49 | static const char cxacru_driver_name[] = "cxacru"; | 50 | static const char cxacru_driver_name[] = "cxacru"; |
@@ -52,6 +53,7 @@ static const char cxacru_driver_name[] = "cxacru"; | |||
52 | #define CXACRU_EP_DATA 0x02 /* Bulk in/out */ | 53 | #define CXACRU_EP_DATA 0x02 /* Bulk in/out */ |
53 | 54 | ||
54 | #define CMD_PACKET_SIZE 64 /* Should be maxpacket(ep)? */ | 55 | #define CMD_PACKET_SIZE 64 /* Should be maxpacket(ep)? */ |
56 | #define CMD_MAX_CONFIG ((CMD_PACKET_SIZE / 4 - 1) / 2) | ||
55 | 57 | ||
56 | /* Addresses */ | 58 | /* Addresses */ |
57 | #define PLLFCLK_ADDR 0x00350068 | 59 | #define PLLFCLK_ADDR 0x00350068 |
@@ -105,6 +107,26 @@ enum cxacru_cm_request { | |||
105 | CM_REQUEST_MAX, | 107 | CM_REQUEST_MAX, |
106 | }; | 108 | }; |
107 | 109 | ||
110 | /* commands for interaction with the flash memory | ||
111 | * | ||
112 | * read: response is the contents of the first 60 bytes of flash memory | ||
113 | * write: request contains the 60 bytes of data to write to flash memory | ||
114 | * response is the contents of the first 60 bytes of flash memory | ||
115 | * | ||
116 | * layout: PP PP VV VV MM MM MM MM MM MM ?? ?? SS SS SS SS SS SS SS SS | ||
117 | * SS SS SS SS SS SS SS SS 00 00 00 00 00 00 00 00 00 00 00 00 | ||
118 | * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
119 | * | ||
120 | * P: le16 USB Product ID | ||
121 | * V: le16 USB Vendor ID | ||
122 | * M: be48 MAC Address | ||
123 | * S: le16 ASCII Serial Number | ||
124 | */ | ||
125 | enum cxacru_cm_flash { | ||
126 | CM_FLASH_READ = 0xa1, | ||
127 | CM_FLASH_WRITE = 0xa2 | ||
128 | }; | ||
129 | |||
108 | /* reply codes to the commands above */ | 130 | /* reply codes to the commands above */ |
109 | enum cxacru_cm_status { | 131 | enum cxacru_cm_status { |
110 | CM_STATUS_UNDEFINED, | 132 | CM_STATUS_UNDEFINED, |
@@ -196,23 +218,32 @@ static DEVICE_ATTR(_name, S_IRUGO, cxacru_sysfs_show_##_name, NULL) | |||
196 | static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ | 218 | static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ |
197 | cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name) | 219 | cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name) |
198 | 220 | ||
221 | #define CXACRU_SET_INIT(_name) \ | ||
222 | static DEVICE_ATTR(_name, S_IWUSR, \ | ||
223 | NULL, cxacru_sysfs_store_##_name) | ||
224 | |||
199 | #define CXACRU_ATTR_INIT(_value, _type, _name) \ | 225 | #define CXACRU_ATTR_INIT(_value, _type, _name) \ |
200 | static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ | 226 | static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ |
201 | struct device_attribute *attr, char *buf) \ | 227 | struct device_attribute *attr, char *buf) \ |
202 | { \ | 228 | { \ |
203 | struct usb_interface *intf = to_usb_interface(dev); \ | 229 | struct cxacru_data *instance = to_usbatm_driver_data(\ |
204 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); \ | 230 | to_usb_interface(dev)); \ |
205 | struct cxacru_data *instance = usbatm_instance->driver_data; \ | 231 | \ |
232 | if (instance == NULL) \ | ||
233 | return -ENODEV; \ | ||
234 | \ | ||
206 | return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \ | 235 | return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \ |
207 | } \ | 236 | } \ |
208 | CXACRU__ATTR_INIT(_name) | 237 | CXACRU__ATTR_INIT(_name) |
209 | 238 | ||
210 | #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name) | 239 | #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name) |
211 | #define CXACRU_CMD_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) | 240 | #define CXACRU_CMD_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) |
241 | #define CXACRU_SET_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) | ||
212 | #define CXACRU__ATTR_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) | 242 | #define CXACRU__ATTR_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) |
213 | 243 | ||
214 | #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name) | 244 | #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name) |
215 | #define CXACRU_CMD_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) | 245 | #define CXACRU_CMD_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) |
246 | #define CXACRU_SET_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) | ||
216 | #define CXACRU__ATTR_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) | 247 | #define CXACRU__ATTR_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) |
217 | 248 | ||
218 | static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) | 249 | static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) |
@@ -267,12 +298,12 @@ static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf) | |||
267 | static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) | 298 | static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) |
268 | { | 299 | { |
269 | static char *str[] = { | 300 | static char *str[] = { |
270 | NULL, | 301 | "", |
271 | "ANSI T1.413", | 302 | "ANSI T1.413", |
272 | "ITU-T G.992.1 (G.DMT)", | 303 | "ITU-T G.992.1 (G.DMT)", |
273 | "ITU-T G.992.2 (G.LITE)" | 304 | "ITU-T G.992.2 (G.LITE)" |
274 | }; | 305 | }; |
275 | if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL)) | 306 | if (unlikely(value >= ARRAY_SIZE(str))) |
276 | return snprintf(buf, PAGE_SIZE, "%u\n", value); | 307 | return snprintf(buf, PAGE_SIZE, "%u\n", value); |
277 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); | 308 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); |
278 | } | 309 | } |
@@ -288,22 +319,28 @@ static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) | |||
288 | static ssize_t cxacru_sysfs_show_mac_address(struct device *dev, | 319 | static ssize_t cxacru_sysfs_show_mac_address(struct device *dev, |
289 | struct device_attribute *attr, char *buf) | 320 | struct device_attribute *attr, char *buf) |
290 | { | 321 | { |
291 | struct usb_interface *intf = to_usb_interface(dev); | 322 | struct cxacru_data *instance = to_usbatm_driver_data( |
292 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); | 323 | to_usb_interface(dev)); |
293 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; | ||
294 | 324 | ||
295 | return snprintf(buf, PAGE_SIZE, "%pM\n", atm_dev->esi); | 325 | if (instance == NULL || instance->usbatm->atm_dev == NULL) |
326 | return -ENODEV; | ||
327 | |||
328 | return snprintf(buf, PAGE_SIZE, "%pM\n", | ||
329 | instance->usbatm->atm_dev->esi); | ||
296 | } | 330 | } |
297 | 331 | ||
298 | static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, | 332 | static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, |
299 | struct device_attribute *attr, char *buf) | 333 | struct device_attribute *attr, char *buf) |
300 | { | 334 | { |
301 | struct usb_interface *intf = to_usb_interface(dev); | ||
302 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); | ||
303 | struct cxacru_data *instance = usbatm_instance->driver_data; | ||
304 | u32 value = instance->card_info[CXINF_LINE_STARTABLE]; | ||
305 | |||
306 | static char *str[] = { "running", "stopped" }; | 335 | static char *str[] = { "running", "stopped" }; |
336 | struct cxacru_data *instance = to_usbatm_driver_data( | ||
337 | to_usb_interface(dev)); | ||
338 | u32 value; | ||
339 | |||
340 | if (instance == NULL) | ||
341 | return -ENODEV; | ||
342 | |||
343 | value = instance->card_info[CXINF_LINE_STARTABLE]; | ||
307 | if (unlikely(value >= ARRAY_SIZE(str))) | 344 | if (unlikely(value >= ARRAY_SIZE(str))) |
308 | return snprintf(buf, PAGE_SIZE, "%u\n", value); | 345 | return snprintf(buf, PAGE_SIZE, "%u\n", value); |
309 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); | 346 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); |
@@ -312,9 +349,8 @@ static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, | |||
312 | static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | 349 | static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, |
313 | struct device_attribute *attr, const char *buf, size_t count) | 350 | struct device_attribute *attr, const char *buf, size_t count) |
314 | { | 351 | { |
315 | struct usb_interface *intf = to_usb_interface(dev); | 352 | struct cxacru_data *instance = to_usbatm_driver_data( |
316 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); | 353 | to_usb_interface(dev)); |
317 | struct cxacru_data *instance = usbatm_instance->driver_data; | ||
318 | int ret; | 354 | int ret; |
319 | int poll = -1; | 355 | int poll = -1; |
320 | char str_cmd[8]; | 356 | char str_cmd[8]; |
@@ -328,13 +364,16 @@ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | |||
328 | return -EINVAL; | 364 | return -EINVAL; |
329 | ret = 0; | 365 | ret = 0; |
330 | 366 | ||
367 | if (instance == NULL) | ||
368 | return -ENODEV; | ||
369 | |||
331 | if (mutex_lock_interruptible(&instance->adsl_state_serialize)) | 370 | if (mutex_lock_interruptible(&instance->adsl_state_serialize)) |
332 | return -ERESTARTSYS; | 371 | return -ERESTARTSYS; |
333 | 372 | ||
334 | if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) { | 373 | if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) { |
335 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0); | 374 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0); |
336 | if (ret < 0) { | 375 | if (ret < 0) { |
337 | atm_err(usbatm_instance, "change adsl state:" | 376 | atm_err(instance->usbatm, "change adsl state:" |
338 | " CHIP_ADSL_LINE_STOP returned %d\n", ret); | 377 | " CHIP_ADSL_LINE_STOP returned %d\n", ret); |
339 | 378 | ||
340 | ret = -EIO; | 379 | ret = -EIO; |
@@ -354,7 +393,7 @@ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | |||
354 | if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) { | 393 | if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) { |
355 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); | 394 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); |
356 | if (ret < 0) { | 395 | if (ret < 0) { |
357 | atm_err(usbatm_instance, "change adsl state:" | 396 | atm_err(instance->usbatm, "change adsl state:" |
358 | " CHIP_ADSL_LINE_START returned %d\n", ret); | 397 | " CHIP_ADSL_LINE_START returned %d\n", ret); |
359 | 398 | ||
360 | ret = -EIO; | 399 | ret = -EIO; |
@@ -407,6 +446,72 @@ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | |||
407 | return ret; | 446 | return ret; |
408 | } | 447 | } |
409 | 448 | ||
449 | /* CM_REQUEST_CARD_DATA_GET times out, so no show attribute */ | ||
450 | |||
451 | static ssize_t cxacru_sysfs_store_adsl_config(struct device *dev, | ||
452 | struct device_attribute *attr, const char *buf, size_t count) | ||
453 | { | ||
454 | struct cxacru_data *instance = to_usbatm_driver_data( | ||
455 | to_usb_interface(dev)); | ||
456 | int len = strlen(buf); | ||
457 | int ret, pos, num; | ||
458 | __le32 data[CMD_PACKET_SIZE / 4]; | ||
459 | |||
460 | if (!capable(CAP_NET_ADMIN)) | ||
461 | return -EACCES; | ||
462 | |||
463 | if (instance == NULL) | ||
464 | return -ENODEV; | ||
465 | |||
466 | pos = 0; | ||
467 | num = 0; | ||
468 | while (pos < len) { | ||
469 | int tmp; | ||
470 | u32 index; | ||
471 | u32 value; | ||
472 | |||
473 | ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp); | ||
474 | if (ret < 2) | ||
475 | return -EINVAL; | ||
476 | if (index < 0 || index > 0x7f) | ||
477 | return -EINVAL; | ||
478 | pos += tmp; | ||
479 | |||
480 | /* skip trailing newline */ | ||
481 | if (buf[pos] == '\n' && pos == len-1) | ||
482 | pos++; | ||
483 | |||
484 | data[num * 2 + 1] = cpu_to_le32(index); | ||
485 | data[num * 2 + 2] = cpu_to_le32(value); | ||
486 | num++; | ||
487 | |||
488 | /* send config values when data buffer is full | ||
489 | * or no more data | ||
490 | */ | ||
491 | if (pos >= len || num >= CMD_MAX_CONFIG) { | ||
492 | char log[CMD_MAX_CONFIG * 12 + 1]; /* %02x=%08x */ | ||
493 | |||
494 | data[0] = cpu_to_le32(num); | ||
495 | ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, | ||
496 | (u8 *) data, 4 + num * 8, NULL, 0); | ||
497 | if (ret < 0) { | ||
498 | atm_err(instance->usbatm, | ||
499 | "set card data returned %d\n", ret); | ||
500 | return -EIO; | ||
501 | } | ||
502 | |||
503 | for (tmp = 0; tmp < num; tmp++) | ||
504 | snprintf(log + tmp*12, 13, " %02x=%08x", | ||
505 | le32_to_cpu(data[tmp * 2 + 1]), | ||
506 | le32_to_cpu(data[tmp * 2 + 2])); | ||
507 | atm_info(instance->usbatm, "config%s\n", log); | ||
508 | num = 0; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | return len; | ||
513 | } | ||
514 | |||
410 | /* | 515 | /* |
411 | * All device attributes are included in CXACRU_ALL_FILES | 516 | * All device attributes are included in CXACRU_ALL_FILES |
412 | * so that the same list can be used multiple times: | 517 | * so that the same list can be used multiple times: |
@@ -442,7 +547,8 @@ CXACRU_ATTR_##_action(CXINF_MODULATION, MODU, modulation); \ | |||
442 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ | 547 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ |
443 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ | 548 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ |
444 | CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \ | 549 | CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \ |
445 | CXACRU_CMD_##_action( adsl_state); | 550 | CXACRU_CMD_##_action( adsl_state); \ |
551 | CXACRU_SET_##_action( adsl_config); | ||
446 | 552 | ||
447 | CXACRU_ALL_FILES(INIT); | 553 | CXACRU_ALL_FILES(INIT); |
448 | 554 | ||
@@ -596,7 +702,7 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ | |||
596 | len = ret / 4; | 702 | len = ret / 4; |
597 | for (offb = 0; offb < len; ) { | 703 | for (offb = 0; offb < len; ) { |
598 | int l = le32_to_cpu(buf[offb++]); | 704 | int l = le32_to_cpu(buf[offb++]); |
599 | if (l > stride || l > (len - offb) / 2) { | 705 | if (l < 0 || l > stride || l > (len - offb) / 2) { |
600 | if (printk_ratelimit()) | 706 | if (printk_ratelimit()) |
601 | usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", | 707 | usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", |
602 | cm, l); | 708 | cm, l); |
@@ -649,9 +755,6 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
649 | { | 755 | { |
650 | struct cxacru_data *instance = usbatm_instance->driver_data; | 756 | struct cxacru_data *instance = usbatm_instance->driver_data; |
651 | struct usb_interface *intf = usbatm_instance->usb_intf; | 757 | struct usb_interface *intf = usbatm_instance->usb_intf; |
652 | /* | ||
653 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; | ||
654 | */ | ||
655 | int ret; | 758 | int ret; |
656 | int start_polling = 1; | 759 | int start_polling = 1; |
657 | 760 | ||
@@ -697,6 +800,9 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
697 | mutex_unlock(&instance->poll_state_serialize); | 800 | mutex_unlock(&instance->poll_state_serialize); |
698 | mutex_unlock(&instance->adsl_state_serialize); | 801 | mutex_unlock(&instance->adsl_state_serialize); |
699 | 802 | ||
803 | printk(KERN_INFO "%s%d: %s %pM\n", atm_dev->type, atm_dev->number, | ||
804 | usbatm_instance->description, atm_dev->esi); | ||
805 | |||
700 | if (start_polling) | 806 | if (start_polling) |
701 | cxacru_poll_status(&instance->poll_work.work); | 807 | cxacru_poll_status(&instance->poll_work.work); |
702 | return 0; | 808 | return 0; |
@@ -873,11 +979,9 @@ cleanup: | |||
873 | 979 | ||
874 | static void cxacru_upload_firmware(struct cxacru_data *instance, | 980 | static void cxacru_upload_firmware(struct cxacru_data *instance, |
875 | const struct firmware *fw, | 981 | const struct firmware *fw, |
876 | const struct firmware *bp, | 982 | const struct firmware *bp) |
877 | const struct firmware *cf) | ||
878 | { | 983 | { |
879 | int ret; | 984 | int ret; |
880 | int off; | ||
881 | struct usbatm_data *usbatm = instance->usbatm; | 985 | struct usbatm_data *usbatm = instance->usbatm; |
882 | struct usb_device *usb_dev = usbatm->usb_dev; | 986 | struct usb_device *usb_dev = usbatm->usb_dev; |
883 | __le16 signature[] = { usb_dev->descriptor.idVendor, | 987 | __le16 signature[] = { usb_dev->descriptor.idVendor, |
@@ -911,6 +1015,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
911 | } | 1015 | } |
912 | 1016 | ||
913 | /* Firmware */ | 1017 | /* Firmware */ |
1018 | usb_info(usbatm, "loading firmware\n"); | ||
914 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); | 1019 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); |
915 | if (ret) { | 1020 | if (ret) { |
916 | usb_err(usbatm, "Firmware upload failed: %d\n", ret); | 1021 | usb_err(usbatm, "Firmware upload failed: %d\n", ret); |
@@ -919,6 +1024,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
919 | 1024 | ||
920 | /* Boot ROM patch */ | 1025 | /* Boot ROM patch */ |
921 | if (instance->modem_type->boot_rom_patch) { | 1026 | if (instance->modem_type->boot_rom_patch) { |
1027 | usb_info(usbatm, "loading boot ROM patch\n"); | ||
922 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); | 1028 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); |
923 | if (ret) { | 1029 | if (ret) { |
924 | usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); | 1030 | usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); |
@@ -933,6 +1039,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
933 | return; | 1039 | return; |
934 | } | 1040 | } |
935 | 1041 | ||
1042 | usb_info(usbatm, "starting device\n"); | ||
936 | if (instance->modem_type->boot_rom_patch) { | 1043 | if (instance->modem_type->boot_rom_patch) { |
937 | val = cpu_to_le32(BR_ADDR); | 1044 | val = cpu_to_le32(BR_ADDR); |
938 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); | 1045 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); |
@@ -958,26 +1065,6 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
958 | usb_err(usbatm, "modem failed to initialize: %d\n", ret); | 1065 | usb_err(usbatm, "modem failed to initialize: %d\n", ret); |
959 | return; | 1066 | return; |
960 | } | 1067 | } |
961 | |||
962 | /* Load config data (le32), doing one packet at a time */ | ||
963 | if (cf) | ||
964 | for (off = 0; off < cf->size / 4; ) { | ||
965 | __le32 buf[CMD_PACKET_SIZE / 4 - 1]; | ||
966 | int i, len = min_t(int, cf->size / 4 - off, CMD_PACKET_SIZE / 4 / 2 - 1); | ||
967 | buf[0] = cpu_to_le32(len); | ||
968 | for (i = 0; i < len; i++, off++) { | ||
969 | buf[i * 2 + 1] = cpu_to_le32(off); | ||
970 | memcpy(buf + i * 2 + 2, cf->data + off * 4, 4); | ||
971 | } | ||
972 | ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, | ||
973 | (u8 *) buf, len, NULL, 0); | ||
974 | if (ret < 0) { | ||
975 | usb_err(usbatm, "load config data failed: %d\n", ret); | ||
976 | return; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | msleep_interruptible(4000); | ||
981 | } | 1068 | } |
982 | 1069 | ||
983 | static int cxacru_find_firmware(struct cxacru_data *instance, | 1070 | static int cxacru_find_firmware(struct cxacru_data *instance, |
@@ -1003,7 +1090,7 @@ static int cxacru_find_firmware(struct cxacru_data *instance, | |||
1003 | static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, | 1090 | static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, |
1004 | struct usb_interface *usb_intf) | 1091 | struct usb_interface *usb_intf) |
1005 | { | 1092 | { |
1006 | const struct firmware *fw, *bp, *cf; | 1093 | const struct firmware *fw, *bp; |
1007 | struct cxacru_data *instance = usbatm_instance->driver_data; | 1094 | struct cxacru_data *instance = usbatm_instance->driver_data; |
1008 | 1095 | ||
1009 | int ret = cxacru_find_firmware(instance, "fw", &fw); | 1096 | int ret = cxacru_find_firmware(instance, "fw", &fw); |
@@ -1021,13 +1108,8 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, | |||
1021 | } | 1108 | } |
1022 | } | 1109 | } |
1023 | 1110 | ||
1024 | if (cxacru_find_firmware(instance, "cf", &cf)) /* optional */ | 1111 | cxacru_upload_firmware(instance, fw, bp); |
1025 | cf = NULL; | ||
1026 | |||
1027 | cxacru_upload_firmware(instance, fw, bp, cf); | ||
1028 | 1112 | ||
1029 | if (cf) | ||
1030 | release_firmware(cf); | ||
1031 | if (instance->modem_type->boot_rom_patch) | 1113 | if (instance->modem_type->boot_rom_patch) |
1032 | release_firmware(bp); | 1114 | release_firmware(bp); |
1033 | release_firmware(fw); | 1115 | release_firmware(fw); |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index fbea8563df1e..9b53e8df4648 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -1333,6 +1333,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf) | |||
1333 | if (instance->atm_dev) { | 1333 | if (instance->atm_dev) { |
1334 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); | 1334 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); |
1335 | atm_dev_deregister(instance->atm_dev); | 1335 | atm_dev_deregister(instance->atm_dev); |
1336 | instance->atm_dev = NULL; | ||
1336 | } | 1337 | } |
1337 | 1338 | ||
1338 | usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ | 1339 | usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ |
@@ -1348,7 +1349,7 @@ static int __init usbatm_usb_init(void) | |||
1348 | { | 1349 | { |
1349 | dbg("%s: driver version %s", __func__, DRIVER_VERSION); | 1350 | dbg("%s: driver version %s", __func__, DRIVER_VERSION); |
1350 | 1351 | ||
1351 | if (sizeof(struct usbatm_control) > sizeof(((struct sk_buff *) 0)->cb)) { | 1352 | if (sizeof(struct usbatm_control) > FIELD_SIZEOF(struct sk_buff, cb)) { |
1352 | printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name); | 1353 | printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name); |
1353 | return -EIO; | 1354 | return -EIO; |
1354 | } | 1355 | } |
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index f6f4508a9d42..0863f85fcc26 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h | |||
@@ -204,4 +204,19 @@ struct usbatm_data { | |||
204 | struct urb *urbs[0]; | 204 | struct urb *urbs[0]; |
205 | }; | 205 | }; |
206 | 206 | ||
207 | static inline void *to_usbatm_driver_data(struct usb_interface *intf) | ||
208 | { | ||
209 | struct usbatm_data *usbatm_instance; | ||
210 | |||
211 | if (intf == NULL) | ||
212 | return NULL; | ||
213 | |||
214 | usbatm_instance = usb_get_intfdata(intf); | ||
215 | |||
216 | if (usbatm_instance == NULL) /* set NULL before unbind() */ | ||
217 | return NULL; | ||
218 | |||
219 | return usbatm_instance->driver_data; /* set NULL after unbind() */ | ||
220 | } | ||
221 | |||
207 | #endif /* _USBATM_H_ */ | 222 | #endif /* _USBATM_H_ */ |