aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.c
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
committerMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
commit2d8ad8719591fa803b0d589ed057fa46f49b7155 (patch)
tree4ae051577dad1161c91dafbf4207bb10a9dc91bb /drivers/usb/class/cdc-acm.c
parent9b4ce7bce5f30712fd926ab4599a803314a07719 (diff)
parentc56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (diff)
Merge commit 'v2.6.38-rc1' into kbuild/packaging
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r--drivers/usb/class/cdc-acm.c151
1 files changed, 98 insertions, 53 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 34d4eb98829e..d6ede989ff22 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -2,7 +2,7 @@
2 * cdc-acm.c 2 * cdc-acm.c
3 * 3 *
4 * Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de> 4 * Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de>
5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> 5 * Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> 6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com>
7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> 7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> 8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name>
@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
170{ 170{
171 wb->use = 0; 171 wb->use = 0;
172 acm->transmitting--; 172 acm->transmitting--;
173 usb_autopm_put_interface_async(acm->control);
173} 174}
174 175
175/* 176/*
@@ -211,9 +212,12 @@ static int acm_write_start(struct acm *acm, int wbn)
211 } 212 }
212 213
213 dbg("%s susp_count: %d", __func__, acm->susp_count); 214 dbg("%s susp_count: %d", __func__, acm->susp_count);
215 usb_autopm_get_interface_async(acm->control);
214 if (acm->susp_count) { 216 if (acm->susp_count) {
215 acm->delayed_wb = wb; 217 if (!acm->delayed_wb)
216 schedule_work(&acm->waker); 218 acm->delayed_wb = wb;
219 else
220 usb_autopm_put_interface_async(acm->control);
217 spin_unlock_irqrestore(&acm->write_lock, flags); 221 spin_unlock_irqrestore(&acm->write_lock, flags);
218 return 0; /* A white lie */ 222 return 0; /* A white lie */
219 } 223 }
@@ -424,7 +428,6 @@ next_buffer:
424 throttled = acm->throttle; 428 throttled = acm->throttle;
425 spin_unlock_irqrestore(&acm->throttle_lock, flags); 429 spin_unlock_irqrestore(&acm->throttle_lock, flags);
426 if (!throttled) { 430 if (!throttled) {
427 tty_buffer_request_room(tty, buf->size);
428 tty_insert_flip_string(tty, buf->base, buf->size); 431 tty_insert_flip_string(tty, buf->base, buf->size);
429 tty_flip_buffer_push(tty); 432 tty_flip_buffer_push(tty);
430 } else { 433 } else {
@@ -534,23 +537,6 @@ static void acm_softint(struct work_struct *work)
534 tty_kref_put(tty); 537 tty_kref_put(tty);
535} 538}
536 539
537static void acm_waker(struct work_struct *waker)
538{
539 struct acm *acm = container_of(waker, struct acm, waker);
540 int rv;
541
542 rv = usb_autopm_get_interface(acm->control);
543 if (rv < 0) {
544 dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
545 return;
546 }
547 if (acm->delayed_wb) {
548 acm_start_wb(acm, acm->delayed_wb);
549 acm->delayed_wb = NULL;
550 }
551 usb_autopm_put_interface(acm->control);
552}
553
554/* 540/*
555 * TTY handlers 541 * TTY handlers
556 */ 542 */
@@ -566,7 +552,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
566 552
567 acm = acm_table[tty->index]; 553 acm = acm_table[tty->index];
568 if (!acm || !acm->dev) 554 if (!acm || !acm->dev)
569 goto err_out; 555 goto out;
570 else 556 else
571 rv = 0; 557 rv = 0;
572 558
@@ -582,8 +568,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
582 568
583 mutex_lock(&acm->mutex); 569 mutex_lock(&acm->mutex);
584 if (acm->port.count++) { 570 if (acm->port.count++) {
571 mutex_unlock(&acm->mutex);
585 usb_autopm_put_interface(acm->control); 572 usb_autopm_put_interface(acm->control);
586 goto done; 573 goto out;
587 } 574 }
588 575
589 acm->ctrlurb->dev = acm->dev; 576 acm->ctrlurb->dev = acm->dev;
@@ -612,18 +599,18 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
612 set_bit(ASYNCB_INITIALIZED, &acm->port.flags); 599 set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
613 rv = tty_port_block_til_ready(&acm->port, tty, filp); 600 rv = tty_port_block_til_ready(&acm->port, tty, filp);
614 tasklet_schedule(&acm->urb_task); 601 tasklet_schedule(&acm->urb_task);
615done: 602
616 mutex_unlock(&acm->mutex); 603 mutex_unlock(&acm->mutex);
617err_out: 604out:
618 mutex_unlock(&open_mutex); 605 mutex_unlock(&open_mutex);
619 return rv; 606 return rv;
620 607
621full_bailout: 608full_bailout:
622 usb_kill_urb(acm->ctrlurb); 609 usb_kill_urb(acm->ctrlurb);
623bail_out: 610bail_out:
624 usb_autopm_put_interface(acm->control);
625 acm->port.count--; 611 acm->port.count--;
626 mutex_unlock(&acm->mutex); 612 mutex_unlock(&acm->mutex);
613 usb_autopm_put_interface(acm->control);
627early_bail: 614early_bail:
628 mutex_unlock(&open_mutex); 615 mutex_unlock(&open_mutex);
629 tty_port_tty_set(&acm->port, NULL); 616 tty_port_tty_set(&acm->port, NULL);
@@ -649,19 +636,13 @@ static void acm_tty_unregister(struct acm *acm)
649 636
650static int acm_tty_chars_in_buffer(struct tty_struct *tty); 637static int acm_tty_chars_in_buffer(struct tty_struct *tty);
651 638
652static void acm_port_down(struct acm *acm, int drain) 639static void acm_port_down(struct acm *acm)
653{ 640{
654 int i, nr = acm->rx_buflimit; 641 int i, nr = acm->rx_buflimit;
655 mutex_lock(&open_mutex); 642 mutex_lock(&open_mutex);
656 if (acm->dev) { 643 if (acm->dev) {
657 usb_autopm_get_interface(acm->control); 644 usb_autopm_get_interface(acm->control);
658 acm_set_control(acm, acm->ctrlout = 0); 645 acm_set_control(acm, acm->ctrlout = 0);
659 /* try letting the last writes drain naturally */
660 if (drain) {
661 wait_event_interruptible_timeout(acm->drain_wait,
662 (ACM_NW == acm_wb_is_avail(acm)) || !acm->dev,
663 ACM_CLOSE_TIMEOUT * HZ);
664 }
665 usb_kill_urb(acm->ctrlurb); 646 usb_kill_urb(acm->ctrlurb);
666 for (i = 0; i < ACM_NW; i++) 647 for (i = 0; i < ACM_NW; i++)
667 usb_kill_urb(acm->wb[i].urb); 648 usb_kill_urb(acm->wb[i].urb);
@@ -677,7 +658,7 @@ static void acm_tty_hangup(struct tty_struct *tty)
677{ 658{
678 struct acm *acm = tty->driver_data; 659 struct acm *acm = tty->driver_data;
679 tty_port_hangup(&acm->port); 660 tty_port_hangup(&acm->port);
680 acm_port_down(acm, 0); 661 acm_port_down(acm);
681} 662}
682 663
683static void acm_tty_close(struct tty_struct *tty, struct file *filp) 664static void acm_tty_close(struct tty_struct *tty, struct file *filp)
@@ -698,7 +679,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
698 mutex_unlock(&open_mutex); 679 mutex_unlock(&open_mutex);
699 return; 680 return;
700 } 681 }
701 acm_port_down(acm, 0); 682 acm_port_down(acm);
702 tty_port_close_end(&acm->port, tty); 683 tty_port_close_end(&acm->port, tty);
703 tty_port_tty_set(&acm->port, NULL); 684 tty_port_tty_set(&acm->port, NULL);
704} 685}
@@ -905,7 +886,7 @@ static void acm_write_buffers_free(struct acm *acm)
905 struct usb_device *usb_dev = interface_to_usbdev(acm->control); 886 struct usb_device *usb_dev = interface_to_usbdev(acm->control);
906 887
907 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) 888 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++)
908 usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah); 889 usb_free_coherent(usb_dev, acm->writesize, wb->buf, wb->dmah);
909} 890}
910 891
911static void acm_read_buffers_free(struct acm *acm) 892static void acm_read_buffers_free(struct acm *acm)
@@ -914,8 +895,8 @@ static void acm_read_buffers_free(struct acm *acm)
914 int i, n = acm->rx_buflimit; 895 int i, n = acm->rx_buflimit;
915 896
916 for (i = 0; i < n; i++) 897 for (i = 0; i < n; i++)
917 usb_buffer_free(usb_dev, acm->readsize, 898 usb_free_coherent(usb_dev, acm->readsize,
918 acm->rb[i].base, acm->rb[i].dma); 899 acm->rb[i].base, acm->rb[i].dma);
919} 900}
920 901
921/* Little helper: write buffers allocate */ 902/* Little helper: write buffers allocate */
@@ -925,13 +906,13 @@ static int acm_write_buffers_alloc(struct acm *acm)
925 struct acm_wb *wb; 906 struct acm_wb *wb;
926 907
927 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { 908 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
928 wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL, 909 wb->buf = usb_alloc_coherent(acm->dev, acm->writesize, GFP_KERNEL,
929 &wb->dmah); 910 &wb->dmah);
930 if (!wb->buf) { 911 if (!wb->buf) {
931 while (i != 0) { 912 while (i != 0) {
932 --i; 913 --i;
933 --wb; 914 --wb;
934 usb_buffer_free(acm->dev, acm->writesize, 915 usb_free_coherent(acm->dev, acm->writesize,
935 wb->buf, wb->dmah); 916 wb->buf, wb->dmah);
936 } 917 }
937 return -ENOMEM; 918 return -ENOMEM;
@@ -984,7 +965,8 @@ static int acm_probe(struct usb_interface *intf,
984 } 965 }
985 966
986 if (!buflen) { 967 if (!buflen) {
987 if (intf->cur_altsetting->endpoint->extralen && 968 if (intf->cur_altsetting->endpoint &&
969 intf->cur_altsetting->endpoint->extralen &&
988 intf->cur_altsetting->endpoint->extra) { 970 intf->cur_altsetting->endpoint->extra) {
989 dev_dbg(&intf->dev, 971 dev_dbg(&intf->dev,
990 "Seeking extra descriptors on endpoint\n"); 972 "Seeking extra descriptors on endpoint\n");
@@ -1023,7 +1005,7 @@ static int acm_probe(struct usb_interface *intf,
1023 case USB_CDC_CALL_MANAGEMENT_TYPE: 1005 case USB_CDC_CALL_MANAGEMENT_TYPE:
1024 call_management_function = buffer[3]; 1006 call_management_function = buffer[3];
1025 call_interface_num = buffer[4]; 1007 call_interface_num = buffer[4];
1026 if ((call_management_function & 3) != 3) 1008 if ( (quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3)
1027 dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); 1009 dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n");
1028 break; 1010 break;
1029 default: 1011 default:
@@ -1178,7 +1160,6 @@ made_compressed_probe:
1178 acm->urb_task.func = acm_rx_tasklet; 1160 acm->urb_task.func = acm_rx_tasklet;
1179 acm->urb_task.data = (unsigned long) acm; 1161 acm->urb_task.data = (unsigned long) acm;
1180 INIT_WORK(&acm->work, acm_softint); 1162 INIT_WORK(&acm->work, acm_softint);
1181 INIT_WORK(&acm->waker, acm_waker);
1182 init_waitqueue_head(&acm->drain_wait); 1163 init_waitqueue_head(&acm->drain_wait);
1183 spin_lock_init(&acm->throttle_lock); 1164 spin_lock_init(&acm->throttle_lock);
1184 spin_lock_init(&acm->write_lock); 1165 spin_lock_init(&acm->write_lock);
@@ -1191,7 +1172,7 @@ made_compressed_probe:
1191 tty_port_init(&acm->port); 1172 tty_port_init(&acm->port);
1192 acm->port.ops = &acm_port_ops; 1173 acm->port.ops = &acm_port_ops;
1193 1174
1194 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 1175 buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
1195 if (!buf) { 1176 if (!buf) {
1196 dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); 1177 dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
1197 goto alloc_fail2; 1178 goto alloc_fail2;
@@ -1215,7 +1196,7 @@ made_compressed_probe:
1215 if (rcv->urb == NULL) { 1196 if (rcv->urb == NULL) {
1216 dev_dbg(&intf->dev, 1197 dev_dbg(&intf->dev,
1217 "out of memory (read urbs usb_alloc_urb)\n"); 1198 "out of memory (read urbs usb_alloc_urb)\n");
1218 goto alloc_fail7; 1199 goto alloc_fail6;
1219 } 1200 }
1220 1201
1221 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1202 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -1224,11 +1205,11 @@ made_compressed_probe:
1224 for (i = 0; i < num_rx_buf; i++) { 1205 for (i = 0; i < num_rx_buf; i++) {
1225 struct acm_rb *rb = &(acm->rb[i]); 1206 struct acm_rb *rb = &(acm->rb[i]);
1226 1207
1227 rb->base = usb_buffer_alloc(acm->dev, readsize, 1208 rb->base = usb_alloc_coherent(acm->dev, readsize,
1228 GFP_KERNEL, &rb->dma); 1209 GFP_KERNEL, &rb->dma);
1229 if (!rb->base) { 1210 if (!rb->base) {
1230 dev_dbg(&intf->dev, 1211 dev_dbg(&intf->dev,
1231 "out of memory (read bufs usb_buffer_alloc)\n"); 1212 "out of memory (read bufs usb_alloc_coherent)\n");
1232 goto alloc_fail7; 1213 goto alloc_fail7;
1233 } 1214 }
1234 } 1215 }
@@ -1239,7 +1220,7 @@ made_compressed_probe:
1239 if (snd->urb == NULL) { 1220 if (snd->urb == NULL) {
1240 dev_dbg(&intf->dev, 1221 dev_dbg(&intf->dev,
1241 "out of memory (write urbs usb_alloc_urb)"); 1222 "out of memory (write urbs usb_alloc_urb)");
1242 goto alloc_fail7; 1223 goto alloc_fail8;
1243 } 1224 }
1244 1225
1245 if (usb_endpoint_xfer_int(epwrite)) 1226 if (usb_endpoint_xfer_int(epwrite))
@@ -1278,6 +1259,7 @@ made_compressed_probe:
1278 i = device_create_file(&intf->dev, 1259 i = device_create_file(&intf->dev,
1279 &dev_attr_iCountryCodeRelDate); 1260 &dev_attr_iCountryCodeRelDate);
1280 if (i < 0) { 1261 if (i < 0) {
1262 device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
1281 kfree(acm->country_codes); 1263 kfree(acm->country_codes);
1282 goto skip_countries; 1264 goto skip_countries;
1283 } 1265 }
@@ -1314,13 +1296,14 @@ alloc_fail8:
1314 usb_free_urb(acm->wb[i].urb); 1296 usb_free_urb(acm->wb[i].urb);
1315alloc_fail7: 1297alloc_fail7:
1316 acm_read_buffers_free(acm); 1298 acm_read_buffers_free(acm);
1299alloc_fail6:
1317 for (i = 0; i < num_rx_buf; i++) 1300 for (i = 0; i < num_rx_buf; i++)
1318 usb_free_urb(acm->ru[i].urb); 1301 usb_free_urb(acm->ru[i].urb);
1319 usb_free_urb(acm->ctrlurb); 1302 usb_free_urb(acm->ctrlurb);
1320alloc_fail5: 1303alloc_fail5:
1321 acm_write_buffers_free(acm); 1304 acm_write_buffers_free(acm);
1322alloc_fail4: 1305alloc_fail4:
1323 usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1306 usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
1324alloc_fail2: 1307alloc_fail2:
1325 kfree(acm); 1308 kfree(acm);
1326alloc_fail: 1309alloc_fail:
@@ -1343,7 +1326,6 @@ static void stop_data_traffic(struct acm *acm)
1343 tasklet_enable(&acm->urb_task); 1326 tasklet_enable(&acm->urb_task);
1344 1327
1345 cancel_work_sync(&acm->work); 1328 cancel_work_sync(&acm->work);
1346 cancel_work_sync(&acm->waker);
1347} 1329}
1348 1330
1349static void acm_disconnect(struct usb_interface *intf) 1331static void acm_disconnect(struct usb_interface *intf)
@@ -1371,8 +1353,8 @@ static void acm_disconnect(struct usb_interface *intf)
1371 stop_data_traffic(acm); 1353 stop_data_traffic(acm);
1372 1354
1373 acm_write_buffers_free(acm); 1355 acm_write_buffers_free(acm);
1374 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, 1356 usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
1375 acm->ctrl_dma); 1357 acm->ctrl_dma);
1376 acm_read_buffers_free(acm); 1358 acm_read_buffers_free(acm);
1377 1359
1378 if (!acm->combined_interfaces) 1360 if (!acm->combined_interfaces)
@@ -1435,6 +1417,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
1435static int acm_resume(struct usb_interface *intf) 1417static int acm_resume(struct usb_interface *intf)
1436{ 1418{
1437 struct acm *acm = usb_get_intfdata(intf); 1419 struct acm *acm = usb_get_intfdata(intf);
1420 struct acm_wb *wb;
1438 int rv = 0; 1421 int rv = 0;
1439 int cnt; 1422 int cnt;
1440 1423
@@ -1449,6 +1432,21 @@ static int acm_resume(struct usb_interface *intf)
1449 mutex_lock(&acm->mutex); 1432 mutex_lock(&acm->mutex);
1450 if (acm->port.count) { 1433 if (acm->port.count) {
1451 rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); 1434 rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
1435
1436 spin_lock_irq(&acm->write_lock);
1437 if (acm->delayed_wb) {
1438 wb = acm->delayed_wb;
1439 acm->delayed_wb = NULL;
1440 spin_unlock_irq(&acm->write_lock);
1441 acm_start_wb(acm, wb);
1442 } else {
1443 spin_unlock_irq(&acm->write_lock);
1444 }
1445
1446 /*
1447 * delayed error checking because we must
1448 * do the write path at all cost
1449 */
1452 if (rv < 0) 1450 if (rv < 0)
1453 goto err_out; 1451 goto err_out;
1454 1452
@@ -1460,6 +1458,23 @@ err_out:
1460 return rv; 1458 return rv;
1461} 1459}
1462 1460
1461static int acm_reset_resume(struct usb_interface *intf)
1462{
1463 struct acm *acm = usb_get_intfdata(intf);
1464 struct tty_struct *tty;
1465
1466 mutex_lock(&acm->mutex);
1467 if (acm->port.count) {
1468 tty = tty_port_tty_get(&acm->port);
1469 if (tty) {
1470 tty_hangup(tty);
1471 tty_kref_put(tty);
1472 }
1473 }
1474 mutex_unlock(&acm->mutex);
1475 return acm_resume(intf);
1476}
1477
1463#endif /* CONFIG_PM */ 1478#endif /* CONFIG_PM */
1464 1479
1465#define NOKIA_PCSUITE_ACM_INFO(x) \ 1480#define NOKIA_PCSUITE_ACM_INFO(x) \
@@ -1467,11 +1482,16 @@ err_out:
1467 USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ 1482 USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
1468 USB_CDC_ACM_PROTO_VENDOR) 1483 USB_CDC_ACM_PROTO_VENDOR)
1469 1484
1485#define SAMSUNG_PCSUITE_ACM_INFO(x) \
1486 USB_DEVICE_AND_INTERFACE_INFO(0x04e7, x, \
1487 USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
1488 USB_CDC_ACM_PROTO_VENDOR)
1489
1470/* 1490/*
1471 * USB driver structure. 1491 * USB driver structure.
1472 */ 1492 */
1473 1493
1474static struct usb_device_id acm_ids[] = { 1494static const struct usb_device_id acm_ids[] = {
1475 /* quirky and broken devices */ 1495 /* quirky and broken devices */
1476 { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ 1496 { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
1477 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1497 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
@@ -1524,6 +1544,9 @@ static struct usb_device_id acm_ids[] = {
1524 { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */ 1544 { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
1525 .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ 1545 .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
1526 }, 1546 },
1547 { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
1548 .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
1549 },
1527 1550
1528 /* Nokia S60 phones expose two ACM channels. The first is 1551 /* Nokia S60 phones expose two ACM channels. The first is
1529 * a modem and is picked up by the standard AT-command 1552 * a modem and is picked up by the standard AT-command
@@ -1573,9 +1596,30 @@ static struct usb_device_id acm_ids[] = {
1573 { NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */ 1596 { NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
1574 { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */ 1597 { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */
1575 { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */ 1598 { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */
1599 { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */
1600 { NOKIA_PCSUITE_ACM_INFO(0x0178), }, /* Nokia E63 */
1601 { NOKIA_PCSUITE_ACM_INFO(0x010e), }, /* Nokia E75 */
1602 { NOKIA_PCSUITE_ACM_INFO(0x02d9), }, /* Nokia 6760 Slide */
1603 { NOKIA_PCSUITE_ACM_INFO(0x01d0), }, /* Nokia E52 */
1604 { NOKIA_PCSUITE_ACM_INFO(0x0223), }, /* Nokia E72 */
1605 { NOKIA_PCSUITE_ACM_INFO(0x0275), }, /* Nokia X6 */
1606 { NOKIA_PCSUITE_ACM_INFO(0x026c), }, /* Nokia N97 Mini */
1607 { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */
1608 { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */
1609 { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */
1610 { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
1576 1611
1577 /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ 1612 /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
1578 1613
1614 /* Support Lego NXT using pbLua firmware */
1615 { USB_DEVICE(0x0694, 0xff00),
1616 .driver_info = NOT_A_MODEM,
1617 },
1618
1619 /* control interfaces without any protocol set */
1620 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1621 USB_CDC_PROTO_NONE) },
1622
1579 /* control interfaces with various AT-command sets */ 1623 /* control interfaces with various AT-command sets */
1580 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1624 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1581 USB_CDC_ACM_PROTO_AT_V25TER) }, 1625 USB_CDC_ACM_PROTO_AT_V25TER) },
@@ -1602,6 +1646,7 @@ static struct usb_driver acm_driver = {
1602#ifdef CONFIG_PM 1646#ifdef CONFIG_PM
1603 .suspend = acm_suspend, 1647 .suspend = acm_suspend,
1604 .resume = acm_resume, 1648 .resume = acm_resume,
1649 .reset_resume = acm_reset_resume,
1605#endif 1650#endif
1606 .id_table = acm_ids, 1651 .id_table = acm_ids,
1607#ifdef CONFIG_PM 1652#ifdef CONFIG_PM