diff mbox series

[v2,2/6] USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send()

Message ID 20210801203122.3515-3-himadrispandya@gmail.com
State New
Headers show
Series USB: serial: use wrappers for usb_control_msg() | expand

Commit Message

Himadri Pandya Aug. 1, 2021, 8:31 p.m. UTC
The new wrapper functions for usb_control_msg() can accept data from
stack with robust error checks. Hence use the wrappers with stack
variables for usb transfer buffers to save kernel memory.

Signed-off-by: Himadri Pandya <himadrispandya@gmail.com>
---
Changes in v2:
 - Drop unrelated style fixes
---
 drivers/usb/serial/cp210x.c | 107 ++++++++++--------------------------
 1 file changed, 30 insertions(+), 77 deletions(-)

Comments

Johan Hovold Sept. 21, 2021, 11:34 a.m. UTC | #1
On Mon, Aug 02, 2021 at 02:01:18AM +0530, Himadri Pandya wrote:
> The new wrapper functions for usb_control_msg() can accept data from

> stack with robust error checks.


Please rephrase the "robust error checks" along the lines of "treats
short reads as an error".

> Hence use the wrappers with stack

> variables for usb transfer buffers to save kernel memory.


Again, you're not saving memory here, just moving the allocation.

> Signed-off-by: Himadri Pandya <himadrispandya@gmail.com>

> ---

> Changes in v2:

>  - Drop unrelated style fixes

> ---

>  drivers/usb/serial/cp210x.c | 107 ++++++++++--------------------------

>  1 file changed, 30 insertions(+), 77 deletions(-)

> 

> diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c

> index 3c80bfbf3bec..b73581fc1768 100644

> --- a/drivers/usb/serial/cp210x.c

> +++ b/drivers/usb/serial/cp210x.c

> @@ -628,29 +628,18 @@ 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_SET_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);


This will also no longer log the length of short reads. Please at least
mention it in the commit message.

> -		if (result >= 0)

> -			result = -EIO;

>  	}

>  

> -	kfree(dmabuf);

> -

>  	return result;

>  }


Johan
diff mbox series

Patch

diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 3c80bfbf3bec..b73581fc1768 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -628,29 +628,18 @@  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_SET_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;
 	}
 
-	kfree(dmabuf);
-
 	return result;
 }
 
@@ -669,30 +658,17 @@  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;
 	}
-
-	kfree(dmabuf);
-
 	return result;
 }
 
@@ -727,21 +703,14 @@  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_send(serial->dev, 0, req,
+				      REQTYPE_HOST_TO_INTERFACE, 0,
+				      port_priv->bInterfaceNumber, buf, bufsize,
+				      USB_CTRL_SET_TIMEOUT, GFP_KERNEL);
 
-	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) {
+	if (result) {
 		dev_err(&port->dev, "failed set req 0x%x size %d status: %d\n",
 				req, bufsize, result);
 		return result;
@@ -770,21 +739,14 @@  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);
+	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);
 
-	kfree(dmabuf);
-
-	if (result < 0) {
+	if (result) {
 		dev_err(&serial->interface->dev,
 			"failed to set vendor val 0x%04x size %d: %d\n", val,
 			bufsize, result);
@@ -949,27 +911,18 @@  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 == 0)
+		*count = le32_to_cpu(sts.ulAmountInOutQueue);
+	else
 		dev_err(&port->dev, "failed to get comm status: %d\n", result);
-		if (result >= 0)
-			result = -EIO;
-	}
-
-	kfree(sts);
 
 	return result;
 }