Merge tag 'usb-serial-5.16-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Oct 2021 14:56:03 +0000 (16:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Oct 2021 14:56:03 +0000 (16:56 +0200)
Johan writes:

USB-serial updates for 5.16-rc1

Here are the USB-serial updates for 5.16-rc1, including:

 - conversions of usb_control_msg() calls to use the new wrappers where
   appropriate
 - fix of the keyspan probe error handling after a low-order allocation
   failure (e.g. due to fault injection)
 - allow hung up ports to be runtime suspended

Included are also some related clean ups.

All have been in linux-next with no reported issues.

* tag 'usb-serial-5.16-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial:
  USB: serial: keyspan: fix memleak on probe errors
  USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send()
  USB: serial: ch314: use usb_control_msg_recv()
  USB: serial: kl5kusb105: drop line-status helper
  USB: serial: kl5kusb105: simplify line-status handling
  USB: serial: kl5kusb105: clean up line-status handling
  USB: serial: kl5kusb105: use usb_control_msg_recv() and usb_control_msg_send()
  USB: serial: keyspan_pda: use usb_control_msg_recv()
  USB: serial: ftdi_sio: use usb_control_msg_recv()
  USB: serial: f81232: use usb_control_msg_recv() and usb_control_msg_send()
  USB: serial: allow hung up ports to be suspended
  USB: serial: clean up core error labels

drivers/usb/serial/ch341.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/f81232.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/usb-serial.c

index 2db917e..29f4b87 100644 (file)
@@ -131,17 +131,11 @@ static int ch341_control_in(struct usb_device *dev,
        dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x,%u)\n", __func__,
                request, value, index, bufsize);
 
-       r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
-                           USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                           value, index, buf, bufsize, DEFAULT_TIMEOUT);
-       if (r < (int)bufsize) {
-               if (r >= 0) {
-                       dev_err(&dev->dev,
-                               "short control message received (%d < %u)\n",
-                               r, bufsize);
-                       r = -EIO;
-               }
-
+       r = usb_control_msg_recv(dev, 0, request,
+                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                                value, index, buf, bufsize, DEFAULT_TIMEOUT,
+                                GFP_KERNEL);
+       if (r) {
                dev_err(&dev->dev, "failed to receive control message: %d\n",
                        r);
                return r;
@@ -287,24 +281,19 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)
 static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
 {
        const unsigned int size = 2;
-       char *buffer;
+       u8 buffer[2];
        int r;
        unsigned long flags;
 
-       buffer = kmalloc(size, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-
        r = ch341_control_in(dev, CH341_REQ_READ_REG, 0x0706, 0, buffer, size);
-       if (r < 0)
-               goto out;
+       if (r)
+               return r;
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-out:   kfree(buffer);
-       return r;
+       return 0;
 }
 
 /* -------------------------------------------------------------------------- */
@@ -312,31 +301,28 @@ out:      kfree(buffer);
 static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
 {
        const unsigned int size = 2;
-       char *buffer;
+       u8 buffer[2];
        int r;
 
-       buffer = kmalloc(size, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-
        /* expect two bytes 0x27 0x00 */
        r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size);
-       if (r < 0)
-               goto out;
+       if (r)
+               return r;
        dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]);
 
        r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);
        if (r < 0)
-               goto out;
+               return r;
 
        r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr);
        if (r < 0)
-               goto out;
+               return r;
 
        r = ch341_set_handshake(dev, priv->mcr);
+       if (r < 0)
+               return r;
 
-out:   kfree(buffer);
-       return r;
+       return 0;
 }
 
 static int ch341_detect_quirks(struct usb_serial_port *port)
@@ -345,40 +331,27 @@ static int ch341_detect_quirks(struct usb_serial_port *port)
        struct usb_device *udev = port->serial->dev;
        const unsigned int size = 2;
        unsigned long quirks = 0;
-       char *buffer;
+       u8 buffer[2];
        int r;
 
