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 +++ ...
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
> 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. --
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 ?
That would make sense for hardware assisted RS485 but we still have to sort out DTR/DSR as well --
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 ...as for DTR/DSR patch, will be used the same approach? -- Aristeu --
On Wed, 20 Aug 2008 17:43:36 -0400 I'm still trying to get a sensible answer on how other Unixes handle it --
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
--
