From: Johan Hovold <johan@kernel.org>
To: linux-usb@vger.kernel.org
Cc: Sheng Long Wang <shenglong.wang.ext@siemens.com>,
linux-kernel@vger.kernel.org, Johan Hovold <johan@kernel.org>
Subject: [PATCH 5/6] USB: serial: cp210x: refactor flow-control handling
Date: Mon, 16 Nov 2020 17:18:25 +0100 [thread overview]
Message-ID: <20201116161826.29417-6-johan@kernel.org> (raw)
In-Reply-To: <20201116161826.29417-1-johan@kernel.org>
Add a helper function to be used to configure flow control.
The flow-control code was the last caller that relied on the
memset-on-failure behaviour of cp210x_read_reg_block(), which we can now
drop in favour of bailing out on errors when retrieving the flow-control
settings.
This should also simplify adding support for software flow control.
Signed-off-by: Johan Hovold <johan@kernel.org>
---
drivers/usb/serial/cp210x.c | 97 ++++++++++++++++++-------------------
1 file changed, 47 insertions(+), 50 deletions(-)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 04d2b15ceded..c77fd09b91ce 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -555,14 +555,8 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req,
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);
+ if (!dmabuf)
return -ENOMEM;
- }
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
req, REQTYPE_INTERFACE_TO_HOST, 0,
@@ -576,12 +570,6 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req,
req, bufsize, result);
if (result >= 0)
result = -EIO;
-
- /*
- * 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);
@@ -1095,11 +1083,55 @@ static bool cp210x_termios_change(const struct ktermios *a, const struct ktermio
return tty_termios_hw_change(a, b) || iflag_change;
}
+static void cp210x_set_flow_control(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
+{
+ struct cp210x_flow_ctl flow_ctl;
+ u32 flow_repl;
+ u32 ctl_hs;
+ int ret;
+
+ if (old_termios && C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS))
+ return;
+
+ ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
+ sizeof(flow_ctl));
+ if (ret)
+ return;
+
+ ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
+ flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace);
+
+ ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE;
+ ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE;
+ ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY;
+ ctl_hs &= ~CP210X_SERIAL_DTR_MASK;
+ ctl_hs |= CP210X_SERIAL_DTR_SHIFT(CP210X_SERIAL_DTR_ACTIVE);
+
+ if (C_CRTSCTS(tty)) {
+ ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE;
+ flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+ flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL);
+ } else {
+ ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE;
+ flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+ flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_ACTIVE);
+ }
+
+ dev_dbg(&port->dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n",
+ __func__, ctl_hs, flow_repl);
+
+ flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs);
+ flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl);
+
+ cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl,
+ sizeof(flow_ctl));
+}
+
static void cp210x_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
struct cp210x_serial_private *priv = usb_get_serial_data(port->serial);
- struct device *dev = &port->dev;
u16 bits;
int ret;
@@ -1156,42 +1188,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
if (ret)
dev_err(&port->dev, "failed to set line control: %d\n", ret);
- if (!old_termios || C_CRTSCTS(tty) != (old_termios->c_cflag & CRTSCTS)) {
- struct cp210x_flow_ctl flow_ctl;
- u32 ctl_hs;
- u32 flow_repl;
-
- cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
- sizeof(flow_ctl));
- ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
- flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace);
-
- ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE;
- ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE;
- ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY;
- ctl_hs &= ~CP210X_SERIAL_DTR_MASK;
- ctl_hs |= CP210X_SERIAL_DTR_SHIFT(CP210X_SERIAL_DTR_ACTIVE);
- if (C_CRTSCTS(tty)) {
- ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE;
-
- flow_repl &= ~CP210X_SERIAL_RTS_MASK;
- flow_repl |= CP210X_SERIAL_RTS_SHIFT(
- CP210X_SERIAL_RTS_FLOW_CTL);
- } else {
- ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE;
-
- flow_repl &= ~CP210X_SERIAL_RTS_MASK;
- flow_repl |= CP210X_SERIAL_RTS_SHIFT(
- CP210X_SERIAL_RTS_ACTIVE);
- }
-
- dev_dbg(dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n",
- __func__, ctl_hs, flow_repl);
- flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs);
- flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl);
- cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl,
- sizeof(flow_ctl));
- }
+ cp210x_set_flow_control(tty, port, old_termios);
/*
* Enable event-insertion mode only if input parity checking is
--
2.26.2
next prev parent reply other threads:[~2020-11-16 16:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-16 16:18 [PATCH 0/6] USB: serial: cp210x: clean up termios handling Johan Hovold
2020-11-16 16:18 ` [PATCH 1/6] USB: serial: cp210x: return early on unchanged termios Johan Hovold
2020-11-16 16:18 ` [PATCH 2/6] USB: serial: cp210x: clean up line-control handling Johan Hovold
2020-11-16 16:18 ` [PATCH 3/6] USB: serial: cp210x: set terminal settings on open Johan Hovold
2020-11-16 16:18 ` [PATCH 4/6] USB: serial: cp210x: drop flow-control debugging Johan Hovold
2020-11-16 16:18 ` Johan Hovold [this message]
2020-11-16 16:18 ` [PATCH 6/6] USB: serial: cp210x: clean up dts_rts Johan Hovold
2020-12-04 13:59 ` [PATCH 0/6] USB: serial: cp210x: clean up termios handling Johan Hovold
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=20201116161826.29417-6-johan@kernel.org \
--to=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=shenglong.wang.ext@siemens.com \
/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.