-       buffer = kmalloc(size, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-
        /*
         * A subset of CH34x devices does not support all features. The
         * prescaler is limited and there is no support for sending a RS232
         * break condition. A read failure when trying to set up the latter is
         * used to detect these devices.
         */
-       r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), CH341_REQ_READ_REG,
-                           USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                           CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT);
+       r = usb_control_msg_recv(udev, 0, CH341_REQ_READ_REG,
+                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                                CH341_REG_BREAK, 0, &buffer, size,
+                                DEFAULT_TIMEOUT, GFP_KERNEL);
        if (r == -EPIPE) {
                dev_info(&port->dev, "break control not supported, using simulated break\n");
                quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK;
                r = 0;
-               goto out;
-       }
-
-       if (r != size) {
-               if (r >= 0)
-                       r = -EIO;
+       } else if (r) {
                dev_err(&port->dev, "failed to read break control: %d\n", r);
-               goto out;
        }
 
-       r = 0;
-out:
-       kfree(buffer);
-
        if (quirks) {
                dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks);
                priv->quirks |= quirks;
@@ -647,23 +620,19 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
        struct ch341_private *priv = usb_get_serial_port_data(port);
        int r;
        uint16_t reg_contents;
-       uint8_t *break_reg;
+       uint8_t break_reg[2];
 
        if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) {
                ch341_simulate_break(tty, break_state);
                return;
        }
 
-       break_reg = kmalloc(2, GFP_KERNEL);
-       if (!break_reg)
-               return;
-
        r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,
                        ch341_break_reg, 0, break_reg, 2);
