All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] USB: serial: use wrappers for usb_control_msg()
@ 2021-10-01  6:57 Himadri Pandya
  2021-10-01  6:57 ` [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send() Himadri Pandya
  2021-10-01  6:57 ` [PATCH v3 2/2] USB: serial: cp210x: " Himadri Pandya
  0 siblings, 2 replies; 9+ messages in thread
From: Himadri Pandya @ 2021-10-01  6:57 UTC (permalink / raw)
  To: johan, gregkh, linux-usb, linux-kernel; +Cc: Himadri Pandya

There are many usages of usb_control_msg() that can instead use the new
wrapper functions usb_contro_msg_send() & usb_control_msg_recv() for
better error checks on short reads. The wrappers also handle the
allocation of dma buffers and callers don't need to manage them
explicitly.

This is a follow up on v2 with 6 patches. 4 of them are already applied
so v3 only includes the two remaining patches. The patches are
compile-tested only.

Changes in v3:
 - Rephrase commit messages
 - Add notes on omitting the logs for short read sizes

Changes in v2:
 - Drop unnecessary use of wrappers
 - Drop unrelated style changes

Himadri Pandya (2):
  USB: serial: ch314: use usb_control_msg_recv() and
    usb_control_msg_send()
  USB: serial: cp210x: use usb_control_msg_recv() and
    usb_control_msg_send()

 drivers/usb/serial/ch341.c  |  90 ++++++++----------------------
 drivers/usb/serial/cp210x.c | 106 ++++++++++--------------------------
 2 files changed, 54 insertions(+), 142 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-01  6:57 [PATCH v3 0/2] USB: serial: use wrappers for usb_control_msg() Himadri Pandya
@ 2021-10-01  6:57 ` Himadri Pandya
  2021-10-27 13:04   ` Johan Hovold
  2021-10-01  6:57 ` [PATCH v3 2/2] USB: serial: cp210x: " Himadri Pandya
  1 sibling, 1 reply; 9+ messages in thread
From: Himadri Pandya @ 2021-10-01  6:57 UTC (permalink / raw)
  To: johan, gregkh, linux-usb, linux-kernel; +Cc: Himadri Pandya

usb_control_msg_send/recv are new wrapper functions for usb_control_msg()
that have proper error checks for short reads. These functions can also
accept data buffer on stack. Hence use these functions to simplify error
handling for short reads. Short reads will now get reported as
-EREMOTEIO with no indication of how short the transfer was.

Signed-off-by: Himadri Pandya <himadrispandya@gmail.com>
---
Changes in v3:
 - Rephrase the commit message
 - Include a note on not reporting size of the short reads in the commit
 - Drop unnecessary changes in ch341_control_out()
 - Drop a non-relevant style change
 - Remove some more "out" labels
 - Remove unnecessary return statement from a void function

Changes in v2:
 - Fix callers of ch341_control_out() and ch341_control_in()
 - Remove label "out"
 - Remove an unnecessary assignment statement
---
 drivers/usb/serial/ch341.c | 90 ++++++++++----------------------------
 1 file changed, 24 insertions(+), 66 deletions(-)

diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 2db917eab799..8aecc1f0dee4 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -131,23 +131,13 @@ 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;
-		}
-
-		dev_err(&dev->dev, "failed to receive control message: %d\n",
-			r);
-		return r;
-	}
+	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 0;
+	return r;
 }
 
 #define CH341_CLKRATE		48000000
@@ -287,23 +277,18 @@ 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;
 }
 
@@ -312,30 +297,25 @@ 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;
+	if (r)
+		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);
 
-out:	kfree(buffer);
 	return r;
 }
 
@@ -345,39 +325,23 @@ 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);
@@ -647,23 +611,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]);
@@ -681,11 +641,9 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
 	reg_contents = get_unaligned_le16(break_reg);
 	r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
 			ch341_break_reg, reg_contents);
-	if (r < 0)
+	if (r)
 		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,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/2] USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-01  6:57 [PATCH v3 0/2] USB: serial: use wrappers for usb_control_msg() Himadri Pandya
  2021-10-01  6:57 ` [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send() Himadri Pandya
@ 2021-10-01  6:57 ` Himadri Pandya
  2021-10-27 13:17   ` Johan Hovold
  1 sibling, 1 reply; 9+ messages in thread
From: Himadri Pandya @ 2021-10-01  6:57 UTC (permalink / raw)
  To: johan, gregkh, linux-usb, linux-kernel; +Cc: Himadri Pandya

The new wrapper functions for usb_control_msg() can accept data from
stack and treat short reads as error. 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>
---
Changes in v3:
 - Rephrase the commit message
 - Explicitly mention that short reads don't log length now

Changes in v2:
 - Drop unrelated style fixes
---
 drivers/usb/serial/cp210x.c | 106 ++++++++++--------------------------
 1 file changed, 30 insertions(+), 76 deletions(-)

diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 189279869a8b..3c3ca46b0b82 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -631,29 +631,19 @@ 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;
 	}
 
