[patch] DTR/DSR hardware handshake support for 2.0/2.2/2.4

From: Martin Schenk (schenkm@ping.at)
Date: Tue Aug 01 2000 - 11:35:22 EST


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

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Aug 07 2000 - 21:00:06 EST