aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r--drivers/usb/class/cdc-acm.c85
1 files changed, 65 insertions, 20 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 38f85b0e32ab..c653635ce5c2 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -160,17 +160,29 @@ static inline int acm_set_control(struct acm *acm, int control)
160#define acm_send_break(acm, ms) \ 160#define acm_send_break(acm, ms) \
161 acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) 161 acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0)
162 162
163static void acm_kill_urbs(struct acm *acm) 163static void acm_poison_urbs(struct acm *acm)
164{ 164{
165 int i; 165 int i;
166 166
167 usb_kill_urb(acm->ctrlurb); 167 usb_poison_urb(acm->ctrlurb);
168 for (i = 0; i < ACM_NW; i++) 168 for (i = 0; i < ACM_NW; i++)
169 usb_kill_urb(acm->wb[i].urb); 169 usb_poison_urb(acm->wb[i].urb);
170 for (i = 0; i < acm->rx_buflimit; i++) 170 for (i = 0; i < acm->rx_buflimit; i++)
171 usb_kill_urb(acm->read_urbs[i]); 171 usb_poison_urb(acm->read_urbs[i]);
172}
173
174static void acm_unpoison_urbs(struct acm *acm)
175{
176 int i;
177
178 for (i = 0; i < acm->rx_buflimit; i++)
179 usb_unpoison_urb(acm->read_urbs[i]);
180 for (i = 0; i < ACM_NW; i++)
181 usb_unpoison_urb(acm->wb[i].urb);
182 usb_unpoison_urb(acm->ctrlurb);
172} 183}
173 184
185
174/* 186/*
175 * Write buffer management. 187 * Write buffer management.
176 * All of these assume proper locks taken by the caller. 188 * All of these assume proper locks taken by the caller.
@@ -238,9 +250,10 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
238 250
239 rc = usb_submit_urb(wb->urb, GFP_ATOMIC); 251 rc = usb_submit_urb(wb->urb, GFP_ATOMIC);
240 if (rc < 0) { 252 if (rc < 0) {
241 dev_err(&acm->data->dev, 253 if (rc != -EPERM)
242 "%s - usb_submit_urb(write bulk) failed: %d\n", 254 dev_err(&acm->data->dev,
243 __func__, rc); 255 "%s - usb_submit_urb(write bulk) failed: %d\n",
256 __func__, rc);
244 acm_write_done(acm, wb); 257 acm_write_done(acm, wb);
245 } 258 }
246 return rc; 259 return rc;
@@ -324,8 +337,10 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
324 acm->iocount.dsr++; 337 acm->iocount.dsr++;
325 if (difference & ACM_CTRL_DCD) 338 if (difference & ACM_CTRL_DCD)
326 acm->iocount.dcd++; 339 acm->iocount.dcd++;
327 if (newctrl & ACM_CTRL_BRK) 340 if (newctrl & ACM_CTRL_BRK) {
328 acm->iocount.brk++; 341 acm->iocount.brk++;
342 tty_insert_flip_char(&acm->port, 0, TTY_BREAK);
343 }
329 if (newctrl & ACM_CTRL_RI) 344 if (newctrl & ACM_CTRL_RI)
330 acm->iocount.rng++; 345 acm->iocount.rng++;
331 if (newctrl & ACM_CTRL_FRAMING) 346 if (newctrl & ACM_CTRL_FRAMING)
@@ -336,6 +351,9 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
336 acm->iocount.overrun++; 351 acm->iocount.overrun++;
337 spin_unlock(&acm->read_lock); 352 spin_unlock(&acm->read_lock);
338 353
354 if (newctrl & ACM_CTRL_BRK)
355 tty_flip_buffer_push(&acm->port);
356
339 if (difference) 357 if (difference)
340 wake_up_all(&acm->wioctl); 358 wake_up_all(&acm->wioctl);
341 359
@@ -471,11 +489,16 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
471 489
472static void acm_process_read_urb(struct acm *acm, struct urb *urb) 490static void acm_process_read_urb(struct acm *acm, struct urb *urb)
473{ 491{
492 unsigned long flags;
493
474 if (!urb->actual_length) 494 if (!urb->actual_length)
475 return; 495 return;
476 496
497 spin_lock_irqsave(&acm->read_lock, flags);
477 tty_insert_flip_string(&acm->port, urb->transfer_buffer, 498 tty_insert_flip_string(&acm->port, urb->transfer_buffer,
478 urb->actual_length); 499 urb->actual_length);
500 spin_unlock_irqrestore(&acm->read_lock, flags);
501
479 tty_flip_buffer_push(&acm->port); 502 tty_flip_buffer_push(&acm->port);
480} 503}
481 504
@@ -492,11 +515,6 @@ static void acm_read_bulk_callback(struct urb *urb)
492 dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", 515 dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
493 rb->index, urb->actual_length, status); 516 rb->index, urb->actual_length, status);
494 517
495 if (!acm->dev) {
496 dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
497 return;
498 }
499
500 switch (status) { 518 switch (status) {
501 case 0: 519 case 0:
502 usb_mark_last_busy(acm->dev); 520 usb_mark_last_busy(acm->dev);
@@ -666,7 +684,8 @@ static void acm_port_dtr_rts(struct tty_port *port, int raise)
666 684
667 res = acm_set_control(acm, val); 685 res = acm_set_control(acm, val);
668 if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE)) 686 if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE))
669 dev_err(&acm->control->dev, "failed to set dtr/rts\n"); 687 /* This is broken in too many devices to spam the logs */
688 dev_dbg(&acm->control->dev, "failed to set dtr/rts\n");
670} 689}
671 690
672static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) 691static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
@@ -751,6 +770,7 @@ static void acm_port_shutdown(struct tty_port *port)
751 * Need to grab write_lock to prevent race with resume, but no need to 770 * Need to grab write_lock to prevent race with resume, but no need to
752 * hold it due to the tty-port initialised flag. 771 * hold it due to the tty-port initialised flag.
753 */ 772 */
773 acm_poison_urbs(acm);
754 spin_lock_irq(&acm->write_lock); 774 spin_lock_irq(&acm->write_lock);
755 spin_unlock_irq(&acm->write_lock); 775 spin_unlock_irq(&acm->write_lock);
756 776
@@ -767,7 +787,8 @@ static void acm_port_shutdown(struct tty_port *port)
767 usb_autopm_put_interface_async(acm->control); 787 usb_autopm_put_interface_async(acm->control);
768 } 788 }
769 789
770 acm_kill_urbs(acm); 790 acm_unpoison_urbs(acm);
791
771} 792}
772 793
773static void acm_tty_cleanup(struct tty_struct *tty) 794static void acm_tty_cleanup(struct tty_struct *tty)
@@ -986,8 +1007,6 @@ static int set_serial_info(struct acm *acm,
986 if ((new_serial.close_delay != old_close_delay) || 1007 if ((new_serial.close_delay != old_close_delay) ||
987 (new_serial.closing_wait != old_closing_wait)) 1008 (new_serial.closing_wait != old_closing_wait))
988 retval = -EPERM; 1009 retval = -EPERM;
989 else
990 retval = -EOPNOTSUPP;
991 } else { 1010 } else {
992 acm->port.close_delay = close_delay; 1011 acm->port.close_delay = close_delay;
993 acm->port.closing_wait = closing_wait; 1012 acm->port.closing_wait = closing_wait;
@@ -1559,6 +1578,11 @@ skip_countries:
1559 1578
1560 return 0; 1579 return 0;
1561alloc_fail8: 1580alloc_fail8:
1581 if (!acm->combined_interfaces) {
1582 /* Clear driver data so that disconnect() returns early. */
1583 usb_set_intfdata(data_interface, NULL);
1584 usb_driver_release_interface(&acm_driver, data_interface);
1585 }
1562 if (acm->country_codes) { 1586 if (acm->country_codes) {
1563 device_remove_file(&acm->control->dev, 1587 device_remove_file(&acm->control->dev,
1564 &dev_attr_wCountryCodes); 1588 &dev_attr_wCountryCodes);
@@ -1598,8 +1622,14 @@ static void acm_disconnect(struct usb_interface *intf)
1598 if (!acm) 1622 if (!acm)
1599 return; 1623 return;
1600 1624
1601 mutex_lock(&acm->mutex);
1602 acm->disconnected = true; 1625 acm->disconnected = true;
1626 /*
1627 * there is a circular dependency. acm_softint() can resubmit
1628 * the URBs in error handling so we need to block any
1629 * submission right away
1630 */
1631 acm_poison_urbs(acm);
1632 mutex_lock(&acm->mutex);
1603 if (acm->country_codes) { 1633 if (acm->country_codes) {
1604 device_remove_file(&acm->control->dev, 1634 device_remove_file(&acm->control->dev,
1605 &dev_attr_wCountryCodes); 1635 &dev_attr_wCountryCodes);
@@ -1618,7 +1648,6 @@ static void acm_disconnect(struct usb_interface *intf)
1618 tty_kref_put(tty); 1648 tty_kref_put(tty);
1619 } 1649 }
1620 1650
1621 acm_kill_urbs(acm);
1622 cancel_delayed_work_sync(&acm->dwork); 1651 cancel_delayed_work_sync(&acm->dwork);
1623 1652
1624 tty_unregister_device(acm_tty_driver, acm->minor); 1653 tty_unregister_device(acm_tty_driver, acm->minor);
@@ -1660,7 +1689,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
1660 if (cnt) 1689 if (cnt)
1661 return 0; 1690 return 0;
1662 1691
1663 acm_kill_urbs(acm); 1692 acm_poison_urbs(acm);
1664 cancel_delayed_work_sync(&acm->dwork); 1693 cancel_delayed_work_sync(&acm->dwork);
1665 acm->urbs_in_error_delay = 0; 1694 acm->urbs_in_error_delay = 0;
1666 1695
@@ -1678,6 +1707,8 @@ static int acm_resume(struct usb_interface *intf)
1678 if (--acm->susp_count) 1707 if (--acm->susp_count)
1679 goto out; 1708 goto out;
1680 1709
1710 acm_unpoison_urbs(acm);
1711
1681 if (tty_port_initialized(&acm->port)) { 1712 if (tty_port_initialized(&acm->port)) {
1682 rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC); 1713 rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
1683 1714
@@ -1952,6 +1983,10 @@ static const struct usb_device_id acm_ids[] = {
1952 { USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */ 1983 { USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */
1953 .driver_info = IGNORE_DEVICE, 1984 .driver_info = IGNORE_DEVICE,
1954 }, 1985 },
1986
1987 { USB_DEVICE(0x04d8, 0xf58b),
1988 .driver_info = IGNORE_DEVICE,
1989 },
1955#endif 1990#endif
1956 1991
1957 /*Samsung phone in firmware update mode */ 1992 /*Samsung phone in firmware update mode */
@@ -1982,6 +2017,16 @@ static const struct usb_device_id acm_ids[] = {
1982 .driver_info = SEND_ZERO_PACKET, 2017 .driver_info = SEND_ZERO_PACKET,
1983 }, 2018 },
1984 2019
2020 /* Exclude Goodix Fingerprint Reader */
2021 { USB_DEVICE(0x27c6, 0x5395),
2022 .driver_info = IGNORE_DEVICE,
2023 },
2024
2025 /* Exclude Heimann Sensor GmbH USB appset demo */
2026 { USB_DEVICE(0x32a7, 0x0000),
2027 .driver_info = IGNORE_DEVICE,
2028 },
2029
1985 /* control interfaces without any protocol set */ 2030 /* control interfaces without any protocol set */
1986 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 2031 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1987 USB_CDC_PROTO_NONE) }, 2032 USB_CDC_PROTO_NONE) },