aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-05 11:41:16 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-05 11:41:16 -0500
commitc8d204b38a558d74fafb6915e2593602b7f4b823 (patch)
treed4e076845e4d6dfbef70b1f4740e8fa246958059 /drivers/usb
parent29fc1aa454d0603493b47a8e2410ae6e9ab20258 (diff)
parentef079936d3cd09e63612834fe2698eeada0d8e3f (diff)
Merge tag 'usb-serial-4.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-linus
Johan writes: USB-serial fixes for v4.10-rc3 These fixes address a number of long-standing issues in various USB-serial drivers which would lead to crashes should a malicious device lack the expected endpoints. Included are also a few related fixes, and a couple of unrelated ones that were found during my survey (e.g. a memleak and a sleep-while-atomic). A compiler warning revealed an error-handling issue in the new f81534 driver which is also fixed. Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/cyberjack.c10
-rw-r--r--drivers/usb/serial/f81534.c8
-rw-r--r--drivers/usb/serial/garmin_gps.c1
-rw-r--r--drivers/usb/serial/io_edgeport.c5
-rw-r--r--drivers/usb/serial/io_ti.c22
-rw-r--r--drivers/usb/serial/iuu_phoenix.c11
-rw-r--r--drivers/usb/serial/keyspan_pda.c14
-rw-r--r--drivers/usb/serial/kobil_sct.c12
-rw-r--r--drivers/usb/serial/mos7720.c56
-rw-r--r--drivers/usb/serial/mos7840.c24
-rw-r--r--drivers/usb/serial/omninet.c13
-rw-r--r--drivers/usb/serial/oti6858.c16
-rw-r--r--drivers/usb/serial/pl2303.c8
-rw-r--r--drivers/usb/serial/quatech2.c4
-rw-r--r--drivers/usb/serial/spcp8x5.c14
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c7
16 files changed, 167 insertions, 58 deletions
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 5f17a3b9916d..80260b08398b 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -50,6 +50,7 @@
50#define CYBERJACK_PRODUCT_ID 0x0100 50#define CYBERJACK_PRODUCT_ID 0x0100
51 51
52/* Function prototypes */ 52/* Function prototypes */
53static int cyberjack_attach(struct usb_serial *serial);
53static int cyberjack_port_probe(struct usb_serial_port *port); 54static int cyberjack_port_probe(struct usb_serial_port *port);
54static int cyberjack_port_remove(struct usb_serial_port *port); 55static int cyberjack_port_remove(struct usb_serial_port *port);
55static int cyberjack_open(struct tty_struct *tty, 56static int cyberjack_open(struct tty_struct *tty,
@@ -77,6 +78,7 @@ static struct usb_serial_driver cyberjack_device = {
77 .description = "Reiner SCT Cyberjack USB card reader", 78 .description = "Reiner SCT Cyberjack USB card reader",
78 .id_table = id_table, 79 .id_table = id_table,
79 .num_ports = 1, 80 .num_ports = 1,
81 .attach = cyberjack_attach,
80 .port_probe = cyberjack_port_probe, 82 .port_probe = cyberjack_port_probe,
81 .port_remove = cyberjack_port_remove, 83 .port_remove = cyberjack_port_remove,
82 .open = cyberjack_open, 84 .open = cyberjack_open,
@@ -100,6 +102,14 @@ struct cyberjack_private {
100 short wrsent; /* Data already sent */ 102 short wrsent; /* Data already sent */
101}; 103};
102 104
105static int cyberjack_attach(struct usb_serial *serial)
106{
107 if (serial->num_bulk_out < serial->num_ports)
108 return -ENODEV;
109
110 return 0;
111}
112
103static int cyberjack_port_probe(struct usb_serial_port *port) 113static int cyberjack_port_probe(struct usb_serial_port *port)
104{ 114{
105 struct cyberjack_private *priv; 115 struct cyberjack_private *priv;
diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index 8282a6a18fee..22f23a429a95 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -1237,6 +1237,7 @@ static int f81534_attach(struct usb_serial *serial)
1237static int f81534_port_probe(struct usb_serial_port *port) 1237static int f81534_port_probe(struct usb_serial_port *port)
1238{ 1238{
1239 struct f81534_port_private *port_priv; 1239 struct f81534_port_private *port_priv;
1240 int ret;
1240 1241
1241 port_priv = devm_kzalloc(&port->dev, sizeof(*port_priv), GFP_KERNEL); 1242 port_priv = devm_kzalloc(&port->dev, sizeof(*port_priv), GFP_KERNEL);
1242 if (!port_priv) 1243 if (!port_priv)
@@ -1246,10 +1247,11 @@ static int f81534_port_probe(struct usb_serial_port *port)
1246 mutex_init(&port_priv->mcr_mutex); 1247 mutex_init(&port_priv->mcr_mutex);
1247 1248
1248 /* Assign logic-to-phy mapping */ 1249 /* Assign logic-to-phy mapping */
1249 port_priv->phy_num = f81534_logic_to_phy_port(port->serial, port); 1250 ret = f81534_logic_to_phy_port(port->serial, port);
1250 if (port_priv->phy_num < 0 || port_priv->phy_num >= F81534_NUM_PORT) 1251 if (ret < 0)
1251 return -ENODEV; 1252 return ret;
1252 1253
1254 port_priv->phy_num = ret;
1253 usb_set_serial_port_data(port, port_priv); 1255 usb_set_serial_port_data(port, port_priv);
1254 dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__, 1256 dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__,
1255 port->port_number, port_priv->phy_num); 1257 port->port_number, port_priv->phy_num);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 97cabf803c2f..b2f2e87aed94 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1043,6 +1043,7 @@ static int garmin_write_bulk(struct usb_serial_port *port,
1043 "%s - usb_submit_urb(write bulk) failed with status = %d\n", 1043 "%s - usb_submit_urb(write bulk) failed with status = %d\n",
1044 __func__, status); 1044 __func__, status);
1045 count = status; 1045 count = status;
1046 kfree(buffer);
1046 } 1047 }
1047 1048
1048 /* we are done with this urb, so let the host driver 1049 /* we are done with this urb, so let the host driver
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index dcc0c58aaad5..d50e5773483f 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2751,6 +2751,11 @@ static int edge_startup(struct usb_serial *serial)
2751 EDGE_COMPATIBILITY_MASK1, 2751 EDGE_COMPATIBILITY_MASK1,
2752 EDGE_COMPATIBILITY_MASK2 }; 2752 EDGE_COMPATIBILITY_MASK2 };
2753 2753
2754 if (serial->num_bulk_in < 1 || serial->num_interrupt_in < 1) {
2755 dev_err(&serial->interface->dev, "missing endpoints\n");
2756 return -ENODEV;
2757 }
2758
2754 dev = serial->dev; 2759 dev = serial->dev;
2755 2760
2756 /* create our private serial structure */ 2761 /* create our private serial structure */
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index c339163698eb..9a0db2965fbb 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1499,8 +1499,7 @@ static int do_boot_mode(struct edgeport_serial *serial,
1499 1499
1500 dev_dbg(dev, "%s - Download successful -- Device rebooting...\n", __func__); 1500 dev_dbg(dev, "%s - Download successful -- Device rebooting...\n", __func__);
1501 1501
1502 /* return an error on purpose */ 1502 return 1;
1503 return -ENODEV;
1504 } 1503 }
1505 1504
1506stayinbootmode: 1505stayinbootmode:
@@ -1508,7 +1507,7 @@ stayinbootmode:
1508 dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__); 1507 dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__);
1509 serial->product_info.TiMode = TI_MODE_BOOT; 1508 serial->product_info.TiMode = TI_MODE_BOOT;
1510 1509
1511 return 0; 1510 return 1;
1512} 1511}
1513 1512
1514static int ti_do_config(struct edgeport_port *port, int feature, int on) 1513static int ti_do_config(struct edgeport_port *port, int feature, int on)
@@ -2546,6 +2545,13 @@ static int edge_startup(struct usb_serial *serial)
2546 int status; 2545 int status;
2547 u16 product_id; 2546 u16 product_id;
2548 2547
2548 /* Make sure we have the required endpoints when in download mode. */
2549 if (serial->interface->cur_altsetting->desc.bNumEndpoints > 1) {
2550 if (serial->num_bulk_in < serial->num_ports ||
2551 serial->num_bulk_out < serial->num_ports)
2552 return -ENODEV;
2553 }
2554
2549 /* create our private serial structure */ 2555 /* create our private serial structure */
2550 edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); 2556 edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
2551 if (!edge_serial) 2557 if (!edge_serial)
@@ -2553,14 +2559,18 @@ static int edge_startup(struct usb_serial *serial)
2553 2559
2554 mutex_init(&edge_serial->es_lock); 2560 mutex_init(&edge_serial->es_lock);
2555 edge_serial->serial = serial; 2561 edge_serial->serial = serial;
2562 INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
2556 usb_set_serial_data(serial, edge_serial); 2563 usb_set_serial_data(serial, edge_serial);
2557 2564
2558 status = download_fw(edge_serial); 2565 status = download_fw(edge_serial);
2559 if (status) { 2566 if (status < 0) {
2560 kfree(edge_serial); 2567 kfree(edge_serial);
2561 return status; 2568 return status;
2562 } 2569 }
2563 2570
2571 if (status > 0)
2572 return 1; /* bind but do not register any ports */
2573
2564 product_id = le16_to_cpu( 2574 product_id = le16_to_cpu(
2565 edge_serial->serial->dev->descriptor.idProduct); 2575 edge_serial->serial->dev->descriptor.idProduct);
2566 2576
@@ -2572,7 +2582,6 @@ static int edge_startup(struct usb_serial *serial)
2572 } 2582 }
2573 } 2583 }
2574 2584
2575 INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
2576 edge_heartbeat_schedule(edge_serial); 2585 edge_heartbeat_schedule(edge_serial);
2577 2586
2578 return 0; 2587 return 0;
@@ -2580,6 +2589,9 @@ static int edge_startup(struct usb_serial *serial)
2580 2589
2581static void edge_disconnect(struct usb_serial *serial) 2590static void edge_disconnect(struct usb_serial *serial)
2582{ 2591{
2592 struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
2593
2594 cancel_delayed_work_sync(&edge_serial->heartbeat_work);
2583} 2595}
2584 2596
2585static void edge_release(struct usb_serial *serial) 2597static void edge_release(struct usb_serial *serial)
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 344b4eea4bd5..d57fb5199218 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -68,6 +68,16 @@ struct iuu_private {
68 u32 clk; 68 u32 clk;
69}; 69};
70 70
71static int iuu_attach(struct usb_serial *serial)
72{
73 unsigned char num_ports = serial->num_ports;
74
75 if (serial->num_bulk_in < num_ports || serial->num_bulk_out < num_ports)
76 return -ENODEV;
77
78 return 0;
79}
80
71static int iuu_port_probe(struct usb_serial_port *port) 81static int iuu_port_probe(struct usb_serial_port *port)
72{ 82{
73 struct iuu_private *priv; 83 struct iuu_private *priv;
@@ -1196,6 +1206,7 @@ static struct usb_serial_driver iuu_device = {
1196 .tiocmset = iuu_tiocmset, 1206 .tiocmset = iuu_tiocmset,
1197 .set_termios = iuu_set_termios, 1207 .set_termios = iuu_set_termios,
1198 .init_termios = iuu_init_termios, 1208 .init_termios = iuu_init_termios,
1209 .attach = iuu_attach,
1199 .port_probe = iuu_port_probe, 1210 .port_probe = iuu_port_probe,
1200 .port_remove = iuu_port_remove, 1211 .port_remove = iuu_port_remove,
1201}; 1212};
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index e49ad0c63ad8..83523fcf6fb9 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -699,6 +699,19 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
699MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); 699MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
700#endif 700#endif
701 701
702static int keyspan_pda_attach(struct usb_serial *serial)
703{
704 unsigned char num_ports = serial->num_ports;
705
706 if (serial->num_bulk_out < num_ports ||
707 serial->num_interrupt_in < num_ports) {
708 dev_err(&serial->interface->dev, "missing endpoints\n");
709 return -ENODEV;
710 }
711
712 return 0;
713}
714
702static int keyspan_pda_port_probe(struct usb_serial_port *port) 715static int keyspan_pda_port_probe(struct usb_serial_port *port)
703{ 716{
704 717
@@ -776,6 +789,7 @@ static struct usb_serial_driver keyspan_pda_device = {
776 .break_ctl = keyspan_pda_break_ctl, 789 .break_ctl = keyspan_pda_break_ctl,
777 .tiocmget = keyspan_pda_tiocmget, 790 .tiocmget = keyspan_pda_tiocmget,
778 .tiocmset = keyspan_pda_tiocmset, 791 .tiocmset = keyspan_pda_tiocmset,
792 .attach = keyspan_pda_attach,
779 .port_probe = keyspan_pda_port_probe, 793 .port_probe = keyspan_pda_port_probe,
780 .port_remove = keyspan_pda_port_remove, 794 .port_remove = keyspan_pda_port_remove,
781}; 795};
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 2363654cafc9..813035f51fe7 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -51,6 +51,7 @@
51 51
52 52
53/* Function prototypes */ 53/* Function prototypes */
54static int kobil_attach(struct usb_serial *serial);
54static int kobil_port_probe(struct usb_serial_port *probe); 55static int kobil_port_probe(struct usb_serial_port *probe);
55static int kobil_port_remove(struct usb_serial_port *probe); 56static int kobil_port_remove(struct usb_serial_port *probe);
56static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); 57static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
@@ -86,6 +87,7 @@ static struct usb_serial_driver kobil_device = {
86 .description = "KOBIL USB smart card terminal", 87 .description = "KOBIL USB smart card terminal",
87 .id_table = id_table, 88 .id_table = id_table,
88 .num_ports = 1, 89 .num_ports = 1,
90 .attach = kobil_attach,
89 .port_probe = kobil_port_probe, 91 .port_probe = kobil_port_probe,
90 .port_remove = kobil_port_remove, 92 .port_remove = kobil_port_remove,
91 .ioctl = kobil_ioctl, 93 .ioctl = kobil_ioctl,
@@ -113,6 +115,16 @@ struct kobil_private {
113}; 115};
114 116
115 117
118static int kobil_attach(struct usb_serial *serial)
119{
120 if (serial->num_interrupt_out < serial->num_ports) {
121 dev_err(&serial->interface->dev, "missing interrupt-out endpoint\n");
122 return -ENODEV;
123 }
124
125 return 0;
126}
127
116static int kobil_port_probe(struct usb_serial_port *port) 128static int kobil_port_probe(struct usb_serial_port *port)
117{ 129{
118 struct usb_serial *serial = port->serial; 130 struct usb_serial *serial = port->serial;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index d52caa03679c..91bc170b408a 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -65,8 +65,6 @@ struct moschip_port {
65 struct urb *write_urb_pool[NUM_URBS]; 65 struct urb *write_urb_pool[NUM_URBS];
66}; 66};
67 67
68static struct usb_serial_driver moschip7720_2port_driver;
69
70#define USB_VENDOR_ID_MOSCHIP 0x9710 68#define USB_VENDOR_ID_MOSCHIP 0x9710
71#define MOSCHIP_DEVICE_ID_7720 0x7720 69#define MOSCHIP_DEVICE_ID_7720 0x7720
72#define MOSCHIP_DEVICE_ID_7715 0x7715 70#define MOSCHIP_DEVICE_ID_7715 0x7715
@@ -970,25 +968,6 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
970 tty_port_tty_wakeup(&mos7720_port->port->port); 968 tty_port_tty_wakeup(&mos7720_port->port->port);
971} 969}
972 970
973/*
974 * mos77xx_probe
975 * this function installs the appropriate read interrupt endpoint callback
976 * depending on whether the device is a 7720 or 7715, thus avoiding costly
977 * run-time checks in the high-frequency callback routine itself.
978 */
979static int mos77xx_probe(struct usb_serial *serial,
980 const struct usb_device_id *id)
981{
982 if (id->idProduct == MOSCHIP_DEVICE_ID_7715)
983 moschip7720_2port_driver.read_int_callback =
984 mos7715_interrupt_callback;
985 else
986 moschip7720_2port_driver.read_int_callback =
987 mos7720_interrupt_callback;
988
989 return 0;
990}
991
992static int mos77xx_calc_num_ports(struct usb_serial *serial) 971static int mos77xx_calc_num_ports(struct usb_serial *serial)
993{ 972{
994 u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); 973 u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
@@ -1917,6 +1896,11 @@ static int mos7720_startup(struct usb_serial *serial)
1917 u16 product; 1896 u16 product;
1918 int ret_val; 1897 int ret_val;
1919 1898
1899 if (serial->num_bulk_in < 2 || serial->num_bulk_out < 2) {
1900 dev_err(&serial->interface->dev, "missing bulk endpoints\n");
1901 return -ENODEV;
1902 }
1903
1920 product = le16_to_cpu(serial->dev->descriptor.idProduct); 1904 product = le16_to_cpu(serial->dev->descriptor.idProduct);
1921 dev = serial->dev; 1905 dev = serial->dev;
1922 1906
@@ -1941,19 +1925,18 @@ static int mos7720_startup(struct usb_serial *serial)
1941 tmp->interrupt_in_endpointAddress; 1925 tmp->interrupt_in_endpointAddress;
1942 serial->port[1]->interrupt_in_urb = NULL; 1926 serial->port[1]->interrupt_in_urb = NULL;
1943 serial->port[1]->interrupt_in_buffer = NULL; 1927 serial->port[1]->interrupt_in_buffer = NULL;
1928
1929 if (serial->port[0]->interrupt_in_urb) {
1930 struct urb *urb = serial->port[0]->interrupt_in_urb;
1931
1932 urb->complete = mos7715_interrupt_callback;
1933 }
1944 } 1934 }
1945 1935
1946 /* setting configuration feature to one */ 1936 /* setting configuration feature to one */
1947 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 1937 usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
1948 (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); 1938 (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
1949 1939
1950 /* start the interrupt urb */
1951 ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
1952 if (ret_val)
1953 dev_err(&dev->dev,
1954 "%s - Error %d submitting control urb\n",
1955 __func__, ret_val);
1956
1957#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT 1940#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
1958 if (product == MOSCHIP_DEVICE_ID_7715) { 1941 if (product == MOSCHIP_DEVICE_ID_7715) {
1959 ret_val = mos7715_parport_init(serial); 1942 ret_val = mos7715_parport_init(serial);
@@ -1961,6 +1944,13 @@ static int mos7720_startup(struct usb_serial *serial)
1961 return ret_val; 1944 return ret_val;
1962 } 1945 }
1963#endif 1946#endif
1947 /* start the interrupt urb */
1948 ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
1949 if (ret_val) {
1950 dev_err(&dev->dev, "failed to submit interrupt urb: %d\n",
1951 ret_val);
1952 }
1953
1964 /* LSR For Port 1 */ 1954 /* LSR For Port 1 */
1965 read_mos_reg(serial, 0, MOS7720_LSR, &data); 1955 read_mos_reg(serial, 0, MOS7720_LSR, &data);
1966 dev_dbg(&dev->dev, "LSR:%x\n", data); 1956 dev_dbg(&dev->dev, "LSR:%x\n", data);
@@ -1970,6 +1960,8 @@ static int mos7720_startup(struct usb_serial *serial)
1970 1960
1971static void mos7720_release(struct usb_serial *serial) 1961static void mos7720_release(struct usb_serial *serial)
1972{ 1962{
1963 usb_kill_urb(serial->port[0]->interrupt_in_urb);
1964
1973#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT 1965#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
1974 /* close the parallel port */ 1966 /* close the parallel port */
1975 1967
@@ -2019,11 +2011,6 @@ static int mos7720_port_probe(struct usb_serial_port *port)
2019 if (!mos7720_port) 2011 if (!mos7720_port)
2020 return -ENOMEM; 2012 return -ENOMEM;
2021 2013
2022 /* Initialize all port interrupt end point to port 0 int endpoint.
2023 * Our device has only one interrupt endpoint common to all ports.
2024 */
2025 port->interrupt_in_endpointAddress =
2026 port->serial->port[0]->interrupt_in_endpointAddress;
2027 mos7720_port->port = port; 2014 mos7720_port->port = port;
2028 2015
2029 usb_set_serial_port_data(port, mos7720_port); 2016 usb_set_serial_port_data(port, mos7720_port);
@@ -2053,7 +2040,6 @@ static struct usb_serial_driver moschip7720_2port_driver = {
2053 .close = mos7720_close, 2040 .close = mos7720_close,
2054 .throttle = mos7720_throttle, 2041 .throttle = mos7720_throttle,
2055 .unthrottle = mos7720_unthrottle, 2042 .unthrottle = mos7720_unthrottle,
2056 .probe = mos77xx_probe,
2057 .attach = mos7720_startup, 2043 .attach = mos7720_startup,
2058 .release = mos7720_release, 2044 .release = mos7720_release,
2059 .port_probe = mos7720_port_probe, 2045 .port_probe = mos7720_port_probe,
@@ -2067,7 +2053,7 @@ static struct usb_serial_driver moschip7720_2port_driver = {
2067 .chars_in_buffer = mos7720_chars_in_buffer, 2053 .chars_in_buffer = mos7720_chars_in_buffer,
2068 .break_ctl = mos7720_break, 2054 .break_ctl = mos7720_break,
2069 .read_bulk_callback = mos7720_bulk_in_callback, 2055 .read_bulk_callback = mos7720_bulk_in_callback,
2070 .read_int_callback = NULL /* dynamically assigned in probe() */ 2056 .read_int_callback = mos7720_interrupt_callback,
2071}; 2057};
2072 2058
2073static struct usb_serial_driver * const serial_drivers[] = { 2059static struct usb_serial_driver * const serial_drivers[] = {
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 9a220b8e810f..ea27fb23967a 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -214,7 +214,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
214 214
215struct moschip_port { 215struct moschip_port {
216 int port_num; /*Actual port number in the device(1,2,etc) */ 216 int port_num; /*Actual port number in the device(1,2,etc) */
217 struct urb *write_urb; /* write URB for this port */
218 struct urb *read_urb; /* read URB for this port */ 217 struct urb *read_urb; /* read URB for this port */
219 __u8 shadowLCR; /* last LCR value received */ 218 __u8 shadowLCR; /* last LCR value received */
220 __u8 shadowMCR; /* last MCR value received */ 219 __u8 shadowMCR; /* last MCR value received */
@@ -1037,9 +1036,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
1037 serial, 1036 serial,
1038 serial->port[0]->interrupt_in_urb->interval); 1037 serial->port[0]->interrupt_in_urb->interval);
1039 1038
1040 /* start interrupt read for mos7840 * 1039 /* start interrupt read for mos7840 */
1041 * will continue as long as mos7840 is connected */
1042
1043 response = 1040 response =
1044 usb_submit_urb(serial->port[0]->interrupt_in_urb, 1041 usb_submit_urb(serial->port[0]->interrupt_in_urb,
1045 GFP_KERNEL); 1042 GFP_KERNEL);
@@ -1186,7 +1183,6 @@ static void mos7840_close(struct usb_serial_port *port)
1186 } 1183 }
1187 } 1184 }
1188 1185
1189 usb_kill_urb(mos7840_port->write_urb);
1190 usb_kill_urb(mos7840_port->read_urb); 1186 usb_kill_urb(mos7840_port->read_urb);
1191 mos7840_port->read_urb_busy = false; 1187 mos7840_port->read_urb_busy = false;
1192 1188
@@ -1199,12 +1195,6 @@ static void mos7840_close(struct usb_serial_port *port)
1199 } 1195 }
1200 } 1196 }
1201 1197
1202 if (mos7840_port->write_urb) {
1203 /* if this urb had a transfer buffer already (old tx) free it */
1204 kfree(mos7840_port->write_urb->transfer_buffer);
1205 usb_free_urb(mos7840_port->write_urb);
1206 }
1207
1208 Data = 0x0; 1198 Data = 0x0;
1209 mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); 1199 mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1210 1200
@@ -2113,6 +2103,17 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
2113 return mos7840_num_ports; 2103 return mos7840_num_ports;
2114} 2104}
2115 2105
2106static int mos7840_attach(struct usb_serial *serial)
2107{
2108 if (serial->num_bulk_in < serial->num_ports ||
2109 serial->num_bulk_out < serial->num_ports) {
2110 dev_err(&serial->interface->dev, "missing endpoints\n");
2111 return -ENODEV;
2112 }
2113
2114 return 0;
2115}
2116
2116static int mos7840_port_probe(struct usb_serial_port *port) 2117static int mos7840_port_probe(struct usb_serial_port *port)
2117{ 2118{
2118 struct usb_serial *serial = port->serial; 2119 struct usb_serial *serial = port->serial;
@@ -2388,6 +2389,7 @@ static struct usb_serial_driver moschip7840_4port_device = {
2388 .tiocmset = mos7840_tiocmset, 2389 .tiocmset = mos7840_tiocmset,
2389 .tiocmiwait = usb_serial_generic_tiocmiwait, 2390 .tiocmiwait = usb_serial_generic_tiocmiwait,
2390 .get_icount = usb_serial_generic_get_icount, 2391 .get_icount = usb_serial_generic_get_icount,
2392 .attach = mos7840_attach,
2391 .port_probe = mos7840_port_probe, 2393 .port_probe = mos7840_port_probe,
2392 .port_remove = mos7840_port_remove, 2394 .port_remove = mos7840_port_remove,
2393 .read_bulk_callback = mos7840_bulk_in_callback, 2395 .read_bulk_callback = mos7840_bulk_in_callback,
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index f6c6900bccf0..a180b17d2432 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -38,6 +38,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
38 const unsigned char *buf, int count); 38 const unsigned char *buf, int count);
39static int omninet_write_room(struct tty_struct *tty); 39static int omninet_write_room(struct tty_struct *tty);
40static void omninet_disconnect(struct usb_serial *serial); 40static void omninet_disconnect(struct usb_serial *serial);
41static int omninet_attach(struct usb_serial *serial);
41static int omninet_port_probe(struct usb_serial_port *port); 42static int omninet_port_probe(struct usb_serial_port *port);
42static int omninet_port_remove(struct usb_serial_port *port); 43static int omninet_port_remove(struct usb_serial_port *port);
43 44
@@ -56,6 +57,7 @@ static struct usb_serial_driver zyxel_omninet_device = {
56 .description = "ZyXEL - omni.net lcd plus usb", 57 .description = "ZyXEL - omni.net lcd plus usb",
57 .id_table = id_table, 58 .id_table = id_table,
58 .num_ports = 1, 59 .num_ports = 1,
60 .attach = omninet_attach,
59 .port_probe = omninet_port_probe, 61 .port_probe = omninet_port_probe,
60 .port_remove = omninet_port_remove, 62 .port_remove = omninet_port_remove,
61 .open = omninet_open, 63 .open = omninet_open,
@@ -104,6 +106,17 @@ struct omninet_data {
104 __u8 od_outseq; /* Sequence number for bulk_out URBs */ 106 __u8 od_outseq; /* Sequence number for bulk_out URBs */
105}; 107};
106 108
109static int omninet_attach(struct usb_serial *serial)
110{
111 /* The second bulk-out endpoint is used for writing. */
112 if (serial->num_bulk_out < 2) {
113 dev_err(&serial->interface->dev, "missing endpoints\n");
114 return -ENODEV;
115 }
116
117 return 0;
118}
119
107static int omninet_port_probe(struct usb_serial_port *port) 120static int omninet_port_probe(struct usb_serial_port *port)
108{ 121{
109 struct omninet_data *od; 122 struct omninet_data *od;
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index a4b88bc038b6..b8bf52bf7a94 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -134,6 +134,7 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty);
134static int oti6858_tiocmget(struct tty_struct *tty); 134static int oti6858_tiocmget(struct tty_struct *tty);
135static int oti6858_tiocmset(struct tty_struct *tty, 135static int oti6858_tiocmset(struct tty_struct *tty,
136 unsigned int set, unsigned int clear); 136 unsigned int set, unsigned int clear);
137static int oti6858_attach(struct usb_serial *serial);
137static int oti6858_port_probe(struct usb_serial_port *port); 138static int oti6858_port_probe(struct usb_serial_port *port);
138static int oti6858_port_remove(struct usb_serial_port *port); 139static int oti6858_port_remove(struct usb_serial_port *port);
139 140
@@ -158,6 +159,7 @@ static struct usb_serial_driver oti6858_device = {
158 .write_bulk_callback = oti6858_write_bulk_callback, 159 .write_bulk_callback = oti6858_write_bulk_callback,
159 .write_room = oti6858_write_room, 160 .write_room = oti6858_write_room,
160 .chars_in_buffer = oti6858_chars_in_buffer, 161 .chars_in_buffer = oti6858_chars_in_buffer,
162 .attach = oti6858_attach,
161 .port_probe = oti6858_port_probe, 163 .port_probe = oti6858_port_probe,
162 .port_remove = oti6858_port_remove, 164 .port_remove = oti6858_port_remove,
163}; 165};
@@ -324,6 +326,20 @@ static void send_data(struct work_struct *work)
324 usb_serial_port_softint(port); 326 usb_serial_port_softint(port);
325} 327}
326 328
329static int oti6858_attach(struct usb_serial *serial)
330{
331 unsigned char num_ports = serial->num_ports;
332
333 if (serial->num_bulk_in < num_ports ||
334 serial->num_bulk_out < num_ports ||
335 serial->num_interrupt_in < num_ports) {
336 dev_err(&serial->interface->dev, "missing endpoints\n");
337 return -ENODEV;
338 }
339
340 return 0;
341}
342
327static int oti6858_port_probe(struct usb_serial_port *port) 343static int oti6858_port_probe(struct usb_serial_port *port)
328{ 344{
329 struct oti6858_private *priv; 345 struct oti6858_private *priv;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ae682e4eeaef..46fca6b75846 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -220,9 +220,17 @@ static int pl2303_probe(struct usb_serial *serial,
220static int pl2303_startup(struct usb_serial *serial) 220static int pl2303_startup(struct usb_serial *serial)
221{ 221{
222 struct pl2303_serial_private *spriv; 222 struct pl2303_serial_private *spriv;
223 unsigned char num_ports = serial->num_ports;
223 enum pl2303_type type = TYPE_01; 224 enum pl2303_type type = TYPE_01;
224 unsigned char *buf; 225 unsigned char *buf;
225 226
227 if (serial->num_bulk_in < num_ports ||
228 serial->num_bulk_out < num_ports ||
229 serial->num_interrupt_in < num_ports) {
230 dev_err(&serial->interface->dev, "missing endpoints\n");
231 return -ENODEV;
232 }
233
226 spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); 234 spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
227 if (!spriv) 235 if (!spriv)
228 return -ENOMEM; 236 return -ENOMEM;
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 659cb8606bd9..5709cc93b083 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -408,16 +408,12 @@ static void qt2_close(struct usb_serial_port *port)
408{ 408{
409 struct usb_serial *serial; 409 struct usb_serial *serial;
410 struct qt2_port_private *port_priv; 410 struct qt2_port_private *port_priv;
411 unsigned long flags;
412 int i; 411 int i;
413 412
414 serial = port->serial; 413 serial = port->serial;
415 port_priv = usb_get_serial_port_data(port); 414 port_priv = usb_get_serial_port_data(port);
416 415
417 spin_lock_irqsave(&port_priv->urb_lock, flags);
418 usb_kill_urb(port_priv->write_urb); 416 usb_kill_urb(port_priv->write_urb);
419 port_priv->urb_in_use = false;
420 spin_unlock_irqrestore(&port_priv->urb_lock, flags);
421 417
422 /* flush the port transmit buffer */ 418 /* flush the port transmit buffer */
423 i = usb_control_msg(serial->dev, 419 i = usb_control_msg(serial->dev,
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index ef0dbf0703c5..475e6c31b266 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -154,6 +154,19 @@ static int spcp8x5_probe(struct usb_serial *serial,
154 return 0; 154 return 0;
155} 155}
156 156
157static int spcp8x5_attach(struct usb_serial *serial)
158{
159 unsigned char num_ports = serial->num_ports;
160
161 if (serial->num_bulk_in < num_ports ||
162 serial->num_bulk_out < num_ports) {
163 dev_err(&serial->interface->dev, "missing endpoints\n");
164 return -ENODEV;
165 }
166
167 return 0;
168}
169
157static int spcp8x5_port_probe(struct usb_serial_port *port) 170static int spcp8x5_port_probe(struct usb_serial_port *port)
158{ 171{
159 const struct usb_device_id *id = usb_get_serial_data(port->serial); 172 const struct usb_device_id *id = usb_get_serial_data(port->serial);
@@ -477,6 +490,7 @@ static struct usb_serial_driver spcp8x5_device = {
477 .tiocmget = spcp8x5_tiocmget, 490 .tiocmget = spcp8x5_tiocmget,
478 .tiocmset = spcp8x5_tiocmset, 491 .tiocmset = spcp8x5_tiocmset,
479 .probe = spcp8x5_probe, 492 .probe = spcp8x5_probe,
493 .attach = spcp8x5_attach,
480 .port_probe = spcp8x5_port_probe, 494 .port_probe = spcp8x5_port_probe,
481 .port_remove = spcp8x5_port_remove, 495 .port_remove = spcp8x5_port_remove,
482}; 496};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 8db9d071d940..64b85b8dedf3 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -579,6 +579,13 @@ static int ti_startup(struct usb_serial *serial)
579 goto free_tdev; 579 goto free_tdev;
580 } 580 }
581 581
582 if (serial->num_bulk_in < serial->num_ports ||
583 serial->num_bulk_out < serial->num_ports) {
584 dev_err(&serial->interface->dev, "missing endpoints\n");
585 status = -ENODEV;
586 goto free_tdev;
587 }
588
582 return 0; 589 return 0;
583 590
584free_tdev: 591free_tdev: