| From a99d5e90ef714838f3790b526d0b5ed0cfaa7cfd Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Thu, 12 Jan 2017 14:56:10 +0100 |
| Subject: [PATCH] USB: serial: ark3116: fix open error handling |
| |
| commit b631433b175f1002a31020e09bbfc2e5caecf290 upstream. |
| |
| Fix open error handling which failed to detect errors when reading the |
| MSR and LSR registers, something which could lead to the shadow |
| registers being initialised from errnos. |
| |
| Note that calling the generic close implementation is sufficient in the |
| error paths as the interrupt urb has not yet been submitted and the |
| register updates have not been made. |
| |
| Fixes: f4c1e8d597d1 ("USB: ark3116: Make existing functions 16450-aware |
| and add close and release functions.") |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c |
| index 7812052dc700..754fc3e41005 100644 |
| --- a/drivers/usb/serial/ark3116.c |
| +++ b/drivers/usb/serial/ark3116.c |
| @@ -373,23 +373,29 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) |
| dev_dbg(&port->dev, |
| "%s - usb_serial_generic_open failed: %d\n", |
| __func__, result); |
| - goto err_out; |
| + goto err_free; |
| } |
| |
| /* remove any data still left: also clears error state */ |
| ark3116_read_reg(serial, UART_RX, buf); |
| |
| /* read modem status */ |
| - priv->msr = ark3116_read_reg(serial, UART_MSR, buf); |
| + result = ark3116_read_reg(serial, UART_MSR, buf); |
| + if (result < 0) |
| + goto err_close; |
| + priv->msr = *buf; |
| + |
| /* read line status */ |
| - priv->lsr = ark3116_read_reg(serial, UART_LSR, buf); |
| + result = ark3116_read_reg(serial, UART_LSR, buf); |
| + if (result < 0) |
| + goto err_close; |
| + priv->lsr = *buf; |
| |
| result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
| if (result) { |
| dev_err(&port->dev, "submit irq_in urb failed %d\n", |
| result); |
| - ark3116_close(port); |
| - goto err_out; |
| + goto err_close; |
| } |
| |
| /* activate interrupts */ |
| @@ -402,8 +408,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) |
| if (tty) |
| ark3116_set_termios(tty, port, NULL); |
| |
| -err_out: |
| kfree(buf); |
| + |
| + return 0; |
| + |
| +err_close: |
| + usb_serial_generic_close(port); |
| +err_free: |
| + kfree(buf); |
| + |
| return result; |
| } |
| |
| -- |
| 2.12.0 |
| |