From d14654dff7a3520b5220367b848732a0a8ccdabe Mon Sep 17 00:00:00 2001 From: Paul Chavent Date: Mon, 16 Sep 2013 08:40:59 +0200 Subject: USB: serial: call handle_dcd_change in ftdi driver. When the device receive a DCD status change, forward the signal to the USB serial system. This way, we can detect, for instance, PPS pulses. Signed-off-by: Paul Chavent Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c45f9c0..f53298d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1966,8 +1966,16 @@ static int ftdi_process_packet(struct usb_serial_port *port, port->icount.dsr++; if (diff_status & FTDI_RS0_RI) port->icount.rng++; - if (diff_status & FTDI_RS0_RLSD) + if (diff_status & FTDI_RS0_RLSD) { + struct tty_struct *tty; + port->icount.dcd++; + tty = tty_port_tty_get(&port->port); + if (tty) + usb_serial_handle_dcd_change(port, tty, + status & FTDI_RS0_RLSD); + tty_kref_put(tty); + } wake_up_interruptible(&port->port.delta_msr_wait); priv->prev_status = status; -- cgit v1.1 From 833efc0ed19ce9ed7a84dfd3684eb9d892fe9ded Mon Sep 17 00:00:00 2001 From: Paul Chavent Date: Mon, 16 Sep 2013 08:41:00 +0200 Subject: USB: serial: invoke dcd_change ldisc's handler. The DCD pin of the serial port can receive a PPS signal. By calling the port line discipline dcd handle, this patch allow to monitor PPS through USB serial devices. However the performance aren't as good as the uart drivers, so document this point too. Signed-off-by: Paul Chavent Acked-by: Rodolfo Giometti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 1f31e6b..3a5dac8 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -570,6 +570,16 @@ void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status); + if (tty) { + struct tty_ldisc *ld = tty_ldisc_ref(tty); + + if (ld) { + if (ld->ops->dcd_change) + ld->ops->dcd_change(tty, status); + tty_ldisc_deref(ld); + } + } + if (status) wake_up_interruptible(&port->open_wait); else if (tty && !C_CLOCAL(tty)) -- cgit v1.1 From 5287bf726ff8a7353e883b73576710fd53dc88bb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 6 Oct 2013 03:32:53 +0300 Subject: USB: cyberjack: fix buggy integer overflow test "old_rdtodo" and "size" are short type. They are type promoted to int and the condition is never true. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cyberjack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 7814262..6e1b69d 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -279,7 +279,7 @@ static void cyberjack_read_int_callback(struct urb *urb) old_rdtodo = priv->rdtodo; - if (old_rdtodo + size < old_rdtodo) { + if (old_rdtodo > SHRT_MAX - size) { dev_dbg(dev, "To many bulk_in urbs to do.\n"); spin_unlock(&priv->lock); goto resubmit; -- cgit v1.1 From 92ad247995c587e07cb67dcc8aafac4db636e394 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 9 Oct 2013 17:01:10 +0200 Subject: USB: serial: clean up comments in generic driver Clean up some comments, drop excessive comments and fix-up style. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 57 +++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 32 deletions(-) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 3a5dac8..fce3746 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -7,7 +7,6 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. - * */ #include @@ -37,7 +36,6 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ -/* All of the device info needed for the Generic Serial Converter */ struct usb_serial_driver usb_serial_generic_device = { .driver = { .owner = THIS_MODULE, @@ -66,7 +64,6 @@ int usb_serial_generic_register(void) generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; - /* register our generic driver with ourselves */ retval = usb_serial_register_drivers(serial_drivers, "usbserial_generic", generic_device_ids); #endif @@ -76,7 +73,6 @@ int usb_serial_generic_register(void) void usb_serial_generic_deregister(void) { #ifdef CONFIG_USB_SERIAL_GENERIC - /* remove our generic driver */ usb_serial_deregister_drivers(serial_drivers); #endif } @@ -86,13 +82,11 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port int result = 0; unsigned long flags; - /* clear the throttle flags */ spin_lock_irqsave(&port->lock, flags); port->throttled = 0; port->throttle_req = 0; spin_unlock_irqrestore(&port->lock, flags); - /* if we have a bulk endpoint, start reading from it */ if (port->bulk_in_size) result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); @@ -127,10 +121,12 @@ int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, } /** - * usb_serial_generic_write_start - kick off an URB write - * @port: Pointer to the &struct usb_serial_port data + * usb_serial_generic_write_start - start writing buffered data + * @port: usb-serial port + * + * Serialised using USB_SERIAL_WRITE_BUSY flag. * - * Returns zero on success, or a negative errno value + * Return: Zero on success or if busy, otherwise a negative errno value. */ static int usb_serial_generic_write_start(struct usb_serial_port *port) { @@ -175,9 +171,10 @@ retry: clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); return result; } - - /* Try sending off another urb, unless in irq context (in which case - * there will be no free urb). */ + /* + * Try sending off another urb, unless in irq context (in which case + * there will be no free urb). + */ if (!in_irq()) goto retry; @@ -187,22 +184,20 @@ retry: } /** - * usb_serial_generic_write - generic write function for serial USB devices - * @tty: Pointer to &struct tty_struct for the device - * @port: Pointer to the &usb_serial_port structure for the device - * @buf: Pointer to the data to write - * @count: Number of bytes to write + * usb_serial_generic_write - generic write function + * @tty: tty for the port + * @port: usb-serial port + * @buf: data to write + * @count: number of bytes to write * - * Returns the number of characters actually written, which may be anything - * from zero to @count. If an error occurs, it returns the negative errno - * value. + * Return: The number of characters buffered, which may be anything from + * zero to @count, or a negative errno value. */ int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { int result; - /* only do something if we have a bulk out endpoint */ if (!port->bulk_out_size) return -ENODEV; @@ -337,10 +332,11 @@ void usb_serial_generic_process_read_urb(struct urb *urb) if (!urb->actual_length) return; - - /* The per character mucking around with sysrq path it too slow for - stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases - where the USB serial is not a console anyway */ + /* + * The per character mucking around with sysrq path it too slow for + * stuff like 3G modems, so shortcircuit it in the 99.9999999% of + * cases where the USB serial is not a console anyway. + */ if (!port->port.console || !port->sysrq) tty_insert_flip_string(&port->port, ch, urb->actual_length); else { @@ -425,8 +421,6 @@ void usb_serial_generic_throttle(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; unsigned long flags; - /* Set the throttle request flag. It will be picked up - * by usb_serial_generic_read_bulk_callback(). */ spin_lock_irqsave(&port->lock, flags); port->throttle_req = 1; spin_unlock_irqrestore(&port->lock, flags); @@ -438,7 +432,6 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; int was_throttled; - /* Clear the throttle flags */ spin_lock_irq(&port->lock); was_throttled = port->throttled; port->throttled = port->throttle_req = 0; @@ -558,10 +551,10 @@ int usb_serial_handle_break(struct usb_serial_port *port) EXPORT_SYMBOL_GPL(usb_serial_handle_break); /** - * usb_serial_handle_dcd_change - handle a change of carrier detect state - * @port: usb_serial_port structure for the open port - * @tty: tty_struct structure for the port - * @status: new carrier detect status, nonzero if active + * usb_serial_handle_dcd_change - handle a change of carrier detect state + * @port: usb-serial port + * @tty: tty for the port + * @status: new carrier detect status, nonzero if active */ void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, struct tty_struct *tty, unsigned int status) -- cgit v1.1 From 818f60365a29ab1266d92c6a91094fbf93465ff8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 9 Oct 2013 17:01:11 +0200 Subject: USB: serial: add memory flags to usb_serial_generic_write_start Add memory-flags parameter to usb_serial_generic_write_start which is called from write, resume and completion handler, all with different allocation requirements. Note that by using the memory flag to determine when called from the completion handler, everything will work as before even if the completion handler is run with interrupts enabled (as suggested). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index fce3746..31f7829 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -123,12 +123,14 @@ int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, /** * usb_serial_generic_write_start - start writing buffered data * @port: usb-serial port + * @mem_flags: flags to use for memory allocations * * Serialised using USB_SERIAL_WRITE_BUSY flag. * * Return: Zero on success or if busy, otherwise a negative errno value. */ -static int usb_serial_generic_write_start(struct usb_serial_port *port) +static int usb_serial_generic_write_start(struct usb_serial_port *port, + gfp_t mem_flags) { struct urb *urb; int count, result; @@ -159,7 +161,7 @@ retry: spin_unlock_irqrestore(&port->lock, flags); clear_bit(i, &port->write_urbs_free); - result = usb_submit_urb(urb, GFP_ATOMIC); + result = usb_submit_urb(urb, mem_flags); if (result) { dev_err_console(port, "%s - error submitting urb: %d\n", __func__, result); @@ -172,10 +174,10 @@ retry: return result; } /* - * Try sending off another urb, unless in irq context (in which case - * there will be no free urb). + * Try sending off another urb, unless called from completion handler + * (in which case there will be no free urb or no data). */ - if (!in_irq()) + if (mem_flags != GFP_ATOMIC) goto retry; clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); @@ -205,7 +207,7 @@ int usb_serial_generic_write(struct tty_struct *tty, return 0; count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); - result = usb_serial_generic_write_start(port); + result = usb_serial_generic_write_start(port, GFP_KERNEL); if (result) return result; @@ -409,7 +411,7 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) kfifo_reset_out(&port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); } else { - usb_serial_generic_write_start(port); + usb_serial_generic_write_start(port, GFP_ATOMIC); } usb_serial_port_softint(port); @@ -598,7 +600,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) } if (port->bulk_out_size) { - r = usb_serial_generic_write_start(port); + r = usb_serial_generic_write_start(port, GFP_NOIO); if (r < 0) c++; } -- cgit v1.1 From 706cd17e8559c96dc883ba692c931f1ef31fbc5c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 9 Oct 2013 17:01:12 +0200 Subject: USB: serial: export usb_serial_generic_write_start Export usb_serial_generic_write_start which is needed when implementing a custom resume function while still relying on the generic write implementation. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 31f7829..2b01ec8 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -129,7 +129,7 @@ int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, * * Return: Zero on success or if busy, otherwise a negative errno value. */ -static int usb_serial_generic_write_start(struct usb_serial_port *port, +int usb_serial_generic_write_start(struct usb_serial_port *port, gfp_t mem_flags) { struct urb *urb; @@ -184,6 +184,7 @@ retry: return 0; } +EXPORT_SYMBOL_GPL(usb_serial_generic_write_start); /** * usb_serial_generic_write - generic write function -- cgit v1.1 From a91ccd26e75235d86248d018fe3779732bcafd8d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 9 Oct 2013 17:01:09 +0200 Subject: USB: mos7840: fix tiocmget error handling Make sure to return errors from tiocmget rather than rely on uninitialised stack data. Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index fdf9535..e5bdd98 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1532,7 +1532,11 @@ static int mos7840_tiocmget(struct tty_struct *tty) return -ENODEV; status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr); + if (status != 1) + return -EIO; status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr); + if (status != 1) + return -EIO; result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) | ((mcr & MCR_RTS) ? TIOCM_RTS : 0) | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0) -- cgit v1.1 From 0636fc507a976cdc40f21bdbcce6f0b98ff1dfe9 Mon Sep 17 00:00:00 2001 From: Rui li Date: Fri, 25 Oct 2013 10:57:21 +0800 Subject: =?UTF-8?q?USB=EF=BC=9Aadd=20new=20zte=203g-dongle's=20pid=20to=20?= =?UTF-8?q?option.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rui li Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/usb/serial') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index acaee06..c3d9485 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1376,6 +1376,23 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1545, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1546, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1547, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1565, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1566, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1567, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1589, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1590, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1591, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1592, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1594, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1596, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1598, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1600, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, -- cgit v1.1