-       if (r < 0) {
+       if (r) {
                dev_err(&port->dev, "%s - USB control read error (%d)\n",
                                __func__, r);
-               goto out;
+               return;
        }
        dev_dbg(&port->dev, "%s - initial ch341 break register contents - reg1: %x, reg2: %x\n",
                __func__, break_reg[0], break_reg[1]);
@@ -684,8 +653,6 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
        if (r < 0)
                dev_err(&port->dev, "%s - USB control write error (%d)\n",
                                __func__, r);
-out:
-       kfree(break_reg);
 }
 
 static int ch341_tiocmset(struct tty_struct *tty,
index 1892798..7705328 100644 (file)
@@ -631,30 +631,20 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req,
 {
        struct usb_serial *serial = port->serial;
        struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
-       void *dmabuf;
        int result;
 
-       dmabuf = kmalloc(bufsize, GFP_KERNEL);
-       if (!dmabuf)
-               return -ENOMEM;
 
-       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                       req, REQTYPE_INTERFACE_TO_HOST, 0,
-                       port_priv->bInterfaceNumber, dmabuf, bufsize,
-                       USB_CTRL_GET_TIMEOUT);
-       if (result == bufsize) {
-               memcpy(buf, dmabuf, bufsize);
-               result = 0;
-       } else {
+       result = usb_control_msg_recv(serial->dev, 0, req,
+                       REQTYPE_INTERFACE_TO_HOST, 0,
+                       port_priv->bInterfaceNumber, buf, bufsize,
+                       USB_CTRL_SET_TIMEOUT, GFP_KERNEL);
+       if (result) {
                dev_err(&port->dev, "failed get req 0x%x size %d status: %d\n",
                                req, bufsize, result);
-               if (result >= 0)
-                       result = -EIO;
+               return result;
        }
 
-       kfree(dmabuf);
-
-       return result;
+       return 0;
 }
 
 /*
@@ -672,31 +662,19 @@ static int cp210x_read_u8_reg(struct usb_serial_port *port, u8 req, u8 *val)
 static int cp210x_read_vendor_block(struct usb_serial *serial, u8 type, u16 val,
                                    void *buf, int bufsize)
 {
-       void *dmabuf;
        int result;
 
-       dmabuf = kmalloc(bufsize, GFP_KERNEL);
-       if (!dmabuf)
-               return -ENOMEM;
-
-       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                                CP210X_VENDOR_SPECIFIC, type, val,
-                                cp210x_interface_num(serial), dmabuf, bufsize,
-                                USB_CTRL_GET_TIMEOUT);
-       if (result == bufsize) {
-               memcpy(buf, dmabuf, bufsize);
-               result = 0;
-       } else {
+       result = usb_control_msg_recv(serial->dev, 0, CP210X_VENDOR_SPECIFIC,
+                       type, val, cp210x_interface_num(serial), buf, bufsize,
+                       USB_CTRL_GET_TIMEOUT, GFP_KERNEL);
+       if (result) {
                dev_err(&serial->interface->dev,
                        "failed to get vendor val 0x%04x size %d: %d\n", val,
                        bufsize, result);
-               if (result >= 0)
-                       result = -EIO;
+               return result;
        }
 
-       kfree(dmabuf);
-
-       return result;
+       return 0;
 }
 
 /*
@@ -730,21 +708,13 @@ static int cp210x_write_reg_block(struct usb_serial_port *port, u8 req,
 {
        struct usb_serial *serial = port->serial;
        struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
-       void *dmabuf;
        int result;
 
-       dmabuf = kmemdup(buf, bufsize, GFP_KERNEL);
-       if (!dmabuf)
-               return -ENOMEM;
-
-       result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       req, REQTYPE_HOST_TO_INTERFACE, 0,
-                       port_priv->bInterfaceNumber, dmabuf, bufsize,
-                       USB_CTRL_SET_TIMEOUT);
-
-       kfree(dmabuf);
-
-       if (result < 0) {
+       result = usb_control_msg_send(serial->dev, 0, req,
+                       REQTYPE_HOST_TO_INTERFACE, 0,
+                       port_priv->bInterfaceNumber, buf, bufsize,
+                       USB_CTRL_SET_TIMEOUT, GFP_KERNEL);
+       if (result) {
                dev_err(&port->dev, "failed set req 0x%x size %d status: %d\n",
                                req, bufsize, result);
                return result;
@@ -773,21 +743,12 @@ static int cp210x_write_u32_reg(struct usb_serial_port *port, u8 req, u32 val)
 static int cp210x_write_vendor_block(struct usb_serial *serial, u8 type,
                                     u16 val, void *buf, int bufsize)
 {
-       void *dmabuf;
        int result;
 
-       dmabuf = kmemdup(buf, bufsize, GFP_KERNEL);
-       if (!dmabuf)
-               return -ENOMEM;
-
-       result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                                CP210X_VENDOR_SPECIFIC, type, val,
-                                cp210x_interface_num(serial), dmabuf, bufsize,
-                                USB_CTRL_SET_TIMEOUT);
-
-       kfree(dmabuf);
-
-       if (result < 0) {
+       result = usb_control_msg_send(serial->dev, 0, CP210X_VENDOR_SPECIFIC,
+                       type, val, cp210x_interface_num(serial), buf, bufsize,
+                       USB_CTRL_SET_TIMEOUT, GFP_KERNEL);
+       if (result) {
                dev_err(&serial->interface->dev,
                        "failed to set vendor val 0x%04x size %d: %d\n", val,
                        bufsize, result);
@@ -952,29 +913,21 @@ static int cp210x_get_tx_queue_byte_count(struct usb_serial_port *port,
 {
        struct usb_serial *serial = port->serial;
        struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
-       struct cp210x_comm_status *sts;
+       struct cp210x_comm_status sts;
        int result;
 
-       sts = kmalloc(sizeof(*sts), GFP_KERNEL);
-       if (!sts)
-               return -ENOMEM;
-
-       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                       CP210X_GET_COMM_STATUS, REQTYPE_INTERFACE_TO_HOST,
-                       0, port_priv->bInterfaceNumber, sts, sizeof(*sts),
-                       USB_CTRL_GET_TIMEOUT);
-       if (result == sizeof(*sts)) {
-               *count = le32_to_cpu(sts->ulAmountInOutQueue);
-               result = 0;
-       } else {
+       result = usb_control_msg_recv(serial->dev, 0, CP210X_GET_COMM_STATUS,
+                       REQTYPE_INTERFACE_TO_HOST, 0,
+                       port_priv->bInterfaceNumber, &sts, sizeof(sts),
+                       USB_CTRL_GET_TIMEOUT, GFP_KERNEL);
+       if (result) {
                dev_err(&port->dev, "failed to get comm status: %d\n", result);
-               if (result >= 0)
-                       result = -EIO;
+               return result;
        }
 
-       kfree(sts);
+       *count = le32_to_cpu(sts.ulAmountInOutQueue);
 
-       return result;
+       return 0;
 }
 
 static bool cp210x_tx_empty(struct usb_serial_port *port)
index a7a7af8..3ad1f51 100644 (file)
@@ -139,67 +139,46 @@ static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
 static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val)
 {
        int status;
-       u8 *tmp;
        struct usb_device *dev = port->serial->dev;
 
-       tmp = kmalloc(sizeof(*val), GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-
-       status = usb_control_msg(dev,
-                               usb_rcvctrlpipe(dev, 0),
-                               F81232_REGISTER_REQUEST,
-                               F81232_GET_REGISTER,
-                               reg,
-                               0,
-                               tmp,
-                               sizeof(*val),
-                               USB_CTRL_GET_TIMEOUT);
-       if (status != sizeof(*val)) {
+       status = usb_control_msg_recv(dev,
+                                     0,
+                                     F81232_REGISTER_REQUEST,
+                                     F81232_GET_REGISTER,
+                                     reg,
+                                     0,
+                                     val,
+                                     sizeof(*val),
+                                     USB_CTRL_GET_TIMEOUT,
+                                     GFP_KERNEL);
+       if (status) {
                dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
-
-               if (status < 0)
-                       status = usb_translate_errors(status);
-               else
-                       status = -EIO;
-       } else {
-               status = 0;
-               *val = *tmp;
+               status = usb_translate_errors(status);
        }
 
-       kfree(tmp);
        return status;
 }
 
 static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 val)
 {
        int status;
-       u8 *tmp;
        struct usb_device *dev = port->serial->dev;
 
-       tmp = kmalloc(sizeof(val), GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-
-       *tmp = val;
-
-       status = usb_control_msg(dev,
-                               usb_sndctrlpipe(dev, 0),
-                               F81232_REGISTER_REQUEST,
-                               F81232_SET_REGISTER,
-                               reg,
-                               0,
-                               tmp,
-                               sizeof(val),
-                               USB_CTRL_SET_TIMEOUT);
-       if (status < 0) {
+       status = usb_control_msg_send(dev,
+                                     0,
+                                     F81232_REGISTER_REQUEST,
+                                     F81232_SET_REGISTER,
+                                     reg,
+                                     0,
+                                     &val,
+                                     sizeof(val),
+                                     USB_CTRL_SET_TIMEOUT,
+                                     GFP_KERNEL);
+       if (status) {
                dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
                status = usb_translate_errors(status);
-       } else {
-               status = 0;
        }
 
-       kfree(tmp);
        return status;
 }
 
@@ -857,28 +836,22 @@ static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,
        struct usb_device *dev = interface_to_usbdev(intf);
        int retry = F81534A_ACCESS_REG_RETRY;
        int status;
-       u8 *tmp;
-
-       tmp = kmemdup(val, size, GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
 
        while (retry--) {
-               status = usb_control_msg(dev,
-                                       usb_sndctrlpipe(dev, 0),
-                                       F81232_REGISTER_REQUEST,
-                                       F81232_SET_REGISTER,
-                                       reg,
-                                       0,
-                                       tmp,
-                                       size,
-                                       USB_CTRL_SET_TIMEOUT);
-               if (status < 0) {
+               status = usb_control_msg_send(dev,
+                                             0,
+                                             F81232_REGISTER_REQUEST,
+                                             F81232_SET_REGISTER,
+                                             reg,
+                                             0,
+                                             val,
+                                             size,
+                                             USB_CTRL_SET_TIMEOUT,
+                                             GFP_KERNEL);
+               if (status) {
                        status = usb_translate_errors(status);
                        if (status == -EIO)
                                continue;
-               } else {
-                       status = 0;
                }
 
                break;
@@ -889,7 +862,6 @@ static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,
                                reg, status);
        }
 
-       kfree(tmp);
        return status;
 }
 
index 99d1982..4edebd1 100644 (file)
@@ -1437,27 +1437,15 @@ static int _read_latency_timer(struct usb_serial_port *port)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        struct usb_device *udev = port->serial->dev;
-       unsigned char *buf;
+       ubuf;
        int rv;
 
-       buf = kmalloc(1, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       rv = usb_control_msg(udev,
-                            usb_rcvctrlpipe(udev, 0),
-                            FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
-                            FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
-                            0, priv->interface,
-                            buf, 1, WDR_TIMEOUT);
-       if (rv < 1) {
-               if (rv >= 0)
-                       rv = -EIO;
-       } else {
-               rv = buf[0];
-       }
-
-       kfree(buf);
+       rv = usb_control_msg_recv(udev, 0, FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
+                                 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, 0,
+                                 priv->interface, &buf, 1, WDR_TIMEOUT,
+                                 GFP_KERNEL);
+       if (rv == 0)
+               rv = buf;
 
        return rv;
 }
@@ -1852,32 +1840,21 @@ static int ftdi_read_cbus_pins(struct usb_serial_port *port)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
-       unsigned char *buf;
+       ubuf;
        int result;
 
        result = usb_autopm_get_interface(serial->interface);
        if (result)
                return result;
 
-       buf = kmalloc(1, GFP_KERNEL);
-       if (!buf) {
-               usb_autopm_put_interface(serial->interface);
-               return -ENOMEM;
-       }
-
-       result = usb_control_msg(serial->dev,
-                                usb_rcvctrlpipe(serial->dev, 0),
-                                FTDI_SIO_READ_PINS_REQUEST,
-                                FTDI_SIO_READ_PINS_REQUEST_TYPE, 0,
-                                priv->interface, buf, 1, WDR_TIMEOUT);
-       if (result < 1) {
-               if (result >= 0)
-                       result = -EIO;
-       } else {
-               result = buf[0];
-       }
+       result = usb_control_msg_recv(serial->dev, 0,
+                                     FTDI_SIO_READ_PINS_REQUEST,
+                                     FTDI_SIO_READ_PINS_REQUEST_TYPE, 0,
+                                     priv->interface, &buf, 1, WDR_TIMEOUT,
+                                     GFP_KERNEL);
+       if (result == 0)
+               result = buf;
 
-       kfree(buf);
        usb_autopm_put_interface(serial->interface);
 
        return result;
index 87b89c9..1cfcd80 100644 (file)
@@ -2890,22 +2890,22 @@ static int keyspan_port_probe(struct usb_serial_port *port)
        for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i) {
                p_priv->in_buffer[i] = kzalloc(IN_BUFLEN, GFP_KERNEL);
                if (!p_priv->in_buffer[i])
-                       goto err_in_buffer;
+                       goto err_free_in_buffer;
        }
 
        for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i) {
                p_priv->out_buffer[i] = kzalloc(OUT_BUFLEN, GFP_KERNEL);
                if (!p_priv->out_buffer[i])
-                       goto err_out_buffer;
+                       goto err_free_out_buffer;
        }
 
        p_priv->inack_buffer = kzalloc(INACK_BUFLEN, GFP_KERNEL);
        if (!p_priv->inack_buffer)
-               goto err_inack_buffer;
+               goto err_free_out_buffer;
 
        p_priv->outcont_buffer = kzalloc(OUTCONT_BUFLEN, GFP_KERNEL);
        if (!p_priv->outcont_buffer)
-               goto err_outcont_buffer;
+               goto err_free_inack_buffer;
 
        p_priv->device_details = d_details;
 
@@ -2951,15 +2951,14 @@ static int keyspan_port_probe(struct usb_serial_port *port)
 
        return 0;
 
-err_outcont_buffer:
+err_free_inack_buffer:
        kfree(p_priv->inack_buffer);
-err_inack_buffer:
+err_free_out_buffer:
        for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i)
                kfree(p_priv->out_buffer[i]);
-err_out_buffer:
+err_free_in_buffer:
        for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i)
                kfree(p_priv->in_buffer[i]);
-err_in_buffer:
        kfree(p_priv);
 
        return -ENOMEM;
index 39b0f5f..3e7628b 100644 (file)
@@ -77,36 +77,27 @@ static int keyspan_pda_get_write_room(struct keyspan_pda_private *priv)
 {
        struct usb_serial_port *port = priv->port;
        struct usb_serial *serial = port->serial;
-       u8 *room;
+       u8 room;
        int rc;
 
-       room = kmalloc(1, GFP_KERNEL);
-       if (!room)
-               return -ENOMEM;
-
-       rc = usb_control_msg(serial->dev,
-                            usb_rcvctrlpipe(serial->dev, 0),
-                            6, /* write_room */
-                            USB_TYPE_VENDOR | USB_RECIP_INTERFACE
-                            | USB_DIR_IN,
-                            0, /* value: 0 means "remaining room" */
-                            0, /* index */
-                            room,
-                            1,
-                            2000);
-       if (rc != 1) {
-               if (rc >= 0)
-                       rc = -EIO;
+       rc = usb_control_msg_recv(serial->dev,
+                                 0,
+                                 6, /* write_room */
+                                 USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN,
+                                 0, /* value: 0 means "remaining room" */
+                                 0, /* index */
+                                 &room,
+                                 1,
+                                 2000,
+                                 GFP_KERNEL);
+       if (rc) {
                dev_dbg(&port->dev, "roomquery failed: %d\n", rc);
-               goto out_free;
+               return rc;
        }
 
-       dev_dbg(&port->dev, "roomquery says %d\n", *room);
-       rc = *room;
-out_free:
-       kfree(room);
+       dev_dbg(&port->dev, "roomquery says %d\n", room);
 
-       return rc;
+       return room;
 }
 
 static void keyspan_pda_request_unthrottle(struct work_struct *work)
