aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2013-05-01 11:47:44 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-05-01 11:47:44 -0400
commitbf61c8840efe60fd8f91446860b63338fb424158 (patch)
tree7a71832407a4f0d6346db773343f4c3ae2257b19 /drivers/usb/class
parent5846115b30f3a881e542c8bfde59a699c1c13740 (diff)
parent0c6a61657da78098472fd0eb71cc01f2387fa1bb (diff)
Merge branch 'next' into for-linus
Prepare first set of updates for 3.10 merge window.
Diffstat (limited to 'drivers/usb/class')
-rw-r--r--drivers/usb/class/Kconfig2
-rw-r--r--drivers/usb/class/cdc-acm.c67
-rw-r--r--drivers/usb/class/cdc-acm.h1
-rw-r--r--drivers/usb/class/cdc-wdm.c23
4 files changed, 79 insertions, 14 deletions
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index 2519e320098f..316aac8e4ca1 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -6,7 +6,7 @@ comment "USB Device Class drivers"
6 6
7config USB_ACM 7config USB_ACM
8 tristate "USB Modem (CDC ACM) support" 8 tristate "USB Modem (CDC ACM) support"
9 depends on USB 9 depends on USB && TTY
10 ---help--- 10 ---help---
11 This driver supports USB modems and ISDN adapters which support the 11 This driver supports USB modems and ISDN adapters which support the
12 Communication Device Class Abstract Control Model interface. 12 Communication Device Class Abstract Control Model interface.
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 6e49ec6f3adc..cb8ef3ef5c94 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -410,19 +410,12 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
410 410
411static void acm_process_read_urb(struct acm *acm, struct urb *urb) 411static void acm_process_read_urb(struct acm *acm, struct urb *urb)
412{ 412{
413 struct tty_struct *tty;
414
415 if (!urb->actual_length) 413 if (!urb->actual_length)
416 return; 414 return;
417 415
418 tty = tty_port_tty_get(&acm->port); 416 tty_insert_flip_string(&acm->port, urb->transfer_buffer,
419 if (!tty) 417 urb->actual_length);
420 return; 418 tty_flip_buffer_push(&acm->port);
421
422 tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
423 tty_flip_buffer_push(tty);
424
425 tty_kref_put(tty);
426} 419}
427 420
428static void acm_read_bulk_callback(struct urb *urb) 421static void acm_read_bulk_callback(struct urb *urb)
@@ -787,6 +780,10 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
787 tmp.flags = ASYNC_LOW_LATENCY; 780 tmp.flags = ASYNC_LOW_LATENCY;
788 tmp.xmit_fifo_size = acm->writesize; 781 tmp.xmit_fifo_size = acm->writesize;
789 tmp.baud_base = le32_to_cpu(acm->line.dwDTERate); 782 tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
783 tmp.close_delay = acm->port.close_delay / 10;
784 tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
785 ASYNC_CLOSING_WAIT_NONE :
786 acm->port.closing_wait / 10;
790 787
791 if (copy_to_user(info, &tmp, sizeof(tmp))) 788 if (copy_to_user(info, &tmp, sizeof(tmp)))
792 return -EFAULT; 789 return -EFAULT;
@@ -794,6 +791,37 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
794 return 0; 791 return 0;
795} 792}
796 793
794static int set_serial_info(struct acm *acm,
795 struct serial_struct __user *newinfo)
796{
797 struct serial_struct new_serial;
798 unsigned int closing_wait, close_delay;
799 int retval = 0;
800
801 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
802 return -EFAULT;
803
804 close_delay = new_serial.close_delay * 10;
805 closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
806 ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
807
808 mutex_lock(&acm->port.mutex);
809
810 if (!capable(CAP_SYS_ADMIN)) {
811 if ((close_delay != acm->port.close_delay) ||
812 (closing_wait != acm->port.closing_wait))
813 retval = -EPERM;
814 else
815 retval = -EOPNOTSUPP;
816 } else {
817 acm->port.close_delay = close_delay;
818 acm->port.closing_wait = closing_wait;
819 }
820
821 mutex_unlock(&acm->port.mutex);
822 return retval;
823}
824
797static int acm_tty_ioctl(struct tty_struct *tty, 825static int acm_tty_ioctl(struct tty_struct *tty,
798 unsigned int cmd, unsigned long arg) 826 unsigned int cmd, unsigned long arg)
799{ 827{
@@ -804,6 +832,9 @@ static int acm_tty_ioctl(struct tty_struct *tty,
804 case TIOCGSERIAL: /* gets serial port data */ 832 case TIOCGSERIAL: /* gets serial port data */
805 rv = get_serial_info(acm, (struct serial_struct __user *) arg); 833 rv = get_serial_info(acm, (struct serial_struct __user *) arg);
806 break; 834 break;
835 case TIOCSSERIAL:
836 rv = set_serial_info(acm, (struct serial_struct __user *) arg);
837 break;
807 } 838 }
808 839
809 return rv; 840 return rv;
@@ -949,6 +980,10 @@ static int acm_probe(struct usb_interface *intf,
949 980
950 /* normal quirks */ 981 /* normal quirks */
951 quirks = (unsigned long)id->driver_info; 982 quirks = (unsigned long)id->driver_info;
983
984 if (quirks == IGNORE_DEVICE)
985 return -ENODEV;
986
952 num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; 987 num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
953 988
954 /* handle quirks deadly to normal probing*/ 989 /* handle quirks deadly to normal probing*/
@@ -1564,6 +1599,9 @@ static const struct usb_device_id acm_ids[] = {
1564 { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */ 1599 { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */
1565 .driver_info = NO_UNION_NORMAL, 1600 .driver_info = NO_UNION_NORMAL,
1566 }, 1601 },
1602 { USB_DEVICE(0x05f9, 0x4002), /* PSC Scanning, Magellan 800i */
1603 .driver_info = NO_UNION_NORMAL,
1604 },
1567 { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */ 1605 { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
1568 .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ 1606 .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
1569 }, 1607 },
@@ -1650,6 +1688,15 @@ static const struct usb_device_id acm_ids[] = {
1650 .driver_info = NO_DATA_INTERFACE, 1688 .driver_info = NO_DATA_INTERFACE,
1651 }, 1689 },
1652 1690
1691#if IS_ENABLED(CONFIG_INPUT_IMS_PCU)
1692 { USB_DEVICE(0x04d8, 0x0082), /* Application mode */
1693 .driver_info = IGNORE_DEVICE,
1694 },
1695 { USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */
1696 .driver_info = IGNORE_DEVICE,
1697 },
1698#endif
1699
1653 /* control interfaces without any protocol set */ 1700 /* control interfaces without any protocol set */
1654 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1701 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1655 USB_CDC_PROTO_NONE) }, 1702 USB_CDC_PROTO_NONE) },
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 35ef887b7417..0f76e4af600e 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -128,3 +128,4 @@ struct acm {
128#define NO_CAP_LINE 4 128#define NO_CAP_LINE 4
129#define NOT_A_MODEM 8 129#define NOT_A_MODEM 8
130#define NO_DATA_INTERFACE 16 130#define NO_DATA_INTERFACE 16
131#define IGNORE_DEVICE 32
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 5f0cb417b736..122d056d96d5 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -56,6 +56,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
56#define WDM_RESPONDING 7 56#define WDM_RESPONDING 7
57#define WDM_SUSPENDING 8 57#define WDM_SUSPENDING 8
58#define WDM_RESETTING 9 58#define WDM_RESETTING 9
59#define WDM_OVERFLOW 10
59 60
60#define WDM_MAX 16 61#define WDM_MAX 16
61 62
@@ -155,6 +156,7 @@ static void wdm_in_callback(struct urb *urb)
155{ 156{
156 struct wdm_device *desc = urb->context; 157 struct wdm_device *desc = urb->context;
157 int status = urb->status; 158 int status = urb->status;
159 int length = urb->actual_length;
158 160
159 spin_lock(&desc->iuspin); 161 spin_lock(&desc->iuspin);
160 clear_bit(WDM_RESPONDING, &desc->flags); 162 clear_bit(WDM_RESPONDING, &desc->flags);
@@ -185,9 +187,17 @@ static void wdm_in_callback(struct urb *urb)
185 } 187 }
186 188
187 desc->rerr = status; 189 desc->rerr = status;
188 desc->reslength = urb->actual_length; 190 if (length + desc->length > desc->wMaxCommand) {
189 memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); 191 /* The buffer would overflow */
190 desc->length += desc->reslength; 192 set_bit(WDM_OVERFLOW, &desc->flags);
193 } else {
194 /* we may already be in overflow */
195 if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
196 memmove(desc->ubuf + desc->length, desc->inbuf, length);
197 desc->length += length;
198 desc->reslength = length;
199 }
200 }
191skip_error: 201skip_error:
192 wake_up(&desc->wait); 202 wake_up(&desc->wait);
193 203
@@ -435,6 +445,11 @@ retry:
435 rv = -ENODEV; 445 rv = -ENODEV;
436 goto err; 446 goto err;
437 } 447 }
448 if (test_bit(WDM_OVERFLOW, &desc->flags)) {
449 clear_bit(WDM_OVERFLOW, &desc->flags);
450 rv = -ENOBUFS;
451 goto err;
452 }
438 i++; 453 i++;
439 if (file->f_flags & O_NONBLOCK) { 454 if (file->f_flags & O_NONBLOCK) {
440 if (!test_bit(WDM_READ, &desc->flags)) { 455 if (!test_bit(WDM_READ, &desc->flags)) {
@@ -478,6 +493,7 @@ retry:
478 spin_unlock_irq(&desc->iuspin); 493 spin_unlock_irq(&desc->iuspin);
479 goto retry; 494 goto retry;
480 } 495 }
496
481 if (!desc->reslength) { /* zero length read */ 497 if (!desc->reslength) { /* zero length read */
482 dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); 498 dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
483 clear_bit(WDM_READ, &desc->flags); 499 clear_bit(WDM_READ, &desc->flags);
@@ -1004,6 +1020,7 @@ static int wdm_post_reset(struct usb_interface *intf)
1004 struct wdm_device *desc = wdm_find_device(intf); 1020 struct wdm_device *desc = wdm_find_device(intf);
1005 int rv; 1021 int rv;
1006 1022
1023 clear_bit(WDM_OVERFLOW, &desc->flags);
1007 clear_bit(WDM_RESETTING, &desc->flags); 1024 clear_bit(WDM_RESETTING, &desc->flags);
1008 rv = recover_from_urb_loss(desc); 1025 rv = recover_from_urb_loss(desc);
1009 mutex_unlock(&desc->wlock); 1026 mutex_unlock(&desc->wlock);