-	kfree(dmabuf);
-
 	return result;
 }
 
@@ -672,30 +662,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;
 }
 
@@ -730,21 +707,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(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			req, REQTYPE_HOST_TO_INTERFACE, 0,
-			port_priv->bInterfaceNumber, dmabuf, bufsize,
-			USB_CTRL_SET_TIMEOUT);
-
-	kfree(dmabuf);
+	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 < 0) {
+	if (result) {
 		dev_err(&port->dev, "failed set req 0x%x size %d status: %d\n",
 				req, bufsize, result);
 		return result;
@@ -773,21 +743,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_send(serial->dev, 0, CP210X_VENDOR_SPECIFIC,
+				      type, val, cp210x_interface_num(serial),
+				      buf, bufsize, USB_CTRL_SET_TIMEOUT,
+				      GFP_KERNEL);
 
-	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) {
+	if (result) {
 		dev_err(&serial->interface->dev,
 			"failed to set vendor val 0x%04x size %d: %d\n", val,
 			bufsize, result);
@@ -952,27 +915,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;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-01  6:57 ` [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send() Himadri Pandya
@ 2021-10-27 13:04   ` Johan Hovold
  2021-10-27 13:28     ` Himadri Pandya
  0 siblings, 1 reply; 9+ messages in thread
From: Johan Hovold @ 2021-10-27 13:04 UTC (permalink / raw)
  To: Himadri Pandya; +Cc: gregkh, linux-usb, linux-kernel

On Fri, Oct 01, 2021 at 08:57:19AM +0200, Himadri Pandya wrote:
> usb_control_msg_send/recv are new wrapper functions for usb_control_msg()
> that have proper error checks for short reads. These functions can also
> accept data buffer on stack. Hence use these functions to simplify error
> handling for short reads. Short reads will now get reported as
> -EREMOTEIO with no indication of how short the transfer was.

You're no longer using usb_control_msg_send() so the commit message
including Subject needs to be updated.

> Signed-off-by: Himadri Pandya <himadrispandya@gmail.com>
> ---
> Changes in v3:
>  - Rephrase the commit message
>  - Include a note on not reporting size of the short reads in the commit
>  - Drop unnecessary changes in ch341_control_out()
>  - Drop a non-relevant style change
>  - Remove some more "out" labels
>  - Remove unnecessary return statement from a void function
> 
> Changes in v2:
>  - Fix callers of ch341_control_out() and ch341_control_in()
>  - Remove label "out"
>  - Remove an unnecessary assignment statement
> ---
>  drivers/usb/serial/ch341.c | 90 ++++++++++----------------------------
>  1 file changed, 24 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
> index 2db917eab799..8aecc1f0dee4 100644
> --- a/drivers/usb/serial/ch341.c
> +++ b/drivers/usb/serial/ch341.c
> @@ -131,23 +131,13 @@ 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;
> -		}
> -
> -		dev_err(&dev->dev, "failed to receive control message: %d\n",
> -			r);
> -		return r;
> -	}
> +	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);

Line is now over 80 chars for no good reason.

> +	if (r)
> +		dev_err(&dev->dev, "failed to receive control message: %d\n", r);

Here too.

>  
> -	return 0;
> +	return r;

I'd prefer returning the errno in the error path above and keep an
explicit zero here.

>  }
>  
>  #define CH341_CLKRATE		48000000
> @@ -287,23 +277,18 @@ 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;

This should now be

	return 0;

>  }
>  
> @@ -312,30 +297,25 @@ 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;
> +	if (r)
> +		return r;

Now an unrelated change.

>  
>  	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);
>  
> -out:	kfree(buffer);
>  	return r;

This looks a bit inconsistent now so I'll make this an explicit return
0 too.

>  }
>  
> @@ -345,39 +325,23 @@ 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);

Unnecessarily long line > 80 chars.

>  	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;

Oops, you just broke the driver. :(

This request is used to detect quirky devices and a return value of
-EPIPE here should not abort probe by returning an error to the caller
of this function.

> -		goto out;
> -	}
> -
> -	if (r != size) {
> -		if (r >= 0)
> -			r = -EIO;
> +	} else if (r)

And you still need brackets on the else branch.

>  		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);
> @@ -647,23 +611,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]);
> @@ -681,11 +641,9 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
>  	reg_contents = get_unaligned_le16(break_reg);
>  	r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
>  			ch341_break_reg, reg_contents);
> -	if (r < 0)
> +	if (r)

Now also an unrelated change.

>  		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,

I've fixed up the above so we don't have to spend any more time on this.

The result is here

	https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git/commit/?h=usb-next&id=74f266455062c158f343bc3aa35ef84b3eb7adf1

Johan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/2] USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-01  6:57 ` [PATCH v3 2/2] USB: serial: cp210x: " Himadri Pandya
@ 2021-10-27 13:17   ` Johan Hovold
  2021-10-27 13:34     ` Himadri Pandya
  0 siblings, 1 reply; 9+ messages in thread
From: Johan Hovold @ 2021-10-27 13:17 UTC (permalink / raw)
  To: Himadri Pandya; +Cc: gregkh, linux-usb, linux-kernel

On Fri, Oct 01, 2021 at 08:57:20AM +0200, Himadri Pandya wrote:
> The new wrapper functions for usb_control_msg() can accept data from
> stack and treat short reads as error. 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>
> ---
> Changes in v3:
>  - Rephrase the commit message
>  - Explicitly mention that short reads don't log length now
> 
> Changes in v2:
>  - Drop unrelated style fixes

This looks good now, but I did do some minor style changes described
below.

> ---
>  drivers/usb/serial/cp210x.c | 106 ++++++++++--------------------------
>  1 file changed, 30 insertions(+), 76 deletions(-)
> 
> diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
> index 189279869a8b..3c3ca46b0b82 100644
> --- a/drivers/usb/serial/cp210x.c
> +++ b/drivers/usb/serial/cp210x.c
> @@ -631,29 +631,19 @@ 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);

The indentation style of this driver is a bit inconsistent but there's
no need to change to the open-parenthesis alignment style when you can
avoid it (it's mostly just "checkpacth.pl --subjective" that insists on
it).

Indenting continuation lines two tabs is just fine and avoids excessive
indentation and having to realign arguments when symbol names change.

> +	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;

I changed this to explicit zero and return an error above instead.

> @@ -952,27 +915,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);

The above is now also better handled with an explicit error check and
early return and the doing the *count assignment in the success path.

>  
>  	return result;
>  }