@@ -381,22 +372,20 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial,
                                      unsigned char *value)
 {
        int rc;
-       u8 *data;
-
-       data = kmalloc(1, GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                            3, /* get pins */
-                            USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
-                            0, 0, data, 1, 2000);
-       if (rc == 1)
-               *value = *data;
-       else if (rc >= 0)
-               rc = -EIO;
+       u8 data;
+
+       rc = usb_control_msg_recv(serial->dev, 0,
+                                 3, /* get pins */
+                                 USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN,
+                                 0,
+                                 0,
+                                 &data,
+                                 1,
+                                 2000,
+                                 GFP_KERNEL);
+       if (rc == 0)
+               *value = data;
 
-       kfree(data);
        return rc;
 }
 
index f1e9628..edcc57b 100644 (file)
@@ -124,16 +124,18 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,
 {
        int rc;
 
-       rc = usb_control_msg(port->serial->dev,
-                       usb_sndctrlpipe(port->serial->dev, 0),
-                       KL5KUSB105A_SIO_SET_DATA,
-                       USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
-                       0, /* value */
-                       0, /* index */
-                       settings,
-                       sizeof(struct klsi_105_port_settings),
-                       KLSI_TIMEOUT);
-       if (rc < 0)
+       rc = usb_control_msg_send(port->serial->dev,
+                                 0,
+                                 KL5KUSB105A_SIO_SET_DATA,
+                                 USB_TYPE_VENDOR | USB_DIR_OUT |
+                                 USB_RECIP_INTERFACE,
+                                 0, /* value */
+                                 0, /* index */
+                                 settings,
+                                 sizeof(struct klsi_105_port_settings),
+                                 KLSI_TIMEOUT,
+                                 GFP_KERNEL);
+       if (rc)
                dev_err(&port->dev,
                        "Change port settings failed (error = %d)\n", rc);
 
@@ -145,61 +147,37 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,
        return rc;
 }
 
