USB: serial: kl5kusb105: fix open error path
authorJohan Hovold <johan@kernel.org>
Tue, 29 Nov 2016 15:55:01 +0000 (16:55 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Thu, 16 Mar 2017 02:18:28 +0000 (02:18 +0000)
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>
[bwh: Backported to 3.2: replaced code was using dbg()]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/usb/serial/kl5kusb105.c

index 2cf92f1..a4b9068 100644 (file)
@@ -338,7 +338,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;
        rc = usb_serial_generic_open(tty, port);
        if (rc) {
                retval = rc;
-               goto exit;
+               goto err_free_cfg;
        }
 
        rc = usb_control_msg(port->serial->dev,
        }
 
        rc = usb_control_msg(port->serial->dev,
@@ -357,17 +357,32 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
                dbg("%s - enabled reading", __func__);
 
        rc = klsi_105_get_line_state(port, &line_state);
                dbg("%s - enabled reading", __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);
-               dbg("%s - read line state 0x%lx", __func__, line_state);
-               retval = 0;
-       } else
+       if (rc < 0) {
                retval = rc;
                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);
 
 
-exit:
+       return 0;
+
+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);
        kfree(cfg);
+
        return retval;
 }
 
        return retval;
 }