aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-01-12 08:56:10 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-14 08:00:19 -0400
commitca4e6525df053f0e023195b571c9d6241197bc09 (patch)
tree245fae48a8506eae942bab31a9828e09eabe1f2e
parent94bbbfe21b5a592dc5306f2203d6716734cf9b67 (diff)
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/ark3116.c25
1 files changed, 19 insertions, 6 deletions
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)
373 dev_dbg(&port->dev, 373 dev_dbg(&port->dev,
374 "%s - usb_serial_generic_open failed: %d\n", 374 "%s - usb_serial_generic_open failed: %d\n",
375 __func__, result); 375 __func__, result);
376 goto err_out; 376 goto err_free;
377 } 377 }
378 378
379 /* remove any data still left: also clears error state */ 379 /* remove any data still left: also clears error state */
380 ark3116_read_reg(serial, UART_RX, buf); 380 ark3116_read_reg(serial, UART_RX, buf);
381 381
382 /* read modem status */ 382 /* read modem status */
383 priv->msr = ark3116_read_reg(serial, UART_MSR, buf); 383 result = ark3116_read_reg(serial, UART_MSR, buf);
384 if (result < 0)
385 goto err_close;
386 priv->msr = *buf;
387
384 /* read line status */ 388 /* read line status */
385 priv->lsr = ark3116_read_reg(serial, UART_LSR, buf); 389 result = ark3116_read_reg(serial, UART_LSR, buf);
390 if (result < 0)
391 goto err_close;
392 priv->lsr = *buf;
386 393
387 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 394 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
388 if (result) { 395 if (result) {
389 dev_err(&port->dev, "submit irq_in urb failed %d\n", 396 dev_err(&port->dev, "submit irq_in urb failed %d\n",
390 result); 397 result);
391 ark3116_close(port); 398 goto err_close;
392 goto err_out;
393 } 399 }
394 400
395 /* activate interrupts */ 401 /* activate interrupts */
@@ -402,8 +408,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
402 if (tty) 408 if (tty)
403 ark3116_set_termios(tty, port, NULL); 409 ark3116_set_termios(tty, port, NULL);
404 410
405err_out:
406 kfree(buf); 411 kfree(buf);
412
413 return 0;
414
415err_close:
416 usb_serial_generic_close(port);
417err_free:
418 kfree(buf);
419
407 return result; 420 return result;
408} 421}
409 422