-/* translate a 16-bit status value from the device to linux's TIO bits */
-static unsigned long klsi_105_status2linestate(const __u16 status)
-{
-       unsigned long res = 0;
-
-       res =   ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0)
-             | ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0)
-             ;
-
-       return res;
-}
-
 /*
  * Read line control via vendor command and return result through
- * *line_state_p
+ * the state pointer.
  */
-/* It seems that the status buffer has always only 2 bytes length */
-#define KLSI_STATUSBUF_LEN     2
 static int klsi_105_get_line_state(struct usb_serial_port *port,
-                                  unsigned long *line_state_p)
+                                  unsigned long *state)
 {
+       u16 status;
        int rc;
-       u8 *status_buf;
-       __u16 status;
-
-       status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL);
-       if (!status_buf)
-               return -ENOMEM;
 
-       status_buf[0] = 0xff;
-       status_buf[1] = 0xff;
-       rc = usb_control_msg(port->serial->dev,
-                            usb_rcvctrlpipe(port->serial->dev, 0),
-                            KL5KUSB105A_SIO_POLL,
-                            USB_TYPE_VENDOR | USB_DIR_IN,
-                            0, /* value */
-                            0, /* index */
-                            status_buf, KLSI_STATUSBUF_LEN,
-                            10000
-                            );
-       if (rc != KLSI_STATUSBUF_LEN) {
+       rc = usb_control_msg_recv(port->serial->dev, 0,
+                                 KL5KUSB105A_SIO_POLL,
+                                 USB_TYPE_VENDOR | USB_DIR_IN,
+                                 0, /* value */
+                                 0, /* index */
+                                 &status, sizeof(status),
+                                 10000,
+                                 GFP_KERNEL);
+       if (rc) {
                dev_err(&port->dev, "reading line status failed: %d\n", rc);
-               if (rc >= 0)
-                       rc = -EIO;
-       } else {
-               status = get_unaligned_le16(status_buf);
+               return rc;
+       }
 
-               dev_dbg(&port->dev, "read status %02x %02x\n",
-                       status_buf[0], status_buf[1]);
+       le16_to_cpus(&status);
 
-               *line_state_p = klsi_105_status2linestate(status);
-       }
+       dev_dbg(&port->dev, "read status %04x\n", status);
 