Now applied with the above changes. The result is here:

	https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git/commit/?h=usb-next&id=f5cfbecb0a162319464c9408420282d22ed69721

Johan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-27 13:04   ` Johan Hovold
@ 2021-10-27 13:28     ` Himadri Pandya
  2021-10-27 13:37       ` Johan Hovold
  0 siblings, 1 reply; 9+ messages in thread
From: Himadri Pandya @ 2021-10-27 13:28 UTC (permalink / raw)
  To: Johan Hovold; +Cc: Greg KH, USB list, LKML

On Wed, Oct 27, 2021 at 3:04 PM Johan Hovold <johan@kernel.org> wrote:
>
> On Fri, Oct 01, 2021 at 08:57:19AM +0200, Himadri Pandya wrote:
> > usb_control_msg_send/recv are new wrapper functions for usb_control_msg()
> > that have proper error checks for short reads. These functions can also
> > accept data buffer on stack. Hence use these functions to simplify error
> > handling for short reads. Short reads will now get reported as
> > -EREMOTEIO with no indication of how short the transfer was.
>
> You're no longer using usb_control_msg_send() so the commit message
> including Subject needs to be updated.
>
> > Signed-off-by: Himadri Pandya <himadrispandya@gmail.com>
> > ---
> > Changes in v3:
> >  - Rephrase the commit message
> >  - Include a note on not reporting size of the short reads in the commit
> >  - Drop unnecessary changes in ch341_control_out()
> >  - Drop a non-relevant style change
> >  - Remove some more "out" labels
> >  - Remove unnecessary return statement from a void function
> >
> > Changes in v2:
> >  - Fix callers of ch341_control_out() and ch341_control_in()
> >  - Remove label "out"
> >  - Remove an unnecessary assignment statement
> > ---
> >  drivers/usb/serial/ch341.c | 90 ++++++++++----------------------------
> >  1 file changed, 24 insertions(+), 66 deletions(-)
> >
> > diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
> > index 2db917eab799..8aecc1f0dee4 100644
> > --- a/drivers/usb/serial/ch341.c
> > +++ b/drivers/usb/serial/ch341.c
> > @@ -131,23 +131,13 @@ 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;
> > -             }
> > -
> > -             dev_err(&dev->dev, "failed to receive control message: %d\n",
> > -                     r);
> > -             return r;
> > -     }
> > +     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);
>
> Line is now over 80 chars for no good reason.

Sorry, I changed machines and the checkpatch must not be configured
properly in the new set-up.

>
> > +     if (r)
> > +             dev_err(&dev->dev, "failed to receive control message: %d\n", r);
>
> Here too.
>
> >
> > -     return 0;
> > +     return r;
>
> I'd prefer returning the errno in the error path above and keep an
> explicit zero here.
>

Okay.

> >  }
> >
> >  #define CH341_CLKRATE                48000000
> > @@ -287,23 +277,18 @@ 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;
>
> This should now be
>
>         return 0;
>

Yes. The function was returning the negative error value before the
change. But now it doesn't need to as we are already taking care of it
in the wrapper.

> >  }
> >
> > @@ -312,30 +297,25 @@ 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;
> > +     if (r)
> > +             return r;
>
> Now an unrelated change.

I think it is a related change because we are removing the out label.

>
> >
> >       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);
> >
> > -out: kfree(buffer);
> >       return r;
>
> This looks a bit inconsistent now so I'll make this an explicit return
> 0 too.

Okay.

>
> >  }
> >
> > @@ -345,39 +325,23 @@ 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);
>
> Unnecessarily long line > 80 chars.
>
> >       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;
>
> Oops, you just broke the driver. :(
>
> This request is used to detect quirky devices and a return value of
> -EPIPE here should not abort probe by returning an error to the caller
> of this function.

Understood. Thanks for catching it.

>
> > -             goto out;
> > -     }
> > -
> > -     if (r != size) {
> > -             if (r >= 0)
> > -                     r = -EIO;
> > +     } else if (r)
>
> And you still need brackets on the else branch.

Yes. Okay.

>
> >               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);
> > @@ -647,23 +611,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]);
> > @@ -681,11 +641,9 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
> >       reg_contents = get_unaligned_le16(break_reg);
> >       r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
> >                       ch341_break_reg, reg_contents);
> > -     if (r < 0)
> > +     if (r)
>
> Now also an unrelated change.
>

Maybe I misunderstood your comments on v2. I thought you asked to get
rid of the out labels in callers.

> >               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,
>
> I've fixed up the above so we don't have to spend any more time on this.
>

Thank you.

> The result is here
>
>         https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git/commit/?h=usb-next&id=74f266455062c158f343bc3aa35ef84b3eb7adf1
>
> Johan

Looks good. Thanks for taking the patch.

Regards,
Himadri

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/2] USB: serial: cp210x: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-27 13:17   ` Johan Hovold
@ 2021-10-27 13:34     ` Himadri Pandya
  0 siblings, 0 replies; 9+ messages in thread
From: Himadri Pandya @ 2021-10-27 13:34 UTC (permalink / raw)
  To: Johan Hovold; +Cc: Greg KH, USB list, LKML

On Wed, Oct 27, 2021 at 3:18 PM Johan Hovold <johan@kernel.org> wrote:
>
> On Fri, Oct 01, 2021 at 08:57:20AM +0200, Himadri Pandya wrote:
> > The new wrapper functions for usb_control_msg() can accept data from
> > stack and treat short reads as error. 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>
> > ---
> > Changes in v3:
> >  - Rephrase the commit message
> >  - Explicitly mention that short reads don't log length now
> >
> > Changes in v2:
> >  - Drop unrelated style fixes
>
> This looks good now, but I did do some minor style changes described
> below.
>
> > ---
> >  drivers/usb/serial/cp210x.c | 106 ++++++++++--------------------------
> >  1 file changed, 30 insertions(+), 76 deletions(-)
> >
> > diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
> > index 189279869a8b..3c3ca46b0b82 100644
> > --- a/drivers/usb/serial/cp210x.c
> > +++ b/drivers/usb/serial/cp210x.c
> > @@ -631,29 +631,19 @@ 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);
>
> The indentation style of this driver is a bit inconsistent but there's
> no need to change to the open-parenthesis alignment style when you can
> avoid it (it's mostly just "checkpacth.pl --subjective" that insists on
> it).
>
> Indenting continuation lines two tabs is just fine and avoids excessive
> indentation and having to realign arguments when symbol names change.
>

Thanks for clearing this up. I followed the checkpatch suggestion in
v2 and then came back to the original style of the driver in v3.
Feeling the extra spaces to match the indentation wasn't really fun.

> > +     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;
>
> I changed this to explicit zero and return an error above instead.

Okay.

>
> > @@ -952,27 +915,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);
>
> The above is now also better handled with an explicit error check and
> early return and the doing the *count assignment in the success path.
>

Yes.

> >
> >       return result;
> >  }
>
> Now applied with the above changes. The result is here:
>
>         https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git/commit/?h=usb-next&id=f5cfbecb0a162319464c9408420282d22ed69721
>
> Johan

Thank you.

Regards,
Himadri

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-27 13:28     ` Himadri Pandya
@ 2021-10-27 13:37       ` Johan Hovold
  2021-10-27 13:47         ` Himadri Pandya
  0 siblings, 1 reply; 9+ messages in thread
