From f5cfbecb0a162319464c9408420282d22ed69721 Mon Sep 17 00:00:00 2001 From: Himadri Pandya Date: Fri, 1 Oct 2021 08:57:20 +0200 Subject: [PATCH] USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send() 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 Link: https://lore.kernel.org/r/20211001065720.21330-3-himadrispandya@gmail.com [ johan: style changes ] Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 109 +++++++++++++------------------------------- 1 file changed, 31 insertions(+), 78 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 66a6ac50..920b976 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -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) -- 2.7.4