aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/atm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 11:48:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 11:48:58 -0500
commit7f5b09c15ab989ed5ce4adda0be42c1302df70b7 (patch)
tree9695b00983d1bd077ff91c463abcb136330cf344 /drivers/usb/atm
parent94468080220162f74dc6ce5c3e95e5fec8022902 (diff)
parentcedf8a78421943441b9011ce7bcdab55f07d2ea6 (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.c192
-rw-r--r--drivers/usb/atm/usbatm.c3
-rw-r--r--drivers/usb/atm/usbatm.h15
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
49static const char cxacru_driver_name[] = "cxacru"; 50static 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 */
125enum 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 */
109enum cxacru_cm_status { 131enum 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)
196static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ 218static 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) \
222static 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) \
200static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ 226static 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} \
208CXACRU__ATTR_INIT(_name) 237CXACRU__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
218static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) 249static 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)
267static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) 298static 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)
288static ssize_t cxacru_sysfs_show_mac_address(struct device *dev, 319static 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
298static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, 332static 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,
312static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, 349static 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
451static 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); \
442CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ 547CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \
443CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ 548CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \
444CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \ 549CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \
445CXACRU_CMD_##_action( adsl_state); 550CXACRU_CMD_##_action( adsl_state); \
551CXACRU_SET_##_action( adsl_config);
446 552
447CXACRU_ALL_FILES(INIT); 553CXACRU_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
874static void cxacru_upload_firmware(struct cxacru_data *instance, 980static 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
983static int cxacru_find_firmware(struct cxacru_data *instance, 1070static int cxacru_find_firmware(struct cxacru_data *instance,
@@ -1003,7 +1090,7 @@ static int cxacru_find_firmware(struct cxacru_data *instance,
1003static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, 1090static 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
207static 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_ */