Re: Suggested patch for linux

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thursday 10 July 2008, Matt Schulte wrote:
> 
> > The big problem is that the kernel does not know what is a "transmission"
> > it just sees a series of writes to the device. In many cases the
> > multi-drop or radio systems also need the caller to wait for a
> > transmission slot either by beacon, by timing or by monitoring the
> > carrier detect to avoid collisions.
> I believe that he is referring to something much simpler than you are 
> thinking.  He is talking about 2-wire RS485 transmissions in which the 
> RTS signal is used to enable the driver chips just before transmitting 
> data and disabling (tri-stating) them just after transmitting data.  
> There are some UARTs that have this behavior built into them.

And that feature is currently not supported by Linux, even with UARTs that have hardware support for "Auto RS485" mode, such as the 8250-compatible XR16C2850.

The issue is that no flag is defined for the c_cflag field of the termios structure to enable that feature. The following patch is an example of what would be required.

-----------------------------------------------------------------------------
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 62a2e49..a1351d5 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2071,6 +2071,20 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
 	if (up->port.type == PORT_16750)
 		serial_outp(up, UART_FCR, fcr);
 
+#ifdef CARTS
+	/* Auto RS485 Direction Control on 16850 UARTs */
+	if (up->port.type == PORT_16850) {
+		unsigned char fctr;
+
+		serial_outp(up, UART_LCR, 0xbf);
+		fctr = serial_inp(up, UART_FCTR) & ~UART_FCTR_RS485;
+		if (termios->c_cflag & CARTS)
+			fctr |= UART_FCTR_RS485;
+		serial_outp(up, UART_FCTR, fctr);
+		serial_outp(up, UART_LCR, 0);
+	}
+#endif
+
 	serial_outp(up, UART_LCR, cval);		/* reset DLAB */
 	up->lcr = cval;					/* Save LCR */
 	if (up->port.type != PORT_16750) {
diff --git a/include/asm-powerpc/termbits.h b/include/asm-powerpc/termbits.h
index 5e79198..7b7ee27 100644
--- a/include/asm-powerpc/termbits.h
+++ b/include/asm-powerpc/termbits.h
@@ -166,6 +166,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define CARTS	  004000000000		/* auto RTS control */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 3c8a6aa..3db78cc 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -188,6 +188,7 @@
 #define UART_FCTR_RTS_8DELAY	0x03
 #define UART_FCTR_IRDA		0x04  /* IrDa data encode select */
 #define UART_FCTR_TX_INT	0x08  /* Tx interrupt type select */
+#define UART_FCTR_RS485		0x08  /* Auto RS485 direction control */
 #define UART_FCTR_TRGA		0x00  /* Tx/Rx 550 trigger table select */
 #define UART_FCTR_TRGB		0x10  /* Tx/Rx 650 trigger table select */
 #define UART_FCTR_TRGC		0x20  /* Tx/Rx 654 trigger table select */
-----------------------------------------------------------------------------

As we need a new flag which isn't Posix-compliant as far as I know, the scope of this change can be broader than just the Linux kernel.

Would the above patch be acceptable (I'm open to changes to the CARTS name) as-is, or does it have to be discussed with userspace developers first ?

> > That seems to best be done in user space as the algorithms are quite
> > variable and some are complex.
> >
> > Do we really benefit from having this in kernel ?
> The problem that can come up when executing this feature in user-land 
> (though not exactly common) is when the hardware on the other end 
> responds to your message faster than your user app was able to detect 
> that the UART is finished and then toggle RTS.  When this happens both 
> ends are trying to drive the line and you have bus contention, lost data 
> and possibly damage to the driver chips themselves.

Best regards,

-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

Attachment: signature.asc
Description: This is a digitally signed message part.


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux