From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756326AbcANRhV (ORCPT ); Thu, 14 Jan 2016 12:37:21 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:42500 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756016AbcANRhT (ORCPT ); Thu, 14 Jan 2016 12:37:19 -0500 Message-ID: <5697DCCB.30504@collabora.co.uk> Date: Thu, 14 Jan 2016 17:37:15 +0000 From: Martyn Welch User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.8.0 MIME-Version: 1.0 To: Konstantin Shkolnyy , johan@kernel.org CC: "linux-usb@vger.kernel.org" , linux-kernel@vger.kernel.org Subject: Re: [PATCH v3 1/4] USB: serial: cp210x: New register access functions. References: <1451704309-11906-1-git-send-email-konstantin.shkolnyy@gmail.com> In-Reply-To: <1451704309-11906-1-git-send-email-konstantin.shkolnyy@gmail.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 02/01/16 03:11, Konstantin Shkolnyy wrote: > cp210x_get_config and cp210x_set_config are cumbersome to use. This change > introduces new register access functions to replace them. New functions > are not yet called - the switch is done gradually in following changes. > > Signed-off-by: Konstantin Shkolnyy > --- > change in v3: Presented new function addition as a separate patch #1, > to simplify code review. > > drivers/usb/serial/cp210x.c | 166 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 166 insertions(+) > > diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c > index fd67958..324eb7e 100644 > --- a/drivers/usb/serial/cp210x.c > +++ b/drivers/usb/serial/cp210x.c > @@ -323,6 +323,172 @@ struct cp210x_comm_status { > #define PURGE_ALL 0x000f > > /* > + * Reads a variable-sized block of CP210X_ registers, identified by req. > + * Returns data into buf in native USB byte order. > + */ > +static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req, > + void *buf, int bufsize) > +{ > + 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) { > + /* > + * FIXME Some callers don't bother to check for error, > + * at least give them consistent junk until they are fixed > + */ > + memset(buf, 0, bufsize); > + 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 { > + dev_err(&port->dev, "failed get req 0x%x size %d status: %d\n", > + req, bufsize, result); > + if (result >= 0) > + result = -EPROTO; > + > + /* > + * FIXME Some callers don't bother to check for error, > + * at least give them consistent junk until they are fixed > + */ > + memset(buf, 0, bufsize); > + } > + > + kfree(dmabuf); > + > + return result; > +} > + > +/* > + * Reads any 32-bit CP210X_ register identified by req. > + */ > +static int cp210x_read_u32_reg(struct usb_serial_port *port, u8 req, u32 *val) > +{ > + __le32 le32_val; > + int err; > + > + err = cp210x_read_reg_block(port, req, &le32_val, sizeof(le32_val)); > + if (err) { > + /* > + * FIXME Some callers don't bother to check for error, > + * at least give them consistent junk until they are fixed > + */ > + *val = 0; > + return err; > + } > + > + *val = le32_to_cpu(le32_val); > + > + return 0; > +} > + > +/* > + * Reads any 16-bit CP210X_ register identified by req. > + */ > +static int cp210x_read_u16_reg(struct usb_serial_port *port, u8 req, u16 *val) > +{ > + __le16 le16_val; > + int err; > + > + err = cp210x_read_reg_block(port, req, &le16_val, sizeof(le16_val)); > + if (err) > + return err; > + > + *val = le16_to_cpu(le16_val); > + > + return 0; > +} > + > +/* > + * Reads any 8-bit CP210X_ register identified by req. > + */ > +static int cp210x_read_u8_reg(struct usb_serial_port *port, u8 req, u8 *val) > +{ > + return cp210x_read_reg_block(port, req, val, sizeof(*val)); > +} > + > +/* > + * Writes any 16-bit CP210X_ register (req) whose value is passed > + * entirely in the wValue field of the USB request. > + */ > +static int cp210x_write_u16_reg(struct usb_serial_port *port, u8 req, u16 val) Think this needs a different name to draw more attention to the fact that it writes in a different way from cp210x_write_u32_reg and how the cp210x_read_uXX_reg read. Martyn > +{ > + struct usb_serial *serial = port->serial; > + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); > + int result; > + > + result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), > + req, REQTYPE_HOST_TO_INTERFACE, val, > + port_priv->bInterfaceNumber, NULL, 0, > + USB_CTRL_SET_TIMEOUT); > + if (result < 0) { > + dev_err(&port->dev, "failed set request 0x%x status: %d\n", > + req, result); > + } > + > + return result; > +} > + > +/* > + * Writes a variable-sized block of CP210X_ registers, identified by req. > + * Data in buf must be in native USB byte order. > + */ > +static int cp210x_write_reg_block(struct usb_serial_port *port, u8 req, > + void *buf, int bufsize) > +{ > + 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; > + > + memcpy(dmabuf, buf, bufsize); > + > + 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 == bufsize) { > + result = 0; > + } else { > + dev_err(&port->dev, "failed set req 0x%x size %d status: %d\n", > + req, bufsize, result); > + if (result >= 0) > + result = -EPROTO; > + } > + > + return result; > +} > + > +/* > + * Writes any 32-bit CP210X_ register identified by req. > + */ > +static int cp210x_write_u32_reg(struct usb_serial_port *port, u8 req, u32 val) > +{ > + __le32 le32_val; > + > + le32_val = cpu_to_le32(val); > + > + return cp210x_write_reg_block(port, req, &le32_val, sizeof(le32_val)); > +} > + > +/* > * cp210x_get_config > * Reads from the CP210x configuration registers > * 'size' is specified in bytes. >