[PATCH v1] 8250: add support for DTR/DSR hardware flow control

Previous thread: [2.6 patch] make ptrace_untrace() static by Adrian Bunk on Wednesday, August 6, 2008 - 2:12 pm. (1 message)

Next thread: [2.6.28 parch] the scheduled SERIAL_COLDFIRE removal by Adrian Bunk on Wednesday, August 6, 2008 - 2:19 pm. (3 messages)
From: Aristeu Rozanski
Date: Wednesday, August 6, 2008 - 2:14 pm

This patch adds support for DTR/DSR hardware flow control on 8250 driver on x86
machines. It's done by adding a CDTRDSR flag to work just like CRTSCTS, which is
not done on other architectures on purpose (so each maintainer can allocate it).

This patch was tested with success with a serial printer configured with a small
buffer and DTR/DSR flow control.

This is based on the work of Michael Westermann (http://lkml.org/lkml/2007/8/31/133)

Comments more than welcome.

Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>

---
 drivers/serial/8250.c        |   12 ++++++++--
 drivers/serial/serial_core.c |   42 ++++++++++++++++++++++++++++++++++-
 include/asm-x86/termbits.h   |    1 
 include/linux/serial_core.h  |   51 +++++++++++++++++++++++++++----------------
 include/linux/termios.h      |    5 ++++
 5 files changed, 90 insertions(+), 21 deletions(-)

--- linus-2.6.orig/drivers/serial/8250.c	2008-08-05 16:44:26.000000000 -0400
+++ linus-2.6/drivers/serial/8250.c	2008-08-05 18:45:01.000000000 -0400
@@ -1409,7 +1409,7 @@ static unsigned int check_modem_status(s
 		if (status & UART_MSR_TERI)
 			up->port.icount.rng++;
 		if (status & UART_MSR_DDSR)
-			up->port.icount.dsr++;
+			uart_handle_dsr_change(&up->port, status & UART_MSR_DSR);
 		if (status & UART_MSR_DDCD)
 			uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
 		if (status & UART_MSR_DCTS)
@@ -1739,9 +1739,17 @@ static inline void wait_for_xmitr(struct
 		unsigned int tmout;
 		for (tmout = 1000000; tmout; tmout--) {
 			unsigned int msr = serial_in(up, UART_MSR);
+			struct uart_info *info = up->port.info;
+
 			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
-			if (msr & UART_MSR_CTS)
+
+			if ((info->flags & UIF_CTS_FLOW) &&
+			    (msr & UART_MSR_CTS))
 				break;
+			else if ((info->flags & UIF_DSR_FLOW) &&
+				 (msr & UART_MSR_DSR))
+ 				break;
+
 			udelay(1);
 			touch_nmi_watchdog();
 		}
--- linus-2.6.orig/drivers/serial/serial_core.c	2008-08-05 16:44:26.000000000 -0400
+++ ...
From: Laurent Pinchart
Date: Thursday, August 7, 2008 - 1:32 am

Hi,


It's funny, serial flow control hasn't been discussed for a long time, and =
you're the third person to start a flow control related thread on this mail=

Please read the '[PATCH/RFC] 8250: Auto RS485 direction control' thread for=
 background information. In a nutshell we need more than just CTS/RTS and D=
TR/DSR, and we don't have enough c_cflags bits. We will probably have to cr=
eate a new ioctl.

Best regards,

=2D-=20
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
=46 +32 (2) 387 42 75
From: Alan Cox
Date: Thursday, August 7, 2008 - 2:14 am

> Please read the '[PATCH/RFC] 8250: Auto RS485 direction control' thread for background information. In a nutshell we need more than just CTS/RTS and DTR/DSR, and we don't have enough c_cflags bits. We will probably have to create a new ioctl.

Maybe - fortunately the kernel and user termios structure are now
independent so we can extend ktermios easily enough.

--

From: Tosoni
Date: Thursday, August 7, 2008 - 5:54 am

In my opinion, DSR/DTR is another (wrong) way to do RTS/CTS flow control, so
I would have it implemented in setserial as a modifier to the CRTSCTS flag.

About a RS485 ioctl: could you consider the attached files which are already
in the Linux kernel (in include/asm-cris).
They define a TIOCSERSETRS485 (ioctl.h), and the data structure (rs485.h)
with allows to specify timings. Sounds just like what we want ?

From: Alan Cox
Date: Wednesday, August 13, 2008 - 4:39 am

That would make sense for hardware assisted RS485 but we still have to
sort out DTR/DSR as well
--

From: Alan Cox
Date: Monday, August 18, 2008 - 8:25 am

On Thu, 7 Aug 2008 14:54:05 +0200

I had a deeper look at this for RS485 and the answer is "sort of". I've
reworked the structure to keep it the same size irrespective of 32/64bit
systems, and to make stuff flags that can be, plus add some extra u32
words in case we need to (.. when we need to ;)) add stuff later.

Comments, thoughts - will this do what people in the RS485 world need ?

Alan
--------------

tty: Cris has a nice RS485 ioctl so we should steal it

From: Alan Cox <alan@redhat.com>

JP Tosoni observed:

"About a RS485 ioctl: could you consider the attached files which are
 already in the Linux kernel (in include/asm-cris).  They define a
 TIOCSERSETRS485 (ioctl.h), and the data structure (rs485.h)
 with allows to specify timings. Sounds just like what we want ?"

and he's right: sort of. Rework the structure to use flag bits and make the
time delay a fixed sized field so we don't get 32/64bit problems. Add the ioctls
to x86 so that people know what to add to their platform of choice.

Signed-off-by: Alan Cox <alan@redhat.com>
---

 include/asm-x86/ioctls.h |    2 ++
 include/linux/serial.h   |   16 ++++++++++++++++
 2 files changed, 18 insertions(+), 0 deletions(-)


diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h
index c0c338b..2cd4775 100644
--- a/include/asm-x86/ioctls.h
+++ b/include/asm-x86/ioctls.h
@@ -51,6 +51,8 @@
 #define TCSETS2		_IOW('T', 0x2B, struct termios2)
 #define TCSETSW2	_IOW('T', 0x2C, struct termios2)
 #define TCSETSF2	_IOW('T', 0x2D, struct termios2)
+#define TIOCGRS485	0x542E
+#define TIOCSRS485	0x542F
 #define TIOCGPTN	_IOR('T', 0x30, unsigned int)
 				/* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK	_IOW('T', 0x31, int)  /* Lock/unlock Pty */
diff --git a/include/linux/serial.h b/include/linux/serial.h
index deb7143..1ea8d92 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -173,6 +173,22 @@ struct serial_icounter_struct {
 	int reserved[9];
 };
 
+/*
+ * Serial ...
From: Aristeu Rozanski
Date: Wednesday, August 20, 2008 - 2:43 pm

as for DTR/DSR patch, will be used the same approach?

-- 
Aristeu

--

From: Alan Cox
Date: Thursday, August 21, 2008 - 3:23 am

On Wed, 20 Aug 2008 17:43:36 -0400

I'm still trying to get a sensible answer on how other Unixes handle it
--

From: 'Aristeu Rozanski'
Date: Thursday, August 21, 2008 - 11:59 am

I did some research on that:
Solaris and AIX:
	TC{G,S}ETX for extended options and only input flow control (DTRXOFF)
SCO:
	{S,G}ETFLOW for configuring flow control, TXHARD, RXHARD for DTRDSR
FreeBSD:
	cflags has 'dtrflow' and 'dsrflow'

Having the option to set individually which pins to use for input and output
flow control and which ones should be on/off all the time seem to be a powerful
way to do it, instead of having a "CDTRDSR".

-- 
Aristeu

--

Previous thread: [2.6 patch] make ptrace_untrace() static by Adrian Bunk on Wednesday, August 6, 2008 - 2:12 pm. (1 message)

Next thread: [2.6.28 parch] the scheduled SERIAL_COLDFIRE removal by Adrian Bunk on Wednesday, August 6, 2008 - 2:19 pm. (3 messages)