diff options
Diffstat (limited to 'drivers/usb/class')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 138 | ||||
-rw-r--r-- | drivers/usb/class/cdc-acm.h | 4 | ||||
-rw-r--r-- | drivers/usb/class/cdc-wdm.c | 59 | ||||
-rw-r--r-- | drivers/usb/class/usblp.c | 7 | ||||
-rw-r--r-- | drivers/usb/class/usbtmc.c | 2 |
5 files changed, 171 insertions, 39 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index dac7676ce21..a06f2cdc610 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -155,7 +155,6 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) | |||
155 | wb->urb->transfer_dma = wb->dmah; | 155 | wb->urb->transfer_dma = wb->dmah; |
156 | wb->urb->transfer_buffer_length = wb->len; | 156 | wb->urb->transfer_buffer_length = wb->len; |
157 | wb->urb->dev = acm->dev; | 157 | wb->urb->dev = acm->dev; |
158 | |||
159 | rc = usb_submit_urb(wb->urb, GFP_ATOMIC); | 158 | rc = usb_submit_urb(wb->urb, GFP_ATOMIC); |
160 | if (rc < 0) { | 159 | if (rc < 0) { |
161 | dev_err(&acm->data->dev, | 160 | dev_err(&acm->data->dev, |
@@ -171,6 +170,9 @@ static int acm_write_start(struct acm *acm, int wbn) | |||
171 | unsigned long flags; | 170 | unsigned long flags; |
172 | struct acm_wb *wb = &acm->wb[wbn]; | 171 | struct acm_wb *wb = &acm->wb[wbn]; |
173 | int rc; | 172 | int rc; |
173 | #ifdef CONFIG_PM | ||
174 | struct urb *res; | ||
175 | #endif | ||
174 | 176 | ||
175 | spin_lock_irqsave(&acm->write_lock, flags); | 177 | spin_lock_irqsave(&acm->write_lock, flags); |
176 | if (!acm->dev) { | 178 | if (!acm->dev) { |
@@ -183,15 +185,33 @@ static int acm_write_start(struct acm *acm, int wbn) | |||
183 | acm->susp_count); | 185 | acm->susp_count); |
184 | usb_autopm_get_interface_async(acm->control); | 186 | usb_autopm_get_interface_async(acm->control); |
185 | if (acm->susp_count) { | 187 | if (acm->susp_count) { |
188 | #ifdef CONFIG_PM | ||
189 | acm->transmitting++; | ||
190 | wb->urb->transfer_buffer = wb->buf; | ||
191 | wb->urb->transfer_dma = wb->dmah; | ||
192 | wb->urb->transfer_buffer_length = wb->len; | ||
193 | wb->urb->dev = acm->dev; | ||
194 | usb_anchor_urb(wb->urb, &acm->deferred); | ||
195 | #else | ||
186 | if (!acm->delayed_wb) | 196 | if (!acm->delayed_wb) |
187 | acm->delayed_wb = wb; | 197 | acm->delayed_wb = wb; |
188 | else | 198 | else |
189 | usb_autopm_put_interface_async(acm->control); | 199 | usb_autopm_put_interface_async(acm->control); |
200 | #endif | ||
190 | spin_unlock_irqrestore(&acm->write_lock, flags); | 201 | spin_unlock_irqrestore(&acm->write_lock, flags); |
191 | return 0; /* A white lie */ | 202 | return 0; /* A white lie */ |
192 | } | 203 | } |
193 | usb_mark_last_busy(acm->dev); | 204 | usb_mark_last_busy(acm->dev); |
194 | 205 | #ifdef CONFIG_PM | |
206 | while ((res = usb_get_from_anchor(&acm->deferred))) { | ||
207 | rc = usb_submit_urb(res, GFP_ATOMIC); | ||
208 | if (rc < 0) { | ||
209 | dbg("usb_submit_urb(pending request) failed: %d", rc); | ||
210 | usb_unanchor_urb(res); | ||
211 | acm_write_done(acm, res->context); | ||
212 | } | ||
213 | } | ||
214 | #endif | ||
195 | rc = acm_start_wb(acm, wb); | 215 | rc = acm_start_wb(acm, wb); |
196 | spin_unlock_irqrestore(&acm->write_lock, flags); | 216 | spin_unlock_irqrestore(&acm->write_lock, flags); |
197 | 217 | ||
@@ -476,7 +496,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
476 | if (usb_autopm_get_interface(acm->control) < 0) | 496 | if (usb_autopm_get_interface(acm->control) < 0) |
477 | goto early_bail; | 497 | goto early_bail; |
478 | else | 498 | else |
479 | acm->control->needs_remote_wakeup = 1; | 499 | acm->control->needs_remote_wakeup = 0; |
480 | 500 | ||
481 | mutex_lock(&acm->mutex); | 501 | mutex_lock(&acm->mutex); |
482 | if (acm->port.count++) { | 502 | if (acm->port.count++) { |
@@ -539,7 +559,6 @@ static void acm_port_down(struct acm *acm) | |||
539 | { | 559 | { |
540 | int i; | 560 | int i; |
541 | 561 | ||
542 | mutex_lock(&open_mutex); | ||
543 | if (acm->dev) { | 562 | if (acm->dev) { |
544 | usb_autopm_get_interface(acm->control); | 563 | usb_autopm_get_interface(acm->control); |
545 | acm_set_control(acm, acm->ctrlout = 0); | 564 | acm_set_control(acm, acm->ctrlout = 0); |
@@ -551,14 +570,23 @@ static void acm_port_down(struct acm *acm) | |||
551 | acm->control->needs_remote_wakeup = 0; | 570 | acm->control->needs_remote_wakeup = 0; |
552 | usb_autopm_put_interface(acm->control); | 571 | usb_autopm_put_interface(acm->control); |
553 | } | 572 | } |
554 | mutex_unlock(&open_mutex); | ||
555 | } | 573 | } |
556 | 574 | ||
557 | static void acm_tty_hangup(struct tty_struct *tty) | 575 | static void acm_tty_hangup(struct tty_struct *tty) |
558 | { | 576 | { |
559 | struct acm *acm = tty->driver_data; | 577 | struct acm *acm; |
578 | |||
579 | mutex_lock(&open_mutex); | ||
580 | acm = tty->driver_data; | ||
581 | |||
582 | if (!acm) | ||
583 | goto out; | ||
584 | |||
560 | tty_port_hangup(&acm->port); | 585 | tty_port_hangup(&acm->port); |
561 | acm_port_down(acm); | 586 | acm_port_down(acm); |
587 | |||
588 | out: | ||
589 | mutex_unlock(&open_mutex); | ||
562 | } | 590 | } |
563 | 591 | ||
564 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 592 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
@@ -569,8 +597,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
569 | shutdown */ | 597 | shutdown */ |
570 | if (!acm) | 598 | if (!acm) |
571 | return; | 599 | return; |
600 | |||
601 | mutex_lock(&open_mutex); | ||
572 | if (tty_port_close_start(&acm->port, tty, filp) == 0) { | 602 | if (tty_port_close_start(&acm->port, tty, filp) == 0) { |
573 | mutex_lock(&open_mutex); | ||
574 | if (!acm->dev) { | 603 | if (!acm->dev) { |
575 | tty_port_tty_set(&acm->port, NULL); | 604 | tty_port_tty_set(&acm->port, NULL); |
576 | acm_tty_unregister(acm); | 605 | acm_tty_unregister(acm); |
@@ -582,6 +611,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
582 | acm_port_down(acm); | 611 | acm_port_down(acm); |
583 | tty_port_close_end(&acm->port, tty); | 612 | tty_port_close_end(&acm->port, tty); |
584 | tty_port_tty_set(&acm->port, NULL); | 613 | tty_port_tty_set(&acm->port, NULL); |
614 | mutex_unlock(&open_mutex); | ||
585 | } | 615 | } |
586 | 616 | ||
587 | static int acm_tty_write(struct tty_struct *tty, | 617 | static int acm_tty_write(struct tty_struct *tty, |
@@ -863,8 +893,12 @@ static int acm_probe(struct usb_interface *intf, | |||
863 | quirks = (unsigned long)id->driver_info; | 893 | quirks = (unsigned long)id->driver_info; |
864 | num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; | 894 | num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; |
865 | 895 | ||
896 | /* not a real CDC ACM device */ | ||
897 | if (quirks & NOT_REAL_ACM) | ||
898 | return -ENODEV; | ||
899 | |||
866 | /* handle quirks deadly to normal probing*/ | 900 | /* handle quirks deadly to normal probing*/ |
867 | if (quirks == NO_UNION_NORMAL) { | 901 | if (quirks & NO_UNION_NORMAL) { |
868 | data_interface = usb_ifnum_to_if(usb_dev, 1); | 902 | data_interface = usb_ifnum_to_if(usb_dev, 1); |
869 | control_interface = usb_ifnum_to_if(usb_dev, 0); | 903 | control_interface = usb_ifnum_to_if(usb_dev, 0); |
870 | goto skip_normal_probe; | 904 | goto skip_normal_probe; |
@@ -1074,6 +1108,7 @@ made_compressed_probe: | |||
1074 | acm->readsize = readsize; | 1108 | acm->readsize = readsize; |
1075 | acm->rx_buflimit = num_rx_buf; | 1109 | acm->rx_buflimit = num_rx_buf; |
1076 | INIT_WORK(&acm->work, acm_softint); | 1110 | INIT_WORK(&acm->work, acm_softint); |
1111 | init_usb_anchor(&acm->deferred); | ||
1077 | spin_lock_init(&acm->write_lock); | 1112 | spin_lock_init(&acm->write_lock); |
1078 | spin_lock_init(&acm->read_lock); | 1113 | spin_lock_init(&acm->read_lock); |
1079 | mutex_init(&acm->mutex); | 1114 | mutex_init(&acm->mutex); |
@@ -1081,6 +1116,8 @@ made_compressed_probe: | |||
1081 | acm->is_int_ep = usb_endpoint_xfer_int(epread); | 1116 | acm->is_int_ep = usb_endpoint_xfer_int(epread); |
1082 | if (acm->is_int_ep) | 1117 | if (acm->is_int_ep) |
1083 | acm->bInterval = epread->bInterval; | 1118 | acm->bInterval = epread->bInterval; |
1119 | if (quirks & NO_HANGUP_IN_RESET_RESUME) | ||
1120 | acm->no_hangup_in_reset_resume = 1; | ||
1084 | tty_port_init(&acm->port); | 1121 | tty_port_init(&acm->port); |
1085 | acm->port.ops = &acm_port_ops; | 1122 | acm->port.ops = &acm_port_ops; |
1086 | 1123 | ||
@@ -1181,6 +1218,8 @@ made_compressed_probe: | |||
1181 | i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); | 1218 | i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); |
1182 | if (i < 0) { | 1219 | if (i < 0) { |
1183 | kfree(acm->country_codes); | 1220 | kfree(acm->country_codes); |
1221 | acm->country_codes = NULL; | ||
1222 | acm->country_code_size = 0; | ||
1184 | goto skip_countries; | 1223 | goto skip_countries; |
1185 | } | 1224 | } |
1186 | 1225 | ||
@@ -1189,6 +1228,8 @@ made_compressed_probe: | |||
1189 | if (i < 0) { | 1228 | if (i < 0) { |
1190 | device_remove_file(&intf->dev, &dev_attr_wCountryCodes); | 1229 | device_remove_file(&intf->dev, &dev_attr_wCountryCodes); |
1191 | kfree(acm->country_codes); | 1230 | kfree(acm->country_codes); |
1231 | acm->country_codes = NULL; | ||
1232 | acm->country_code_size = 0; | ||
1192 | goto skip_countries; | 1233 | goto skip_countries; |
1193 | } | 1234 | } |
1194 | } | 1235 | } |
@@ -1241,6 +1282,11 @@ static void stop_data_traffic(struct acm *acm) | |||
1241 | { | 1282 | { |
1242 | int i; | 1283 | int i; |
1243 | 1284 | ||
1285 | if (!acm) { | ||
1286 | pr_err("%s: !acm\n", __func__); | ||
1287 | return; | ||
1288 | } | ||
1289 | |||
1244 | dev_dbg(&acm->control->dev, "%s\n", __func__); | 1290 | dev_dbg(&acm->control->dev, "%s\n", __func__); |
1245 | 1291 | ||
1246 | usb_kill_urb(acm->ctrlurb); | 1292 | usb_kill_urb(acm->ctrlurb); |
@@ -1276,6 +1322,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1276 | 1322 | ||
1277 | stop_data_traffic(acm); | 1323 | stop_data_traffic(acm); |
1278 | 1324 | ||
1325 | usb_kill_anchored_urbs(&acm->deferred); | ||
1279 | acm_write_buffers_free(acm); | 1326 | acm_write_buffers_free(acm); |
1280 | usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer, | 1327 | usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer, |
1281 | acm->ctrl_dma); | 1328 | acm->ctrl_dma); |
@@ -1305,6 +1352,11 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) | |||
1305 | struct acm *acm = usb_get_intfdata(intf); | 1352 | struct acm *acm = usb_get_intfdata(intf); |
1306 | int cnt; | 1353 | int cnt; |
1307 | 1354 | ||
1355 | if (!acm) { | ||
1356 | pr_err("%s: !acm\n", __func__); | ||
1357 | return -ENODEV; | ||
1358 | } | ||
1359 | |||
1308 | if (message.event & PM_EVENT_AUTO) { | 1360 | if (message.event & PM_EVENT_AUTO) { |
1309 | int b; | 1361 | int b; |
1310 | 1362 | ||
@@ -1339,23 +1391,50 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) | |||
1339 | static int acm_resume(struct usb_interface *intf) | 1391 | static int acm_resume(struct usb_interface *intf) |
1340 | { | 1392 | { |
1341 | struct acm *acm = usb_get_intfdata(intf); | 1393 | struct acm *acm = usb_get_intfdata(intf); |
1342 | struct acm_wb *wb; | ||
1343 | int rv = 0; | 1394 | int rv = 0; |
1344 | int cnt; | 1395 | int cnt; |
1396 | #ifdef CONFIG_PM | ||
1397 | struct urb *res; | ||
1398 | #else | ||
1399 | struct acm_wb *wb; | ||
1400 | #endif | ||
1401 | |||
1402 | if (!acm) { | ||
1403 | pr_err("%s: !acm\n", __func__); | ||
1404 | return -ENODEV; | ||
1405 | } | ||
1345 | 1406 | ||
1346 | spin_lock_irq(&acm->read_lock); | 1407 | spin_lock_irq(&acm->read_lock); |
1347 | acm->susp_count -= 1; | 1408 | if (acm->susp_count > 0) { |
1348 | cnt = acm->susp_count; | 1409 | acm->susp_count -= 1; |
1410 | cnt = acm->susp_count; | ||
1411 | } else { | ||
1412 | spin_unlock_irq(&acm->read_lock); | ||
1413 | return 0; | ||
1414 | } | ||
1349 | spin_unlock_irq(&acm->read_lock); | 1415 | spin_unlock_irq(&acm->read_lock); |
1350 | 1416 | ||
1351 | if (cnt) | 1417 | if (cnt) |
1352 | return 0; | 1418 | return 0; |
1353 | 1419 | ||
1420 | |||
1354 | mutex_lock(&acm->mutex); | 1421 | mutex_lock(&acm->mutex); |
1422 | |||
1355 | if (acm->port.count) { | 1423 | if (acm->port.count) { |
1356 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); | 1424 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); |
1357 | |||
1358 | spin_lock_irq(&acm->write_lock); | 1425 | spin_lock_irq(&acm->write_lock); |
1426 | #ifdef CONFIG_PM | ||
1427 | while ((res = usb_get_from_anchor(&acm->deferred))) { | ||
1428 | rv = usb_submit_urb(res, GFP_ATOMIC); | ||
1429 | if (rv < 0) { | ||
1430 | dbg("usb_submit_urb(pending request)" | ||
1431 | " failed: %d", rv); | ||
1432 | usb_unanchor_urb(res); | ||
1433 | acm_write_done(acm, res->context); | ||
1434 | } | ||
1435 | } | ||
1436 | spin_unlock_irq(&acm->write_lock); | ||
1437 | #else | ||
1359 | if (acm->delayed_wb) { | 1438 | if (acm->delayed_wb) { |
1360 | wb = acm->delayed_wb; | 1439 | wb = acm->delayed_wb; |
1361 | acm->delayed_wb = NULL; | 1440 | acm->delayed_wb = NULL; |
@@ -1364,6 +1443,7 @@ static int acm_resume(struct usb_interface *intf) | |||
1364 | } else { | 1443 | } else { |
1365 | spin_unlock_irq(&acm->write_lock); | 1444 | spin_unlock_irq(&acm->write_lock); |
1366 | } | 1445 | } |
1446 | #endif | ||
1367 | 1447 | ||
1368 | /* | 1448 | /* |
1369 | * delayed error checking because we must | 1449 | * delayed error checking because we must |
@@ -1385,11 +1465,17 @@ static int acm_reset_resume(struct usb_interface *intf) | |||
1385 | struct acm *acm = usb_get_intfdata(intf); | 1465 | struct acm *acm = usb_get_intfdata(intf); |
1386 | struct tty_struct *tty; | 1466 | struct tty_struct *tty; |
1387 | 1467 | ||
1468 | if (!acm) { | ||
1469 | pr_err("%s: !acm\n", __func__); | ||
1470 | return -ENODEV; | ||
1471 | } | ||
1472 | |||
1388 | mutex_lock(&acm->mutex); | 1473 | mutex_lock(&acm->mutex); |
1389 | if (acm->port.count) { | 1474 | if (acm->port.count) { |
1390 | tty = tty_port_tty_get(&acm->port); | 1475 | tty = tty_port_tty_get(&acm->port); |
1391 | if (tty) { | 1476 | if (tty) { |
1392 | tty_hangup(tty); | 1477 | if (!acm->no_hangup_in_reset_resume) |
1478 | tty_hangup(tty); | ||
1393 | tty_kref_put(tty); | 1479 | tty_kref_put(tty); |
1394 | } | 1480 | } |
1395 | } | 1481 | } |
@@ -1456,6 +1542,16 @@ static const struct usb_device_id acm_ids[] = { | |||
1456 | }, | 1542 | }, |
1457 | { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ | 1543 | { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ |
1458 | }, | 1544 | }, |
1545 | /* Motorola H24 HSPA module: */ | ||
1546 | { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ | ||
1547 | { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ | ||
1548 | { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ | ||
1549 | { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ | ||
1550 | { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ | ||
1551 | { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ | ||
1552 | { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ | ||
1553 | { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ | ||
1554 | |||
1459 | { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ | 1555 | { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ |
1460 | .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on | 1556 | .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on |
1461 | data interface instead of | 1557 | data interface instead of |
@@ -1469,6 +1565,9 @@ static const struct usb_device_id acm_ids[] = { | |||
1469 | { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */ | 1565 | { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */ |
1470 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ | 1566 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ |
1471 | }, | 1567 | }, |
1568 | { USB_DEVICE(0x1519, 0x0020), | ||
1569 | .driver_info = NO_UNION_NORMAL | NO_HANGUP_IN_RESET_RESUME, /* has no union descriptor */ | ||
1570 | }, | ||
1472 | 1571 | ||
1473 | /* Nokia S60 phones expose two ACM channels. The first is | 1572 | /* Nokia S60 phones expose two ACM channels. The first is |
1474 | * a modem and is picked up by the standard AT-command | 1573 | * a modem and is picked up by the standard AT-command |
@@ -1534,6 +1633,9 @@ static const struct usb_device_id acm_ids[] = { | |||
1534 | { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ | 1633 | { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ |
1535 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | 1634 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ |
1536 | 1635 | ||
1636 | /* Support for Owen devices */ | ||
1637 | { USB_DEVICE(0x03eb, 0x0030), }, /* Owen SI30 */ | ||
1638 | |||
1537 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1639 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
1538 | 1640 | ||
1539 | /* Support Lego NXT using pbLua firmware */ | 1641 | /* Support Lego NXT using pbLua firmware */ |
@@ -1546,6 +1648,16 @@ static const struct usb_device_id acm_ids[] = { | |||
1546 | .driver_info = NO_DATA_INTERFACE, | 1648 | .driver_info = NO_DATA_INTERFACE, |
1547 | }, | 1649 | }, |
1548 | 1650 | ||
1651 | /* Exclude XMM6260 boot rom (not running modem software yet) */ | ||
1652 | { USB_DEVICE(0x058b, 0x0041), | ||
1653 | .driver_info = NOT_REAL_ACM, | ||
1654 | }, | ||
1655 | |||
1656 | /* Icera 450 */ | ||
1657 | { USB_DEVICE(0x1983, 0x0321), | ||
1658 | .driver_info = NO_HANGUP_IN_RESET_RESUME, | ||
1659 | }, | ||
1660 | |||
1549 | /* control interfaces without any protocol set */ | 1661 | /* control interfaces without any protocol set */ |
1550 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1662 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
1551 | USB_CDC_PROTO_NONE) }, | 1663 | USB_CDC_PROTO_NONE) }, |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index ca7937f26e2..ec59fda787f 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -115,8 +115,10 @@ struct acm { | |||
115 | unsigned int is_int_ep:1; /* interrupt endpoints contrary to spec used */ | 115 | unsigned int is_int_ep:1; /* interrupt endpoints contrary to spec used */ |
116 | unsigned int throttled:1; /* actually throttled */ | 116 | unsigned int throttled:1; /* actually throttled */ |
117 | unsigned int throttle_req:1; /* throttle requested */ | 117 | unsigned int throttle_req:1; /* throttle requested */ |
118 | unsigned int no_hangup_in_reset_resume:1; /* do not call tty_hangup in acm_reset_resume */ | ||
118 | u8 bInterval; | 119 | u8 bInterval; |
119 | struct acm_wb *delayed_wb; /* write queued for a device about to be woken */ | 120 | struct acm_wb *delayed_wb; /* write queued for a device about to be woken */ |
121 | struct usb_anchor deferred; | ||
120 | }; | 122 | }; |
121 | 123 | ||
122 | #define CDC_DATA_INTERFACE_TYPE 0x0a | 124 | #define CDC_DATA_INTERFACE_TYPE 0x0a |
@@ -127,3 +129,5 @@ struct acm { | |||
127 | #define NO_CAP_LINE 4 | 129 | #define NO_CAP_LINE 4 |
128 | #define NOT_A_MODEM 8 | 130 | #define NOT_A_MODEM 8 |
129 | #define NO_DATA_INTERFACE 16 | 131 | #define NO_DATA_INTERFACE 16 |
132 | #define NOT_REAL_ACM 32 | ||
133 | #define NO_HANGUP_IN_RESET_RESUME 64 | ||
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 2b9ff518b50..90581a85134 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -57,6 +57,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | |||
57 | 57 | ||
58 | #define WDM_MAX 16 | 58 | #define WDM_MAX 16 |
59 | 59 | ||
60 | /* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ | ||
61 | #define WDM_DEFAULT_BUFSIZE 256 | ||
60 | 62 | ||
61 | static DEFINE_MUTEX(wdm_mutex); | 63 | static DEFINE_MUTEX(wdm_mutex); |
62 | 64 | ||
@@ -88,7 +90,8 @@ struct wdm_device { | |||
88 | int count; | 90 | int count; |
89 | dma_addr_t shandle; | 91 | dma_addr_t shandle; |
90 | dma_addr_t ihandle; | 92 | dma_addr_t ihandle; |
91 | struct mutex lock; | 93 | struct mutex wlock; |
94 | struct mutex rlock; | ||
92 | wait_queue_head_t wait; | 95 | wait_queue_head_t wait; |
93 | struct work_struct rxwork; | 96 | struct work_struct rxwork; |
94 | int werr; | 97 | int werr; |
@@ -323,7 +326,7 @@ static ssize_t wdm_write | |||
323 | } | 326 | } |
324 | 327 | ||
325 | /* concurrent writes and disconnect */ | 328 | /* concurrent writes and disconnect */ |
326 | r = mutex_lock_interruptible(&desc->lock); | 329 | r = mutex_lock_interruptible(&desc->wlock); |
327 | rv = -ERESTARTSYS; | 330 | rv = -ERESTARTSYS; |
328 | if (r) { | 331 | if (r) { |
329 | kfree(buf); | 332 | kfree(buf); |
@@ -386,7 +389,7 @@ static ssize_t wdm_write | |||
386 | out: | 389 | out: |
387 | usb_autopm_put_interface(desc->intf); | 390 | usb_autopm_put_interface(desc->intf); |
388 | outnp: | 391 | outnp: |
389 | mutex_unlock(&desc->lock); | 392 | mutex_unlock(&desc->wlock); |
390 | outnl: | 393 | outnl: |
391 | return rv < 0 ? rv : count; | 394 | return rv < 0 ? rv : count; |
392 | } | 395 | } |
@@ -399,7 +402,7 @@ static ssize_t wdm_read | |||
399 | struct wdm_device *desc = file->private_data; | 402 | struct wdm_device *desc = file->private_data; |
400 | 403 | ||
401 | 404 | ||
402 | rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ | 405 | rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ |
403 | if (rv < 0) | 406 | if (rv < 0) |
404 | return -ERESTARTSYS; | 407 | return -ERESTARTSYS; |
405 | 408 | ||
@@ -467,14 +470,16 @@ retry: | |||
467 | for (i = 0; i < desc->length - cntr; i++) | 470 | for (i = 0; i < desc->length - cntr; i++) |
468 | desc->ubuf[i] = desc->ubuf[i + cntr]; | 471 | desc->ubuf[i] = desc->ubuf[i + cntr]; |
469 | 472 | ||
473 | spin_lock_irq(&desc->iuspin); | ||
470 | desc->length -= cntr; | 474 | desc->length -= cntr; |
475 | spin_unlock_irq(&desc->iuspin); | ||
471 | /* in case we had outstanding data */ | 476 | /* in case we had outstanding data */ |
472 | if (!desc->length) | 477 | if (!desc->length) |
473 | clear_bit(WDM_READ, &desc->flags); | 478 | clear_bit(WDM_READ, &desc->flags); |
474 | rv = cntr; | 479 | rv = cntr; |
475 | 480 | ||
476 | err: | 481 | err: |
477 | mutex_unlock(&desc->lock); | 482 | mutex_unlock(&desc->rlock); |
478 | return rv; | 483 | return rv; |
479 | } | 484 | } |
480 | 485 | ||
@@ -540,7 +545,8 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
540 | } | 545 | } |
541 | intf->needs_remote_wakeup = 1; | 546 | intf->needs_remote_wakeup = 1; |
542 | 547 | ||
543 | mutex_lock(&desc->lock); | 548 | /* using write lock to protect desc->count */ |
549 | mutex_lock(&desc->wlock); | ||
544 | if (!desc->count++) { | 550 | if (!desc->count++) { |
545 | desc->werr = 0; | 551 | desc->werr = 0; |
546 | desc->rerr = 0; | 552 | desc->rerr = 0; |
@@ -553,7 +559,7 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
553 | } else { | 559 | } else { |
554 | rv = 0; | 560 | rv = 0; |
555 | } | 561 | } |
556 | mutex_unlock(&desc->lock); | 562 | mutex_unlock(&desc->wlock); |
557 | usb_autopm_put_interface(desc->intf); | 563 | usb_autopm_put_interface(desc->intf); |
558 | out: | 564 | out: |
559 | mutex_unlock(&wdm_mutex); | 565 | mutex_unlock(&wdm_mutex); |
@@ -565,9 +571,11 @@ static int wdm_release(struct inode *inode, struct file *file) | |||
565 | struct wdm_device *desc = file->private_data; | 571 | struct wdm_device *desc = file->private_data; |
566 | 572 | ||
567 | mutex_lock(&wdm_mutex); | 573 | mutex_lock(&wdm_mutex); |
568 | mutex_lock(&desc->lock); | 574 | |
575 | /* using write lock to protect desc->count */ | ||
576 | mutex_lock(&desc->wlock); | ||
569 | desc->count--; | 577 | desc->count--; |
570 | mutex_unlock(&desc->lock); | 578 | mutex_unlock(&desc->wlock); |
571 | 579 | ||
572 | if (!desc->count) { | 580 | if (!desc->count) { |
573 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); | 581 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); |
@@ -630,7 +638,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
630 | struct usb_cdc_dmm_desc *dmhd; | 638 | struct usb_cdc_dmm_desc *dmhd; |
631 | u8 *buffer = intf->altsetting->extra; | 639 | u8 *buffer = intf->altsetting->extra; |
632 | int buflen = intf->altsetting->extralen; | 640 | int buflen = intf->altsetting->extralen; |
633 | u16 maxcom = 0; | 641 | u16 maxcom = WDM_DEFAULT_BUFSIZE; |
634 | 642 | ||
635 | if (!buffer) | 643 | if (!buffer) |
636 | goto out; | 644 | goto out; |
@@ -665,7 +673,8 @@ next_desc: | |||
665 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); | 673 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); |
666 | if (!desc) | 674 | if (!desc) |
667 | goto out; | 675 | goto out; |
668 | mutex_init(&desc->lock); | 676 | mutex_init(&desc->rlock); |
677 | mutex_init(&desc->wlock); | ||
669 | spin_lock_init(&desc->iuspin); | 678 | spin_lock_init(&desc->iuspin); |
670 | init_waitqueue_head(&desc->wait); | 679 | init_waitqueue_head(&desc->wait); |
671 | desc->wMaxCommand = maxcom; | 680 | desc->wMaxCommand = maxcom; |
@@ -716,7 +725,7 @@ next_desc: | |||
716 | goto err; | 725 | goto err; |
717 | 726 | ||
718 | desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), | 727 | desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), |
719 | desc->bMaxPacketSize0, | 728 | desc->wMaxCommand, |
720 | GFP_KERNEL, | 729 | GFP_KERNEL, |
721 | &desc->response->transfer_dma); | 730 | &desc->response->transfer_dma); |
722 | if (!desc->inbuf) | 731 | if (!desc->inbuf) |
@@ -779,11 +788,13 @@ static void wdm_disconnect(struct usb_interface *intf) | |||
779 | /* to terminate pending flushes */ | 788 | /* to terminate pending flushes */ |
780 | clear_bit(WDM_IN_USE, &desc->flags); | 789 | clear_bit(WDM_IN_USE, &desc->flags); |
781 | spin_unlock_irqrestore(&desc->iuspin, flags); | 790 | spin_unlock_irqrestore(&desc->iuspin, flags); |
782 | mutex_lock(&desc->lock); | 791 | wake_up_all(&desc->wait); |
792 | mutex_lock(&desc->rlock); | ||
793 | mutex_lock(&desc->wlock); | ||
783 | kill_urbs(desc); | 794 | kill_urbs(desc); |
784 | cancel_work_sync(&desc->rxwork); | 795 | cancel_work_sync(&desc->rxwork); |
785 | mutex_unlock(&desc->lock); | 796 | mutex_unlock(&desc->wlock); |
786 | wake_up_all(&desc->wait); | 797 | mutex_unlock(&desc->rlock); |
787 | if (!desc->count) | 798 | if (!desc->count) |
788 | cleanup(desc); | 799 | cleanup(desc); |
789 | mutex_unlock(&wdm_mutex); | 800 | mutex_unlock(&wdm_mutex); |
@@ -798,8 +809,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
798 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); | 809 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); |
799 | 810 | ||
800 | /* if this is an autosuspend the caller does the locking */ | 811 | /* if this is an autosuspend the caller does the locking */ |
801 | if (!(message.event & PM_EVENT_AUTO)) | 812 | if (!(message.event & PM_EVENT_AUTO)) { |
802 | mutex_lock(&desc->lock); | 813 | mutex_lock(&desc->rlock); |
814 | mutex_lock(&desc->wlock); | ||
815 | } | ||
803 | spin_lock_irq(&desc->iuspin); | 816 | spin_lock_irq(&desc->iuspin); |
804 | 817 | ||
805 | if ((message.event & PM_EVENT_AUTO) && | 818 | if ((message.event & PM_EVENT_AUTO) && |
@@ -815,8 +828,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
815 | kill_urbs(desc); | 828 | kill_urbs(desc); |
816 | cancel_work_sync(&desc->rxwork); | 829 | cancel_work_sync(&desc->rxwork); |
817 | } | 830 | } |
818 | if (!(message.event & PM_EVENT_AUTO)) | 831 | if (!(message.event & PM_EVENT_AUTO)) { |
819 | mutex_unlock(&desc->lock); | 832 | mutex_unlock(&desc->wlock); |
833 | mutex_unlock(&desc->rlock); | ||
834 | } | ||
820 | 835 | ||
821 | return rv; | 836 | return rv; |
822 | } | 837 | } |
@@ -854,7 +869,8 @@ static int wdm_pre_reset(struct usb_interface *intf) | |||
854 | { | 869 | { |
855 | struct wdm_device *desc = usb_get_intfdata(intf); | 870 | struct wdm_device *desc = usb_get_intfdata(intf); |
856 | 871 | ||
857 | mutex_lock(&desc->lock); | 872 | mutex_lock(&desc->rlock); |
873 | mutex_lock(&desc->wlock); | ||
858 | kill_urbs(desc); | 874 | kill_urbs(desc); |
859 | 875 | ||
860 | /* | 876 | /* |
@@ -876,7 +892,8 @@ static int wdm_post_reset(struct usb_interface *intf) | |||
876 | int rv; | 892 | int rv; |
877 | 893 | ||
878 | rv = recover_from_urb_loss(desc); | 894 | rv = recover_from_urb_loss(desc); |
879 | mutex_unlock(&desc->lock); | 895 | mutex_unlock(&desc->wlock); |
896 | mutex_unlock(&desc->rlock); | ||
880 | return 0; | 897 | return 0; |
881 | } | 898 | } |
882 | 899 | ||
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 9eca4053312..cb3a93243a0 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/mutex.h> | 58 | #include <linux/mutex.h> |
59 | #undef DEBUG | 59 | #undef DEBUG |
60 | #include <linux/usb.h> | 60 | #include <linux/usb.h> |
61 | #include <linux/ratelimit.h> | ||
61 | 62 | ||
62 | /* | 63 | /* |
63 | * Version Information | 64 | * Version Information |
@@ -348,8 +349,7 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
348 | mutex_lock(&usblp->mut); | 349 | mutex_lock(&usblp->mut); |
349 | if ((error = usblp_read_status(usblp, usblp->statusbuf)) < 0) { | 350 | if ((error = usblp_read_status(usblp, usblp->statusbuf)) < 0) { |
350 | mutex_unlock(&usblp->mut); | 351 | mutex_unlock(&usblp->mut); |
351 | if (printk_ratelimit()) | 352 | printk_ratelimited(KERN_ERR |
352 | printk(KERN_ERR | ||
353 | "usblp%d: error %d reading printer status\n", | 353 | "usblp%d: error %d reading printer status\n", |
354 | usblp->minor, error); | 354 | usblp->minor, error); |
355 | return 0; | 355 | return 0; |
@@ -653,8 +653,7 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
653 | 653 | ||
654 | case LPGETSTATUS: | 654 | case LPGETSTATUS: |
655 | if ((retval = usblp_read_status(usblp, usblp->statusbuf))) { | 655 | if ((retval = usblp_read_status(usblp, usblp->statusbuf))) { |
656 | if (printk_ratelimit()) | 656 | printk_ratelimited(KERN_ERR "usblp%d:" |
657 | printk(KERN_ERR "usblp%d:" | ||
658 | "failed reading printer status (%d)\n", | 657 | "failed reading printer status (%d)\n", |
659 | usblp->minor, retval); | 658 | usblp->minor, retval); |
660 | retval = -EIO; | 659 | retval = -EIO; |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 385acb895ab..3f94ac34dce 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -268,7 +268,7 @@ usbtmc_abort_bulk_in_status: | |||
268 | dev_err(dev, "usb_bulk_msg returned %d\n", rv); | 268 | dev_err(dev, "usb_bulk_msg returned %d\n", rv); |
269 | goto exit; | 269 | goto exit; |
270 | } | 270 | } |
271 | } while ((actual = max_size) && | 271 | } while ((actual == max_size) && |
272 | (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); | 272 | (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); |
273 | 273 | ||
274 | if (actual == max_size) { | 274 | if (actual == max_size) { |