USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send()
authorHimadri Pandya <himadrispandya@gmail.com>
Fri, 1 Oct 2021 06:57:20 +0000 (08:57 +0200)
committerJohan Hovold <johan@kernel.org>
Wed, 27 Oct 2021 12:57:41 +0000 (14:57 +0200)
The new wrapper functions for usb_control_msg() can accept data from
stack and treat short reads as errors. Hence use the wrappers functions.
Please note that because of this change, cp210x_read_reg_block() will no
longer log the length of short reads.

Signed-off-by: Himadri Pandya <himadrispandya@gmail.com>
Link: https://lore.kernel.org/r/20211001065720.21330-3-himadrispandya@gmail.com
[ johan: style changes ]
Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/cp210x.c

index 66a6ac5..920b976 100644 (file)
@@ -629,30 +629,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;
 }
 
 /*
@@ -670,31 +660,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;
 }
 
 /*
@@ -728,21 +706,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;
@@ -771,21 +741,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);
@@ -950,29 +911,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)