From: Johan Hovold @ 2021-10-27 13:37 UTC (permalink / raw)
  To: Himadri Pandya; +Cc: Greg KH, USB list, LKML

On Wed, Oct 27, 2021 at 03:28:42PM +0200, Himadri Pandya wrote:
> On Wed, Oct 27, 2021 at 3:04 PM Johan Hovold <johan@kernel.org> wrote:
> > On Fri, Oct 01, 2021 at 08:57:19AM +0200, Himadri Pandya wrote:

> > > @@ -287,23 +277,18 @@ 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;
> >
> > This should now be
> >
> >         return 0;
> >
> 
> Yes. The function was returning the negative error value before the
> change. But now it doesn't need to as we are already taking care of it
> in the wrapper.

It has more to do with the fact that we now return early on errors so r
will always be zero here. It's better to be explicit about that.
 
> > >  }
> > >
> > > @@ -312,30 +297,25 @@ 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;
> > > +     if (r)
> > > +             return r;
> >
> > Now an unrelated change.
> 
> I think it is a related change because we are removing the out label.

Sorry, I meant that the (r < 0) change was unrelated since you're no
longer touching ch341_control_out(). The return is indeed still needed.
 
> > > @@ -647,23 +611,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]);
> > > @@ -681,11 +641,9 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
> > >       reg_contents = get_unaligned_le16(break_reg);
> > >       r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
> > >                       ch341_break_reg, reg_contents);
> > > -     if (r < 0)
> > > +     if (r)
> >
> > Now also an unrelated change.
> >
> 
> Maybe I misunderstood your comments on v2. I thought you asked to get
> rid of the out labels in callers.