-       kfree(status_buf);
-       return rc;
+       *state = ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0) |
+                ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0);
+
+       return 0;
 }
 
 
@@ -245,7 +223,7 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
        int retval = 0;
        int rc;
        unsigned long line_state;
-       struct klsi_105_port_settings *cfg;
+       struct klsi_105_port_settings cfg;
        unsigned long flags;
 
        /* Do a defined restart:
@@ -255,27 +233,22 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
         * Then read the modem line control and store values in
         * priv->line_state.
         */
-       cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
-       if (!cfg)
-               return -ENOMEM;
 
-       cfg->pktlen   = 5;
-       cfg->baudrate = kl5kusb105a_sio_b9600;
-       cfg->databits = kl5kusb105a_dtb_8;
-       cfg->unknown1 = 0;
-       cfg->unknown2 = 1;
-       klsi_105_chg_port_settings(port, cfg);
+       cfg.pktlen   = 5;
+       cfg.baudrate = kl5kusb105a_sio_b9600;
+       cfg.databits = kl5kusb105a_dtb_8;
+       cfg.unknown1 = 0;
+       cfg.unknown2 = 1;
+       klsi_105_chg_port_settings(port, &cfg);
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->cfg.pktlen   = cfg->pktlen;
-       priv->cfg.baudrate = cfg->baudrate;
-       priv->cfg.databits = cfg->databits;
-       priv->cfg.unknown1 = cfg->unknown1;
-       priv->cfg.unknown2 = cfg->unknown2;
+       priv->cfg.pktlen   = cfg.pktlen;
+       priv->cfg.baudrate = cfg.baudrate;
+       priv->cfg.databits = cfg.databits;
+       priv->cfg.unknown1 = cfg.unknown1;
+       priv->cfg.unknown2 = cfg.unknown2;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       kfree(cfg);
-
        /* READ_ON and urb submission */
        rc = usb_serial_generic_open(tty, port);
        if (rc)
