diff options
Diffstat (limited to 'drivers/usb/atm/speedtch.c')
-rw-r--r-- | drivers/usb/atm/speedtch.c | 167 |
1 files changed, 120 insertions, 47 deletions
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index c1b47d74e206..7860c8a5800d 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -35,12 +35,14 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/stat.h> | 36 | #include <linux/stat.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/types.h> | ||
39 | #include <linux/usb_ch9.h> | ||
38 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
39 | 41 | ||
40 | #include "usbatm.h" | 42 | #include "usbatm.h" |
41 | 43 | ||
42 | #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>" | 44 | #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>" |
43 | #define DRIVER_VERSION "1.9" | 45 | #define DRIVER_VERSION "1.10" |
44 | #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION | 46 | #define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION |
45 | 47 | ||
46 | static const char speedtch_driver_name[] = "speedtch"; | 48 | static const char speedtch_driver_name[] = "speedtch"; |
@@ -66,31 +68,42 @@ static const char speedtch_driver_name[] = "speedtch"; | |||
66 | 68 | ||
67 | #define RESUBMIT_DELAY 1000 /* milliseconds */ | 69 | #define RESUBMIT_DELAY 1000 /* milliseconds */ |
68 | 70 | ||
69 | #define DEFAULT_ALTSETTING 1 | 71 | #define DEFAULT_BULK_ALTSETTING 1 |
72 | #define DEFAULT_ISOC_ALTSETTING 2 | ||
70 | #define DEFAULT_DL_512_FIRST 0 | 73 | #define DEFAULT_DL_512_FIRST 0 |
74 | #define DEFAULT_ENABLE_ISOC 0 | ||
71 | #define DEFAULT_SW_BUFFERING 0 | 75 | #define DEFAULT_SW_BUFFERING 0 |
72 | 76 | ||
73 | static int altsetting = DEFAULT_ALTSETTING; | 77 | static unsigned int altsetting = 0; /* zero means: use the default */ |
74 | static int dl_512_first = DEFAULT_DL_512_FIRST; | 78 | static int dl_512_first = DEFAULT_DL_512_FIRST; |
79 | static int enable_isoc = DEFAULT_ENABLE_ISOC; | ||
75 | static int sw_buffering = DEFAULT_SW_BUFFERING; | 80 | static int sw_buffering = DEFAULT_SW_BUFFERING; |
76 | 81 | ||
77 | module_param(altsetting, int, S_IRUGO | S_IWUSR); | 82 | module_param(altsetting, uint, S_IRUGO | S_IWUSR); |
78 | MODULE_PARM_DESC(altsetting, | 83 | MODULE_PARM_DESC(altsetting, |
79 | "Alternative setting for data interface (default: " | 84 | "Alternative setting for data interface (bulk_default: " |
80 | __MODULE_STRING(DEFAULT_ALTSETTING) ")"); | 85 | __MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: " |
86 | __MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")"); | ||
81 | 87 | ||
82 | module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); | 88 | module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); |
83 | MODULE_PARM_DESC(dl_512_first, | 89 | MODULE_PARM_DESC(dl_512_first, |
84 | "Read 512 bytes before sending firmware (default: " | 90 | "Read 512 bytes before sending firmware (default: " |
85 | __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); | 91 | __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); |
86 | 92 | ||
93 | module_param(enable_isoc, bool, S_IRUGO | S_IWUSR); | ||
94 | MODULE_PARM_DESC(enable_isoc, | ||
95 | "Use isochronous transfers if available (default: " | ||
96 | __MODULE_STRING(DEFAULT_ENABLE_ISOC) ")"); | ||
97 | |||
87 | module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); | 98 | module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); |
88 | MODULE_PARM_DESC(sw_buffering, | 99 | MODULE_PARM_DESC(sw_buffering, |
89 | "Enable software buffering (default: " | 100 | "Enable software buffering (default: " |
90 | __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); | 101 | __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); |
91 | 102 | ||
103 | #define INTERFACE_DATA 1 | ||
92 | #define ENDPOINT_INT 0x81 | 104 | #define ENDPOINT_INT 0x81 |
93 | #define ENDPOINT_DATA 0x07 | 105 | #define ENDPOINT_BULK_DATA 0x07 |
106 | #define ENDPOINT_ISOC_DATA 0x07 | ||
94 | #define ENDPOINT_FIRMWARE 0x05 | 107 | #define ENDPOINT_FIRMWARE 0x05 |
95 | 108 | ||
96 | #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) | 109 | #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) |
@@ -98,6 +111,8 @@ MODULE_PARM_DESC(sw_buffering, | |||
98 | struct speedtch_instance_data { | 111 | struct speedtch_instance_data { |
99 | struct usbatm_data *usbatm; | 112 | struct usbatm_data *usbatm; |
100 | 113 | ||
114 | unsigned int altsetting; | ||
115 | |||
101 | struct work_struct status_checker; | 116 | struct work_struct status_checker; |
102 | 117 | ||
103 | unsigned char last_status; | 118 | unsigned char last_status; |
@@ -205,7 +220,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
205 | buffer, 0x200, &actual_length, 2000); | 220 | buffer, 0x200, &actual_length, 2000); |
206 | 221 | ||
207 | if (ret < 0 && ret != -ETIMEDOUT) | 222 | if (ret < 0 && ret != -ETIMEDOUT) |
208 | usb_dbg(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); | 223 | usb_warn(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret); |
209 | else | 224 | else |
210 | usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret); | 225 | usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret); |
211 | } | 226 | } |
@@ -219,7 +234,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
219 | buffer, thislen, &actual_length, DATA_TIMEOUT); | 234 | buffer, thislen, &actual_length, DATA_TIMEOUT); |
220 | 235 | ||
221 | if (ret < 0) { | 236 | if (ret < 0) { |
222 | usb_dbg(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); | 237 | usb_err(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret); |
223 | goto out_free; | 238 | goto out_free; |
224 | } | 239 | } |
225 | usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size); | 240 | usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size); |
@@ -232,7 +247,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
232 | buffer, 0x200, &actual_length, DATA_TIMEOUT); | 247 | buffer, 0x200, &actual_length, DATA_TIMEOUT); |
233 | 248 | ||
234 | if (ret < 0) { | 249 | if (ret < 0) { |
235 | usb_dbg(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); | 250 | usb_err(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret); |
236 | goto out_free; | 251 | goto out_free; |
237 | } | 252 | } |
238 | usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length); | 253 | usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length); |
@@ -246,7 +261,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
246 | buffer, thislen, &actual_length, DATA_TIMEOUT); | 261 | buffer, thislen, &actual_length, DATA_TIMEOUT); |
247 | 262 | ||
248 | if (ret < 0) { | 263 | if (ret < 0) { |
249 | usb_dbg(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); | 264 | usb_err(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret); |
250 | goto out_free; | 265 | goto out_free; |
251 | } | 266 | } |
252 | } | 267 | } |
@@ -259,7 +274,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
259 | buffer, 0x200, &actual_length, DATA_TIMEOUT); | 274 | buffer, 0x200, &actual_length, DATA_TIMEOUT); |
260 | 275 | ||
261 | if (ret < 0) { | 276 | if (ret < 0) { |
262 | usb_dbg(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); | 277 | usb_err(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret); |
263 | goto out_free; | 278 | goto out_free; |
264 | } | 279 | } |
265 | 280 | ||
@@ -270,6 +285,11 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
270 | because we're in our own kernel thread anyway. */ | 285 | because we're in our own kernel thread anyway. */ |
271 | msleep_interruptible(1000); | 286 | msleep_interruptible(1000); |
272 | 287 | ||
288 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { | ||
289 | usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret); | ||
290 | goto out_free; | ||
291 | } | ||
292 | |||
273 | /* Enable software buffering, if requested */ | 293 | /* Enable software buffering, if requested */ |
274 | if (sw_buffering) | 294 | if (sw_buffering) |
275 | speedtch_set_swbuff(instance, 1); | 295 | speedtch_set_swbuff(instance, 1); |
@@ -285,8 +305,8 @@ out: | |||
285 | return ret; | 305 | return ret; |
286 | } | 306 | } |
287 | 307 | ||
288 | static int speedtch_find_firmware(struct usb_interface *intf, int phase, | 308 | static int speedtch_find_firmware(struct usbatm_data *usbatm, struct usb_interface *intf, |
289 | const struct firmware **fw_p) | 309 | int phase, const struct firmware **fw_p) |
290 | { | 310 | { |
291 | struct device *dev = &intf->dev; | 311 | struct device *dev = &intf->dev; |
292 | const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice); | 312 | const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice); |
@@ -295,24 +315,24 @@ static int speedtch_find_firmware(struct usb_interface *intf, int phase, | |||
295 | char buf[24]; | 315 | char buf[24]; |
296 | 316 | ||
297 | sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); | 317 | sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); |
298 | dev_dbg(dev, "%s: looking for %s\n", __func__, buf); | 318 | usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); |
299 | 319 | ||
300 | if (request_firmware(fw_p, buf, dev)) { | 320 | if (request_firmware(fw_p, buf, dev)) { |
301 | sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); | 321 | sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); |
302 | dev_dbg(dev, "%s: looking for %s\n", __func__, buf); | 322 | usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); |
303 | 323 | ||
304 | if (request_firmware(fw_p, buf, dev)) { | 324 | if (request_firmware(fw_p, buf, dev)) { |
305 | sprintf(buf, "speedtch-%d.bin", phase); | 325 | sprintf(buf, "speedtch-%d.bin", phase); |
306 | dev_dbg(dev, "%s: looking for %s\n", __func__, buf); | 326 | usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); |
307 | 327 | ||
308 | if (request_firmware(fw_p, buf, dev)) { | 328 | if (request_firmware(fw_p, buf, dev)) { |
309 | dev_warn(dev, "no stage %d firmware found!\n", phase); | 329 | usb_err(usbatm, "%s: no stage %d firmware found!\n", __func__, phase); |
310 | return -ENOENT; | 330 | return -ENOENT; |
311 | } | 331 | } |
312 | } | 332 | } |
313 | } | 333 | } |
314 | 334 | ||
315 | dev_info(dev, "found stage %d firmware %s\n", phase, buf); | 335 | usb_info(usbatm, "found stage %d firmware %s\n", phase, buf); |
316 | 336 | ||
317 | return 0; | 337 | return 0; |
318 | } | 338 | } |
@@ -323,15 +343,16 @@ static int speedtch_heavy_init(struct usbatm_data *usbatm, struct usb_interface | |||
323 | struct speedtch_instance_data *instance = usbatm->driver_data; | 343 | struct speedtch_instance_data *instance = usbatm->driver_data; |
324 | int ret; | 344 | int ret; |
325 | 345 | ||
326 | if ((ret = speedtch_find_firmware(intf, 1, &fw1)) < 0) | 346 | if ((ret = speedtch_find_firmware(usbatm, intf, 1, &fw1)) < 0) |
327 | return ret; | 347 | return ret; |
328 | 348 | ||
329 | if ((ret = speedtch_find_firmware(intf, 2, &fw2)) < 0) { | 349 | if ((ret = speedtch_find_firmware(usbatm, intf, 2, &fw2)) < 0) { |
330 | release_firmware(fw1); | 350 | release_firmware(fw1); |
331 | return ret; | 351 | return ret; |
332 | } | 352 | } |
333 | 353 | ||
334 | ret = speedtch_upload_firmware(instance, fw1, fw2); | 354 | if ((ret = speedtch_upload_firmware(instance, fw1, fw2)) < 0) |
355 | usb_err(usbatm, "%s: firmware upload failed (%d)!\n", __func__, ret); | ||
335 | 356 | ||
336 | release_firmware(fw2); | 357 | release_firmware(fw2); |
337 | release_firmware(fw1); | 358 | release_firmware(fw1); |
@@ -428,7 +449,9 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) | |||
428 | int down_speed, up_speed, ret; | 449 | int down_speed, up_speed, ret; |
429 | unsigned char status; | 450 | unsigned char status; |
430 | 451 | ||
452 | #ifdef VERBOSE_DEBUG | ||
431 | atm_dbg(usbatm, "%s entered\n", __func__); | 453 | atm_dbg(usbatm, "%s entered\n", __func__); |
454 | #endif | ||
432 | 455 | ||
433 | ret = speedtch_read_status(instance); | 456 | ret = speedtch_read_status(instance); |
434 | if (ret < 0) { | 457 | if (ret < 0) { |
@@ -441,9 +464,9 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) | |||
441 | 464 | ||
442 | status = buf[OFFSET_7]; | 465 | status = buf[OFFSET_7]; |
443 | 466 | ||
444 | atm_dbg(usbatm, "%s: line state %02x\n", __func__, status); | ||
445 | |||
446 | if ((status != instance->last_status) || !status) { | 467 | if ((status != instance->last_status) || !status) { |
468 | atm_dbg(usbatm, "%s: line state 0x%02x\n", __func__, status); | ||
469 | |||
447 | switch (status) { | 470 | switch (status) { |
448 | case 0: | 471 | case 0: |
449 | atm_dev->signal = ATM_PHY_SIG_LOST; | 472 | atm_dev->signal = ATM_PHY_SIG_LOST; |
@@ -484,7 +507,7 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) | |||
484 | 507 | ||
485 | default: | 508 | default: |
486 | atm_dev->signal = ATM_PHY_SIG_UNKNOWN; | 509 | atm_dev->signal = ATM_PHY_SIG_UNKNOWN; |
487 | atm_info(usbatm, "Unknown line state %02x\n", status); | 510 | atm_info(usbatm, "unknown line state %02x\n", status); |
488 | break; | 511 | break; |
489 | } | 512 | } |
490 | 513 | ||
@@ -583,11 +606,6 @@ static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_de | |||
583 | 606 | ||
584 | atm_dbg(usbatm, "%s entered\n", __func__); | 607 | atm_dbg(usbatm, "%s entered\n", __func__); |
585 | 608 | ||
586 | if ((ret = usb_set_interface(usb_dev, 1, altsetting)) < 0) { | ||
587 | atm_dbg(usbatm, "%s: usb_set_interface returned %d!\n", __func__, ret); | ||
588 | return ret; | ||
589 | } | ||
590 | |||
591 | /* Set MAC address, it is stored in the serial number */ | 609 | /* Set MAC address, it is stored in the serial number */ |
592 | memset(atm_dev->esi, 0, sizeof(atm_dev->esi)); | 610 | memset(atm_dev->esi, 0, sizeof(atm_dev->esi)); |
593 | if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { | 611 | if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { |
@@ -678,20 +696,27 @@ static void speedtch_release_interfaces(struct usb_device *usb_dev, int num_inte | |||
678 | 696 | ||
679 | static int speedtch_bind(struct usbatm_data *usbatm, | 697 | static int speedtch_bind(struct usbatm_data *usbatm, |
680 | struct usb_interface *intf, | 698 | struct usb_interface *intf, |
681 | const struct usb_device_id *id, | 699 | const struct usb_device_id *id) |
682 | int *need_heavy_init) | ||
683 | { | 700 | { |
684 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 701 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
685 | struct usb_interface *cur_intf; | 702 | struct usb_interface *cur_intf, *data_intf; |
686 | struct speedtch_instance_data *instance; | 703 | struct speedtch_instance_data *instance; |
687 | int ifnum = intf->altsetting->desc.bInterfaceNumber; | 704 | int ifnum = intf->altsetting->desc.bInterfaceNumber; |
688 | int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; | 705 | int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; |
689 | int i, ret; | 706 | int i, ret; |
707 | int use_isoc; | ||
690 | 708 | ||
691 | usb_dbg(usbatm, "%s entered\n", __func__); | 709 | usb_dbg(usbatm, "%s entered\n", __func__); |
692 | 710 | ||
711 | /* sanity checks */ | ||
712 | |||
693 | if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { | 713 | if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { |
694 | usb_dbg(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass); | 714 | usb_err(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass); |
715 | return -ENODEV; | ||
716 | } | ||
717 | |||
718 | if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) { | ||
719 | usb_err(usbatm, "%s: data interface not found!\n", __func__); | ||
695 | return -ENODEV; | 720 | return -ENODEV; |
696 | } | 721 | } |
697 | 722 | ||
@@ -704,25 +729,71 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
704 | ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm); | 729 | ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm); |
705 | 730 | ||
706 | if (ret < 0) { | 731 | if (ret < 0) { |
707 | usb_dbg(usbatm, "%s: failed to claim interface %d (%d)\n", __func__, i, ret); | 732 | usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, i, ret); |
708 | speedtch_release_interfaces(usb_dev, i); | 733 | speedtch_release_interfaces(usb_dev, i); |
709 | return ret; | 734 | return ret; |
710 | } | 735 | } |
711 | } | 736 | } |
712 | } | 737 | } |
713 | 738 | ||
714 | instance = kmalloc(sizeof(*instance), GFP_KERNEL); | 739 | instance = kzalloc(sizeof(*instance), GFP_KERNEL); |
715 | 740 | ||
716 | if (!instance) { | 741 | if (!instance) { |
717 | usb_dbg(usbatm, "%s: no memory for instance data!\n", __func__); | 742 | usb_err(usbatm, "%s: no memory for instance data!\n", __func__); |
718 | ret = -ENOMEM; | 743 | ret = -ENOMEM; |
719 | goto fail_release; | 744 | goto fail_release; |
720 | } | 745 | } |
721 | 746 | ||
722 | memset(instance, 0, sizeof(struct speedtch_instance_data)); | ||
723 | |||
724 | instance->usbatm = usbatm; | 747 | instance->usbatm = usbatm; |
725 | 748 | ||
749 | /* altsetting and enable_isoc may change at any moment, so take a snapshot */ | ||
750 | instance->altsetting = altsetting; | ||
751 | use_isoc = enable_isoc; | ||
752 | |||
753 | if (instance->altsetting) | ||
754 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { | ||
755 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret); | ||
756 | instance->altsetting = 0; /* fall back to default */ | ||
757 | } | ||
758 | |||
759 | if (!instance->altsetting && use_isoc) | ||
760 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { | ||
761 | usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); | ||
762 | use_isoc = 0; /* fall back to bulk */ | ||
763 | } | ||
764 | |||
765 | if (use_isoc) { | ||
766 | const struct usb_host_interface *desc = data_intf->cur_altsetting; | ||
767 | const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in; | ||
768 | int i; | ||
769 | |||
770 | use_isoc = 0; /* fall back to bulk if endpoint not found */ | ||
771 | |||
772 | for (i=0; i<desc->desc.bNumEndpoints; i++) { | ||
773 | const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc; | ||
774 | |||
775 | if ((endpoint_desc->bEndpointAddress == target_address)) { | ||
776 | use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
777 | USB_ENDPOINT_XFER_ISOC; | ||
778 | break; | ||
779 | } | ||
780 | } | ||
781 | |||
782 | if (!use_isoc) | ||
783 | usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); | ||
784 | } | ||
785 | |||
786 | if (!use_isoc && !instance->altsetting) | ||
787 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { | ||
788 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); | ||
789 | goto fail_free; | ||
790 | } | ||
791 | |||
792 | if (!instance->altsetting) | ||
793 | instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; | ||
794 | |||
795 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); | ||
796 | |||
726 | INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); | 797 | INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); |
727 | 798 | ||
728 | instance->status_checker.timer.function = speedtch_status_poll; | 799 | instance->status_checker.timer.function = speedtch_status_poll; |
@@ -749,13 +820,15 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
749 | 0x12, 0xc0, 0x07, 0x00, | 820 | 0x12, 0xc0, 0x07, 0x00, |
750 | instance->scratch_buffer + OFFSET_7, SIZE_7, 500); | 821 | instance->scratch_buffer + OFFSET_7, SIZE_7, 500); |
751 | 822 | ||
752 | *need_heavy_init = (ret != SIZE_7); | 823 | usbatm->flags |= (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); |
753 | 824 | ||
754 | usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already"); | 825 | usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not"); |
755 | 826 | ||
756 | if (*need_heavy_init) | 827 | if (!(usbatm->flags & UDSL_SKIP_HEAVY_INIT)) |
757 | if ((ret = usb_reset_device(usb_dev)) < 0) | 828 | if ((ret = usb_reset_device(usb_dev)) < 0) { |
829 | usb_err(usbatm, "%s: device reset failed (%d)!\n", __func__, ret); | ||
758 | goto fail_free; | 830 | goto fail_free; |
831 | } | ||
759 | 832 | ||
760 | usbatm->driver_data = instance; | 833 | usbatm->driver_data = instance; |
761 | 834 | ||
@@ -787,15 +860,15 @@ static void speedtch_unbind(struct usbatm_data *usbatm, struct usb_interface *in | |||
787 | ***********/ | 860 | ***********/ |
788 | 861 | ||
789 | static struct usbatm_driver speedtch_usbatm_driver = { | 862 | static struct usbatm_driver speedtch_usbatm_driver = { |
790 | .owner = THIS_MODULE, | ||
791 | .driver_name = speedtch_driver_name, | 863 | .driver_name = speedtch_driver_name, |
792 | .bind = speedtch_bind, | 864 | .bind = speedtch_bind, |
793 | .heavy_init = speedtch_heavy_init, | 865 | .heavy_init = speedtch_heavy_init, |
794 | .unbind = speedtch_unbind, | 866 | .unbind = speedtch_unbind, |
795 | .atm_start = speedtch_atm_start, | 867 | .atm_start = speedtch_atm_start, |
796 | .atm_stop = speedtch_atm_stop, | 868 | .atm_stop = speedtch_atm_stop, |
797 | .in = ENDPOINT_DATA, | 869 | .bulk_in = ENDPOINT_BULK_DATA, |
798 | .out = ENDPOINT_DATA | 870 | .bulk_out = ENDPOINT_BULK_DATA, |
871 | .isoc_in = ENDPOINT_ISOC_DATA | ||
799 | }; | 872 | }; |
800 | 873 | ||
801 | static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | 874 | static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) |