Yes, but as above I'm referring to the (r < 0) change for
ch341_control_out() which is now unrelated to the rest of the patch.

Johan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send()
  2021-10-27 13:37       ` Johan Hovold
@ 2021-10-27 13:47         ` Himadri Pandya
  0 siblings, 0 replies; 9+ messages in thread
From: Himadri Pandya @ 2021-10-27 13:47 UTC (permalink / raw)
  To: Johan Hovold; +Cc: Greg KH, USB list, LKML

On Wed, Oct 27, 2021 at 3:38 PM Johan Hovold <johan@kernel.org> wrote:
>
> On Wed, Oct 27, 2021 at 03:28:42PM +0200, Himadri Pandya wrote:
> > On Wed, Oct 27, 2021 at 3:04 PM Johan Hovold <johan@kernel.org> wrote:
> > > On Fri, Oct 01, 2021 at 08:57:19AM +0200, Himadri Pandya wrote:
>
> > > > @@ -287,23 +277,18 @@ 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;
> > >
> > > This should now be
> > >
> > >         return 0;
> > >
> >
> > Yes. The function was returning the negative error value before the
> > change. But now it doesn't need to as we are already taking care of it
> > in the wrapper.
>
> It has more to do with the fact that we now return early on errors so r
> will always be zero here. It's better to be explicit about that.
>