index 090a78c..24101bd 100644 (file)
@@ -208,8 +208,8 @@ void usb_serial_put(struct usb_serial *serial)
  *
  * This is the first place a new tty gets used.  Hence this is where we
  * acquire references to the usb_serial structure and the driver module,
- * where we store a pointer to the port, and where we do an autoresume.
- * All these actions are reversed in serial_cleanup().
+ * where we store a pointer to the port.  All these actions are reversed
+ * in serial_cleanup().
  */
 static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
 {
@@ -225,17 +225,13 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
 
        serial = port->serial;
        if (!try_module_get(serial->type->driver.owner))
-               goto error_module_get;
-
-       retval = usb_autopm_get_interface(serial->interface);
-       if (retval)
-               goto error_get_interface;
+               goto err_put_serial;
 
        init_termios = (driver->termios[idx] == NULL);
 
        retval = tty_standard_install(driver, tty);
        if (retval)
-               goto error_init_termios;
+               goto err_put_module;
 
        mutex_unlock(&serial->disc_mutex);
 
@@ -247,11 +243,9 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
 
        return retval;
 
- error_init_termios:
-       usb_autopm_put_interface(serial->interface);
- error_get_interface:
+err_put_module:
        module_put(serial->type->driver.owner);
- error_module_get:
+err_put_serial:
        usb_serial_put(serial);
        mutex_unlock(&serial->disc_mutex);
        return retval;
@@ -265,10 +259,19 @@ static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty)
        int retval;
 
        mutex_lock(&serial->disc_mutex);
