Commit f5cfbecb authored by Himadri Pandya's avatar Himadri Pandya Committed by Johan Hovold
Browse files

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: default avatarHimadri Pandya <himadrispandya@gmail.com>
Link: https://lore.kernel.org/r/20211001065720.21330-3-himadrispandya@gmail.com


[ johan: style changes ]
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent 74f26645
Loading
Loading
Loading
Loading
+31 −78
Original line number Diff line number Diff line
@@ -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)