USB: serial: kl5kusb105: fix open error path
authorJohan Hovold <johan@kernel.org>
Tue, 29 Nov 2016 15:55:01 +0000 (16:55 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Jun 2017 22:46:48 +0000 (00:46 +0200)
commit 6774d5f53271d5f60464f824748995b71da401ab upstream.

Kill urbs and disable read before returning from open on failure to
retrieve the line state.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
drivers/usb/serial/kl5kusb105.c

index 1b4054fe52a5fccf85d4be4cbe4cbb3b30ff03b7..70e163d21e9aa7a68b02208cde114ebb18c7ddf5 100644 (file)
@@ -304,7 +304,7 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
        rc = usb_serial_generic_open(tty, port);
        if (rc) {
                retval = rc;
-               goto exit;
+               goto err_free_cfg;
        }
 
        rc = usb_control_msg(port->serial->dev,
@@ -323,17 +323,32 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
                dev_dbg(&port->dev, "%s - enabled reading\n", __func__);
 
        rc = klsi_105_get_line_state(port, &line_state);
-       if (rc >= 0) {
-               spin_lock_irqsave(&priv->lock, flags);
-               priv->line_state = line_state;
-               spin_unlock_irqrestore(&priv->lock, flags);
-               dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, line_state);
-               retval = 0;
-       } else
+       if (rc < 0) {
                retval = rc;
+               goto err_disable_read;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->line_state = line_state;
+       spin_unlock_irqrestore(&priv->lock, flags);
+       dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__,
+                       line_state);
+
+       return 0;
 
-exit:
+err_disable_read:
+       usb_control_msg(port->serial->dev,
+                            usb_sndctrlpipe(port->serial->dev, 0),
+                            KL5KUSB105A_SIO_CONFIGURE,
+                            USB_TYPE_VENDOR | USB_DIR_OUT,
+                            KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
+                            0, /* index */
+                            NULL, 0,
+                            KLSI_TIMEOUT);
+       usb_serial_generic_close(port);
+err_free_cfg:
        kfree(cfg);
+
        return retval;
 }