-       if (serial->disconnected)
+       if (serial->disconnected) {
                retval = -ENODEV;
-       else
-               retval = port->serial->type->open(tty, port);
+               goto out_unlock;
+       }
+
+       retval = usb_autopm_get_interface(serial->interface);
+       if (retval)
+               goto out_unlock;
+
+       retval = port->serial->type->open(tty, port);
+       if (retval)
+               usb_autopm_put_interface(serial->interface);
+out_unlock:
        mutex_unlock(&serial->disc_mutex);
 
        if (retval < 0)
@@ -304,6 +307,8 @@ static void serial_port_shutdown(struct tty_port *tport)
 
        if (drv->close)
                drv->close(port);
+
+       usb_autopm_put_interface(port->serial->interface);
 }
 
 static void serial_hangup(struct tty_struct *tty)
@@ -352,8 +357,6 @@ static void serial_cleanup(struct tty_struct *tty)
        serial = port->serial;
        owner = serial->type->driver.owner;
 
-       usb_autopm_put_interface(serial->interface);
-
        usb_serial_put(serial);
        module_put(owner);
 }
@@ -1328,7 +1331,7 @@ static int __init usb_serial_init(void)
        result = bus_register(&usb_serial_bus_type);
        if (result) {
                pr_err("%s - registering bus driver failed\n", __func__);
-               goto exit_bus;
+               goto err_put_driver;
        }
 
        usb_serial_tty_driver->driver_name = "usbserial";
@@ -1346,25 +1349,23 @@ static int __init usb_serial_init(void)
        result = tty_register_driver(usb_serial_tty_driver);
        if (result) {
                pr_err("%s - tty_register_driver failed\n", __func__);
-               goto exit_reg_driver;
+               goto err_unregister_bus;
        }
 
        /* register the generic driver, if we should */
        result = usb_serial_generic_register();
        if (result < 0) {
                pr_err("%s - registering generic driver failed\n", __func__);
-               goto exit_generic;
+               goto err_unregister_driver;
        }
 
        return result;
 
-exit_generic:
+err_unregister_driver:
        tty_unregister_driver(usb_serial_tty_driver);
-
-exit_reg_driver:
+err_unregister_bus:
        bus_unregister(&usb_serial_bus_type);
-
-exit_bus:
+err_put_driver:
        pr_err("%s - returning with error %d\n", __func__, result);
        tty_driver_kref_put(usb_serial_tty_driver);
        return result;
@@ -1509,13 +1510,13 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[]
 
        rc = usb_register(udriver);
        if (rc)
-               goto failed_usb_register;
+               goto err_free_driver;
 
        for (sd = serial_drivers; *sd; ++sd) {
                (*sd)->usb_driver = udriver;
                rc = usb_serial_register(*sd);
                if (rc)
-                       goto failed;
+                       goto err_deregister_drivers;
        }
 
        /* Now set udriver's id_table and look for matches */
@@ -1523,11 +1524,11 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[]
        rc = driver_attach(&udriver->drvwrap.driver);
        return 0;
 
- failed:
+err_deregister_drivers:
        while (sd-- > serial_drivers)
                usb_serial_deregister(*sd);
        usb_deregister(udriver);
-failed_usb_register:
+err_free_driver:
        kfree(udriver);
        return rc;
 }