From: Johan Hovold <johan@kernel.org>
To: "Jaromír Škorpil" <Jerry@jrr.cz>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Johan Hovold <johan@kernel.org>,
linux-usb@vger.kernel.org
Subject: Re: [PATCH v4] usbserial: cp210x - icount support for parity error checking
Date: Mon, 6 Jul 2020 11:08:09 +0200 [thread overview]
Message-ID: <20200706090809.GH3453@localhost> (raw)
In-Reply-To: <838f09f9-4063-1c2c-8b4d-c18dee6c18de@jrr.cz>
On Mon, Jun 22, 2020 at 05:13:41PM +0200, Jaromír Škorpil wrote:
> The current version of cp210x driver doesn't provide any way to detect
> a parity error in received data from userspace. Some serial protocols like
> STM32 bootloader protect data only by parity so application needs to
> know whether parity error happened to repeat peripheral data reading.
>
> Added support for icount (ioctl TIOCGICOUNT) which sends GET_COMM_STATUS
> command to CP210X and according received flags increments fields for
> parity error, frame error, break and overrun. An application can detect
> an error condition after reading data from ttyUSB and reacts adequately.
> There is no impact for applications which don't call ioctl TIOCGICOUNT.
>
> The flag "hardware overrun" is not examined because CP2102 sets this bit
> for the first received byte after openning of port which was previously
> closed with some unreaded data in buffer. This is confusing and checking
> "queue overrun" flag seems be enough.
>
> Signed-off-by: Jaromír Škorpil <Jerry@jrr.cz>
> ---
> v2: Simplified counting - only queue overrun checked
> v3: Changed description + UTF8 name
> v4: Corrected endian
So let's go with this and then I can add support for in-band reporting
on top.
I was gonna apply it and the missing locking, but noticed that the patch
is white-space damaged. At least some leading tabs have been converted.
Try sending the patch yourself (e.g. using git-send-email) and make sure
you can apply it using git-am.
> cp210x.c | 43 ++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 38 insertions(+), 5 deletions(-)
>
> diff -up linux-5.8-rc1/drivers/usb/serial/cp210x.c j/drivers/usb/serial/cp210x.c
> --- linux-5.8-rc1/drivers/usb/serial/cp210x.c
> +++ j/drivers/usb/serial/cp210x.c
> @@ -43,6 +43,8 @@ static int cp210x_tiocmget(struct tty_st
> static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int);
> static int cp210x_tiocmset_port(struct usb_serial_port *port,
> unsigned int, unsigned int);
> +static int cp210x_get_icount(struct tty_struct *tty,
> + struct serial_icounter_struct *icount);
> static void cp210x_break_ctl(struct tty_struct *, int);
> static int cp210x_attach(struct usb_serial *);
> static void cp210x_disconnect(struct usb_serial *);
> @@ -274,6 +276,7 @@ static struct usb_serial_driver cp210x_d
> .tx_empty = cp210x_tx_empty,
> .tiocmget = cp210x_tiocmget,
> .tiocmset = cp210x_tiocmset,
> + .get_icount = cp210x_get_icount,
> .attach = cp210x_attach,
> .disconnect = cp210x_disconnect,
> .release = cp210x_release,
> @@ -393,6 +396,13 @@ struct cp210x_comm_status {
> u8 bReserved;
> } __packed;
>
> +/* cp210x_comm_status::ulErrors */
> +#define CP210X_SERIAL_ERR_BREAK BIT(0)
> +#define CP210X_SERIAL_ERR_FRAME BIT(1)
> +#define CP210X_SERIAL_ERR_HW_OVERRUN BIT(2)
> +#define CP210X_SERIAL_ERR_QUEUE_OVERRUN BIT(3)
> +#define CP210X_SERIAL_ERR_PARITY BIT(4)
Can you drop the SERIAL_ infix here?
> +
> /*
> * CP210X_PURGE - 16 bits passed in wValue of USB request.
> * SiLabs app note AN571 gives a strange description of the 4 bits:
> @@ -836,10 +846,10 @@ static void cp210x_close(struct usb_seri
> }
>
> /*
> - * Read how many bytes are waiting in the TX queue.
> + * Read how many bytes are waiting in the TX queue and update error counters.
> */
> -static int cp210x_get_tx_queue_byte_count(struct usb_serial_port *port,
> - u32 *count)
> +static int cp210x_get_comm_status(struct usb_serial_port *port,
> + u32 *tx_count)
> {
> struct usb_serial *serial = port->serial;
> struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
> @@ -855,7 +865,17 @@ static int cp210x_get_tx_queue_byte_coun
> 0, port_priv->bInterfaceNumber, sts, sizeof(*sts),
> USB_CTRL_GET_TIMEOUT);
> if (result == sizeof(*sts)) {
> - *count = le32_to_cpu(sts->ulAmountInOutQueue);
> + u32 flags = le32_to_cpu(sts->ulErrors);
Here should be a newline.
> + if (flags & CP210X_SERIAL_ERR_BREAK)
> + port->icount.brk++;
> + if (flags & CP210X_SERIAL_ERR_FRAME)
> + port->icount.frame++;
> + if (flags & CP210X_SERIAL_ERR_QUEUE_OVERRUN)
> + port->icount.overrun++;
> + if (flags & CP210X_SERIAL_ERR_PARITY)
> + port->icount.parity++;
And these icount increments should be done under the port->lock as
TIOCGICOUNT can be called in parallel.
> + if (tx_count)
> + *tx_count = le32_to_cpu(sts->ulAmountInOutQueue);
> result = 0;
> } else {
> dev_err(&port->dev, "failed to get comm status: %d\n", result);
> @@ -873,13 +893,26 @@ static bool cp210x_tx_empty(struct usb_s
> int err;
> u32 count;
>
> - err = cp210x_get_tx_queue_byte_count(port, &count);
> + err = cp210x_get_comm_status(port, &count);
> if (err)
> return true;
>
> return !count;
> }
>
> +static int cp210x_get_icount(struct tty_struct *tty,
> + struct serial_icounter_struct *icount)
> +{
> + struct usb_serial_port *port = tty->driver_data;
> + int result;
> +
> + result = cp210x_get_comm_status(port, NULL);
> + if (result)
> + return result;
> +
> + return usb_serial_generic_get_icount(tty, icount);
> +}
> +
> /*
> * cp210x_get_termios
> * Reads the baud rate, data bits, parity, stop bits and flow control mode
>
>
>
Johan
next prev parent reply other threads:[~2020-07-06 9:08 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-20 19:58 [PATCH 1/1] usbserial: cp210x - icount support for parity error checking Jerry
2020-06-21 8:54 ` [PATCH v2] " Jerry
2020-06-21 8:58 ` [PATCH 1/1] " Greg Kroah-Hartman
2020-06-21 9:45 ` Jerry
2020-06-21 9:55 ` Greg Kroah-Hartman
2020-06-21 10:34 ` Jerry
2020-06-21 13:58 ` Greg Kroah-Hartman
2020-06-21 20:21 ` [PATCH v3] " Jaromír Škorpil
2020-06-22 5:31 ` Greg Kroah-Hartman
2020-06-22 15:13 ` [PATCH v4] " Jaromír Škorpil
2020-06-25 4:31 ` Jerry
2020-06-25 6:53 ` Johan Hovold
2020-07-01 15:42 ` Johan Hovold
2020-07-01 19:28 ` Jerry
2020-07-03 7:45 ` Johan Hovold
2020-07-03 15:01 ` Johan Hovold
2020-07-06 11:47 ` Jerry
2020-07-06 13:59 ` Johan Hovold
2020-07-08 21:05 ` Jerry
2020-07-13 10:54 ` Johan Hovold
2020-07-03 18:45 ` Jerry
2020-07-06 7:51 ` Johan Hovold
2020-07-06 9:08 ` Johan Hovold [this message]
2020-07-08 21:34 ` [PATCH v5] " Jaromir Skorpil
2020-07-08 22:21 ` Jaromir Skorpil
2020-06-22 4:38 ` [PATCH 1/1] " Jerry
2020-06-22 5:30 ` Greg Kroah-Hartman
2020-06-22 16:50 ` Jerry
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200706090809.GH3453@localhost \
--to=johan@kernel.org \
--cc=Jerry@jrr.cz \
--cc=gregkh@linuxfoundation.org \
--cc=linux-usb@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.