Skip to contentSkip to conversation

Linux Keyspan USB serial driver ignoring XOFF

DISCUSSION John Goerzen 2 participants 3 messages Sep 20, 2019 – Sep 23, 2019 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore
#1 lore raw
In reply to a message not in the archive

Hello,

I have narrowed down the issue I'm about to describe to keyspan.c; a Digi Edgeport/1 with identical configuration works fine.

I am configuring a Raspberry Pi running 4.19.66 (though keyspan.c hasn't changed since 2017) to talk to a real-live vt420. Configuring agetty with systemd worked easy enough, but I found that XON/XOFF wasn't working. stty -a shows ixon and ixoff as appropriate, but sending Ctrl-S (tested from multiple ways of sending) had no effect on output in bash, or scrolling output. (Emacs, though, recognized it as the start of a search, so I knew it was getting down the line.)

After a great deal of head-scratching on this, I went to look at the kernel source and found that keyspan.c does not appear to be honoring XOFF. I also have a Digi Edgeport/1 on hand (which uses io_ti.c), and when I swapped to that, everything worked fine - Ctrl-S caused the expected pause.

As far as I can tell, keyspan.c simply never implemented handling of XOFF, but you guys are the experts there.

I twiddled many, many settings with stty but could not find anything that would make it honor xoff/Ctrl-S with the Keyspan. Even as a regular user that would use that trick to pause scrolling, it had no effect. Different TERM settings also had no effect.

Output of stty -a:

speed 19200 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

Thanks,

John

maintainer
#2 lore raw
Quoted 14 lines · John Goerzen

Hello,

I have narrowed down the issue I'm about to describe to keyspan.c; a Digi Edgeport/1 with identical configuration works fine.

I am configuring a Raspberry Pi running 4.19.66 (though keyspan.c hasn't changed since 2017) to talk to a real-live vt420. Configuring agetty with systemd worked easy enough, but I found that XON/XOFF wasn't working. stty -a shows ixon and ixoff as appropriate, but sending Ctrl-S (tested from multiple ways of sending) had no effect on output in bash, or scrolling output. (Emacs, though, recognized it as the start of a search, so I knew it was getting down the line.)

Quoted 8 lines

After a great deal of head-scratching on this, I went to look at the kernel source and found that keyspan.c does not appear to be honoring XOFF. I also have a Digi Edgeport/1 on hand (which uses io_ti.c), and when I swapped to that, everything worked fine - Ctrl-S caused the expected pause.

As far as I can tell, keyspan.c simply never implemented handling of XOFF, but you guys are the experts there.

That's correct, the driver does not support software flow control even if the hardware seems to have some support for assisted XON/XOFF.

Would you mind testing the below patch which may be enough to turn sw-flow control always on. If that works, I can probably find time to cook up a proper patch to make this configurable later this week.

Johan

From 55b46d78fe63f182923e4674659fa18f4624d6b8 Mon Sep 17 00:00:00 2001
From: Johan Hovold <[email protected]>
Date: Mon, 23 Sep 2019 12:14:56 +0200
Subject: [PATCH] USB: serial: keyspan: enable XON flow control

---
 drivers/usb/serial/keyspan.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/serial/keyspan.c +4 -4
index d34779fe4a8d..934430cbdfc4 100644
@@ -2118,7 +2118,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
 	msg.setLcr = 0xff;
 
 	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
-	msg.xonFlowControl = 0;
+	msg.xonFlowControl = 1;
 	msg.setFlowControl = 0xff;
 	msg.forwardingLength = 16;
 	msg.xonChar = 17;
@@ -2234,7 +2234,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
 	msg.parity = 0;		/* XXX for now */
 
 	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
-	msg.xonFlowControl = 0;
+	msg.xonFlowControl = 1;
 
 	/* Do handshaking outputs, DTR is inverted relative to RTS */
 	msg.rts = p_priv->rts_state;
@@ -2388,7 +2388,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
 	msg.setLcr = 0xff;
 
 	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
-	msg.xonFlowControl = 0;
+	msg.xonFlowControl = 1;
 	msg.setFlowControl = 0xff;
 
 	msg.forwardingLength = 16;
@@ -2690,7 +2690,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
 	msg.setLcr = 0xff;
 
 	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
-	msg.xonFlowControl = 0;
+	msg.xonFlowControl = 1;
 	msg.setFlowControl = 0xff;
 	msg.forwardingLength = 16;
 	msg.xonChar = 17;
Signature · 1 line
2.23.0
#3 lore raw
Quoted 6 lines · Johan Hovold

That's correct, the driver does not support software flow control even if the hardware seems to have some support for assisted XON/XOFF.

Would you mind testing the below patch which may be enough to turn sw-flow control always on. If that works, I can probably find time to cook up a proper patch to make this configurable later this week.

Hi Johan,

I gave it a try, but unfortunately that patch made no difference to the
behavior I was seeing. I'm happy to do whatever debugging may be
helpful.

Thanks!

- John