Messages in this thread | | | Date | Tue, 01 Aug 2000 18:35:22 +0200 | From | Martin Schenk <> | Subject | [patch] DTR/DSR hardware handshake support for 2.0/2.2/2.4 |
| |
As I needed support for DTR/DSR hardware handshake to communicate with a serial printer (and the "wire RTS/CTS to DTR/DSR" tip from the serial-HOWTO works fine for a demo, but is not applicable for a few thousand POS terminals *gg*), I implemented this functionality.
I append patches for serial.c on 2.0.38/2.2.16/2.4.0-test5, and a patch to include/asm-*/termbits.h (which adds a flag DTRDSR).
In order to use this patch, add the following #define to your code: #define DTRDSR 004000000000 and use DTRDSR as you used CRTSCTS.
I guess this patch is trivial enough to go into the next kernel versions
Martin*** linux-old/drivers/char/serial.c Tue Aug 1 18:15:20 2000 --- linux/drivers/char/serial.c Tue Aug 1 18:24:01 2000 *************** *** 21,26 **** --- 21,30 ---- * * Added Support for PCI serial boards which contain 16x50 Chips * 31.10.1998 Henning P. Schmiedehausen <hps@tanstaafl.de> + * + * 8/00: Added support for DTR/DRS hardware handshake (using flag DTRDRS) + * Martin Schenk <martin@schenk.com> + * * * This module exports the following rs232 io functions: * *************** *** 585,594 **** } } if (info->flags & ASYNC_CTS_FLOW) { if (info->tty->hw_stopped) { ! if (status & UART_MSR_CTS) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! printk("CTS tx start..."); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; --- 589,601 ---- } } if (info->flags & ASYNC_CTS_FLOW) { + int flg=(info->tty->termios->c_cflag & DTRDSR) ? UART_MSR_DSR : UART_MSR_CTS; + if (info->tty->hw_stopped) { ! if (status & flg) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! if (info->tty->termios->c_cflag & DTRDSR) printk("DSR tx start..."); ! else printk("CTS tx start..."); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; *************** *** 597,605 **** return; } } else { ! if (!(status & UART_MSR_CTS)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! printk("CTS tx stop..."); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; --- 604,613 ---- return; } } else { ! if (!(status & flg)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! if (info->tty->termios->c_cflag & DTRDSR) printk("DSR tx ..."); ! else printk("CTS tx stop..."); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; *************** *** 1336,1341 **** --- 1344,1353 ---- info->flags |= ASYNC_CTS_FLOW; info->IER |= UART_IER_MSI; } else + if (cflag & DTRDSR) { + info->flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) info->flags &= ~ASYNC_CHECK_CD; *************** *** 1524,1529 **** --- 1536,1542 ---- static void rs_throttle(struct tty_struct * tty) { struct async_struct *info = (struct async_struct *)tty->driver_data; + int flg=0; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; *************** *** 1537,1544 **** if (I_IXOFF(tty)) info->x_char = STOP_CHAR(tty); ! info->MCR &= ~UART_MCR_RTS; ! info->MCR_noint &= ~UART_MCR_RTS; cli(); serial_out(info, UART_MCR, info->MCR); sti(); --- 1550,1560 ---- if (I_IXOFF(tty)) info->x_char = STOP_CHAR(tty); ! if (tty->termios->c_cflag & CRTSCTS) flg=UART_MCR_RTS; ! if (tty->termios->c_cflag & DTRDSR) flg=UART_MCR_DTR; ! ! info->MCR &= ~flg; ! info->MCR_noint &= ~flg; cli(); serial_out(info, UART_MCR, info->MCR); sti(); *************** *** 1547,1552 **** --- 1563,1569 ---- static void rs_unthrottle(struct tty_struct * tty) { struct async_struct *info = (struct async_struct *)tty->driver_data; + int flg=0; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; *************** *** 1563,1570 **** else info->x_char = START_CHAR(tty); } ! info->MCR |= UART_MCR_RTS; ! info->MCR_noint |= UART_MCR_RTS; cli(); serial_out(info, UART_MCR, info->MCR); sti(); --- 1580,1590 ---- else info->x_char = START_CHAR(tty); } ! if (tty->termios->c_cflag & CRTSCTS) flg=UART_MCR_RTS; ! if (tty->termios->c_cflag & DTRDSR) flg=UART_MCR_DTR; ! ! info->MCR |= flg; ! info->MCR_noint |= flg; cli(); serial_out(info, UART_MCR, info->MCR); sti(); *************** *** 2210,2215 **** --- 2230,2240 ---- if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } + if ((old_termios->c_cflag & DTRDSR) && + !(tty->termios->c_cflag & DTRDSR)) { tty->hw_stopped = 0; rs_start(tty); } *** linux-old/drivers/char/serial.c Tue Aug 1 17:48:13 2000 --- linux/drivers/char/serial.c Tue Aug 1 17:50:48 2000 *************** *** 32,37 **** --- 32,40 ---- * 4/98: Added changes to support the ARM architecture proposed by * Russell King * + * 8/00: Added support for DTR/DRS hardware handshake (using flag DTRDRS) + * Martin Schenk <martin@schenk.com> + * * This module exports the following rs232 io functions: * * int rs_init(void); *************** *** 543,552 **** } } if (info->flags & ASYNC_CTS_FLOW) { if (info->tty->hw_stopped) { ! if (status & UART_MSR_CTS) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! printk("CTS tx start..."); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; --- 546,558 ---- } } if (info->flags & ASYNC_CTS_FLOW) { + int flg=(info->tty->termios->c_cflag & DTRDSR) ? UART_MSR_DSR : UART_MSR_CTS; + if (info->tty->hw_stopped) { ! if (status & flg) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! if (info->tty->termios->c_cflag & DTRDSR) printk("DSR tx start..."); ! else printk("CTS tx start..."); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; *************** *** 555,563 **** return; } } else { ! if (!(status & UART_MSR_CTS)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! printk("CTS tx stop..."); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; --- 561,570 ---- return; } } else { ! if (!(status & flg)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! if (info->tty->termios->c_cflag & DTRDSR) printk("DSR tx ..."); ! else printk("CTS tx stop..."); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; *************** *** 1332,1337 **** --- 1339,1348 ---- info->flags |= ASYNC_CTS_FLOW; info->IER |= UART_IER_MSI; } else + if (cflag & DTRDSR) { + info->flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) info->flags &= ~ASYNC_CHECK_CD; *************** *** 1591,1596 **** --- 1602,1610 ---- if (tty->termios->c_cflag & CRTSCTS) info->MCR &= ~UART_MCR_RTS; + if (tty->termios->c_cflag & DTRDSR) + info->MCR &= ~UART_MCR_DTR; + save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); restore_flags(flags); *************** *** 1618,1623 **** --- 1632,1639 ---- } if (tty->termios->c_cflag & CRTSCTS) info->MCR |= UART_MCR_RTS; + if (tty->termios->c_cflag & DTRDSR) + info->MCR |= UART_MCR_DTR; save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); restore_flags(flags); *************** *** 2193,2200 **** /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { ! info->MCR |= UART_MCR_DTR; ! if (!(tty->termios->c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { info->MCR |= UART_MCR_RTS; --- 2209,2218 ---- /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { ! if (!(tty->termios->c_cflag & DTRDSR) || ! !test_bit(TTY_THROTTLED, &tty->flags)) { ! info->MCR |= UART_MCR_DTR; ! } if (!(tty->termios->c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { info->MCR |= UART_MCR_RTS; *************** *** 2207,2212 **** --- 2225,2236 ---- /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } + /* Handle turning off DTRDSR */ + if ((old_termios->c_cflag & DTRDSR) && + !(tty->termios->c_cflag & DTRDSR)) { tty->hw_stopped = 0; rs_start(tty); } *** linux-old/drivers/char/serial.c Tue Aug 1 18:03:05 2000 --- linux/drivers/char/serial.c Tue Aug 1 18:11:08 2000 *************** *** 51,56 **** --- 51,59 ---- * * 7/00: Support Timedia/Sunix/Exsys PCI cards * + * 8/00: Added support for DTR/DRS hardware handshake (using flag DTRDRS) + * Martin Schenk <martin@schenk.com> + * * This module exports the following rs232 io functions: * * int rs_init(void); *************** *** 740,749 **** } } if (info->flags & ASYNC_CTS_FLOW) { if (info->tty->hw_stopped) { ! if (status & UART_MSR_CTS) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! printk("CTS tx start..."); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; --- 743,755 ---- } } if (info->flags & ASYNC_CTS_FLOW) { + int flg=(info->tty->termios->c_cflag & DTRDSR) ? UART_MSR_DSR : UART_MSR_CTS; + if (info->tty->hw_stopped) { ! if (status & flg) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! if (info->tty->termios->c_cflag & DTRDSR) printk("DSR tx start..."); ! else printk("CTS tx start..."); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; *************** *** 752,760 **** return; } } else { ! if (!(status & UART_MSR_CTS)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! printk("CTS tx stop..."); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; --- 758,767 ---- return; } } else { ! if (!(status & flg)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) ! if (info->tty->termios->c_cflag & DTRDSR) printk("DSR tx ..."); ! else printk("CTS tx stop..."); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; *************** *** 1700,1705 **** --- 1707,1716 ---- info->flags |= ASYNC_CTS_FLOW; info->IER |= UART_IER_MSI; } else + if (cflag & DTRDSR) { + info->flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) info->flags &= ~ASYNC_CHECK_CD; *************** *** 1968,1973 **** --- 1979,1987 ---- if (tty->termios->c_cflag & CRTSCTS) info->MCR &= ~UART_MCR_RTS; + if (tty->termios->c_cflag & DTRDSR) + info->MCR &= ~UART_MCR_DTR; + save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); restore_flags(flags); *************** *** 1995,2000 **** --- 2009,2016 ---- } if (tty->termios->c_cflag & CRTSCTS) info->MCR |= UART_MCR_RTS; + if (tty->termios->c_cflag & DTRDSR) + info->MCR |= UART_MCR_DTR; save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); restore_flags(flags); *************** *** 2676,2682 **** /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { ! info->MCR |= UART_MCR_DTR; if (!(tty->termios->c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { info->MCR |= UART_MCR_RTS; --- 2692,2701 ---- /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { ! if (!(tty->termios->c_cflag & DTRDSR) || ! !test_bit(TTY_THROTTLED, &tty->flags)) { ! info->MCR |= UART_MCR_DTR; ! } if (!(tty->termios->c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { info->MCR |= UART_MCR_RTS; *************** *** 2689,2694 **** --- 2708,2719 ---- /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } + /* Handle turning off DTRDSR */ + if ((old_termios->c_cflag & DTRDSR) && + !(tty->termios->c_cflag & DTRDSR)) { tty->hw_stopped = 0; rs_start(tty); } *** linux-old/include/asm-i386/termbits.h Tue Aug 1 17:54:03 2000 --- linux/include/asm-i386/termbits.h Tue Aug 1 17:53:59 2000 *************** *** 135,140 **** --- 135,141 ---- #define CIBAUD 002003600000 /* input baud rate (not used) */ #define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ + #define DTRDSR 004000000000 /* DTRDSR flow control */ /* c_lflag bits */ #define ISIG 0000001
| |