Okay. Right.

> > > >  }
> > > >
> > > > @@ -312,30 +297,25 @@ 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;
> > > > +     if (r)
> > > > +             return r;
> > >
> > > Now an unrelated change.
> >
> > I think it is a related change because we are removing the out label.
>
> Sorry, I meant that the (r < 0) change was unrelated since you're no
> longer touching ch341_control_out(). The return is indeed still needed.
>

Oh, okay. My bad.

> > > > @@ -647,23 +611,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]);
> > > > @@ -681,11 +641,9 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
> > > >       reg_contents = get_unaligned_le16(break_reg);
> > > >       r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
> > > >                       ch341_break_reg, reg_contents);
> > > > -     if (r < 0)
> > > > +     if (r)
> > >
> > > Now also an unrelated change.
> > >
> >
> > Maybe I misunderstood your comments on v2. I thought you asked to get
> > rid of the out labels in callers.
>
> Yes, but as above I'm referring to the (r < 0) change for
> ch341_control_out() which is now unrelated to the rest of the patch.
>
> Johan

Yes, got it.

Thanks,
Himadri

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-10-27 13:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-01  6:57 [PATCH v3 0/2] USB: serial: use wrappers for usb_control_msg() Himadri Pandya
2021-10-01  6:57 ` [PATCH v3 1/2] USB: serial: ch314: use usb_control_msg_recv() and usb_control_msg_send() Himadri Pandya
2021-10-27 13:04   ` Johan Hovold
2021-10-27 13:28     ` Himadri Pandya
2021-10-27 13:37       ` Johan Hovold
2021-10-27 13:47         ` Himadri Pandya
2021-10-01  6:57 ` [PATCH v3 2/2] USB: serial: cp210x: " Himadri Pandya
2021-10-27 13:17   ` Johan Hovold
2021-10-27 13:34     ` Himadri Pandya

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.