Messages in this thread Patch in this message | | | Date | Fri, 7 May 2004 16:54:13 +0200 | From | Michael Westermann <> | Subject | [RFC] handshake variable with DTR DSR DCD ... |
| |
Hello,
this is a patch to allow arbitrary serial status lines to be used for hardware handshake. It's mainly useful for DTR/DSR handshake.
diff -Nurp linux-2.4.26.old/drivers/char/serial.c linux-2.4.26/drivers/char/serial.c --- linux-2.4.26.old/drivers/char/serial.c 2004-02-18 14:36:31.000000000 +0100 +++ linux-2.4.26/drivers/char/serial.c 2004-05-07 16:42:19.000000000 +0200 @@ -769,9 +769,12 @@ static _INLINE_ void check_modem_status( } if (info->flags & ASYNC_CTS_FLOW) { if (info->tty->hw_stopped) { - if (status & UART_MSR_CTS) { + if (status & info->status_flow) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); + if (info->status_flow & UART_MSR_CTS) + printk("CTS tx start..."); + else + printk("HW %x tx start...", info->status_flow); #endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; @@ -780,9 +783,12 @@ static _INLINE_ void check_modem_status( return; } } else { - if (!(status & UART_MSR_CTS)) { + if (!(status & info->status_flow)) { #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); + if (info->status_flow & UART_MSR_CTS) + printk("CTS tx stop..."); + else + printk("HW %x tx stop...", info->status_flow); #endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; @@ -1749,9 +1755,13 @@ static void change_speed(struct async_st info->IER &= ~UART_IER_MSI; if (info->flags & ASYNC_HARDPPS_CD) info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { + if (cflag & (CRTSCTS|CHWFLOW)) { info->flags |= ASYNC_CTS_FLOW; info->IER |= UART_IER_MSI; + if (!(cflag & CHWFLOW)) { + info->status_flow = UART_MSR_CTS; + info->modem_flow = UART_MCR_RTS; + } } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) @@ -2018,8 +2028,8 @@ static void rs_throttle(struct tty_struc if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; + if (tty->termios->c_cflag & (CRTSCTS|CHWFLOW)) + info->MCR &= ~info->modem_flow; save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); @@ -2046,8 +2056,8 @@ static void rs_unthrottle(struct tty_str else rs_send_xchar(tty, START_CHAR(tty)); } - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; + if (tty->termios->c_cflag & (CRTSCTS|CHWFLOW)) + info->MCR |= info->modem_flow; save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); restore_flags(flags); @@ -2352,6 +2362,46 @@ static int set_modem_info(struct async_s | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); break; + case TIOHWFLOWBIS: + if (arg & TIOCM_RTS) + info->modem_flow |= UART_MCR_RTS; + if (arg & TIOCM_DTR) + info->modem_flow |= UART_MCR_DTR; +#ifdef TIOCM_OUT1 + if (arg & TIOCM_OUT1) + info->modem_flow |= UART_MCR_OUT1; + if (arg & TIOCM_OUT2) + info->modem_flow |= UART_MCR_OUT2; +#endif + if (arg & TIOCM_CTS) + info->status_flow |= UART_MSR_CTS; + if (arg & TIOCM_DSR) + info->status_flow |= UART_MSR_DSR; + if (arg & TIOCM_RI) + info->status_flow |= UART_MSR_RI; + if (arg & TIOCM_CD) + info->status_flow |= UART_MSR_DCD; + break; + case TIOHWFLOWBIC: + if (arg & TIOCM_RTS) + info->modem_flow &= ~UART_MCR_RTS; + if (arg & TIOCM_DTR) + info->modem_flow &= ~UART_MCR_DTR; +#ifdef TIOCM_OUT1 + if (arg & TIOCM_OUT1) + info->modem_flow &= ~UART_MCR_OUT1; + if (arg & TIOCM_OUT2) + info->modem_flow &= ~UART_MCR_OUT2; +#endif + if (arg & TIOCM_CTS) + info->status_flow &= ~UART_MSR_CTS; + if (arg & TIOCM_DSR) + info->status_flow &= ~UART_MSR_DSR; + if (arg & TIOCM_RI) + info->status_flow &= ~UART_MSR_RI; + if (arg & TIOCM_CD) + info->status_flow &= ~UART_MSR_DCD; + break; default: return -EINVAL; } @@ -2605,6 +2655,8 @@ static int rs_ioctl(struct tty_struct *t #endif case TIOCMGET: return get_modem_info(info, (unsigned int *) arg); + case TIOHWFLOWBIS: + case TIOHWFLOWBIC: case TIOCMBIS: case TIOCMBIC: case TIOCMSET: @@ -2734,9 +2786,9 @@ static void rs_set_termios(struct tty_st if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { info->MCR |= UART_MCR_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || + if (!(tty->termios->c_cflag & (CRTSCTS|CHWFLOW)) || !test_bit(TTY_THROTTLED, &tty->flags)) { - info->MCR |= UART_MCR_RTS; + info->MCR |= info->status_flow; } save_flags(flags); cli(); serial_out(info, UART_MCR, info->MCR); @@ -2744,8 +2796,8 @@ static void rs_set_termios(struct tty_st } /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { + if ((old_termios->c_cflag & (CRTSCTS|CHWFLOW)) && + !(tty->termios->c_cflag & (CRTSCTS|CHWFLOW))) { tty->hw_stopped = 0; rs_start(tty); } diff -Nurp linux-2.4.26.old/include/asm-i386/ioctls.h linux-2.4.26/include/asm-i386/ioctls.h --- linux-2.4.26.old/include/asm-i386/ioctls.h 2003-08-25 13:44:43.000000000 +0200 +++ linux-2.4.26/include/asm-i386/ioctls.h 2004-05-07 13:48:28.000000000 +0200 @@ -68,6 +68,8 @@ #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 +#define TIOHWFLOWBIS 0x5461 /* Set hardware flow Control */ +#define TIOHWFLOWBIC 0x5462 /* Clear hardware flow Control */ /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -Nurp linux-2.4.26.old/include/asm-i386/termbits.h linux-2.4.26/include/asm-i386/termbits.h --- linux-2.4.26.old/include/asm-i386/termbits.h 2000-01-21 01:05:26.000000000 +0100 +++ linux-2.4.26/include/asm-i386/termbits.h 2004-05-07 16:43:39.000000000 +0200 @@ -132,6 +132,7 @@ struct termios { #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017 +#define CHWFLOW 001000000000 /* flexible hw flow_ctrl */ #define CIBAUD 002003600000 /* input baud rate (not used) */ #define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ diff -Nurp linux-2.4.26.old/include/linux/serialP.h linux-2.4.26/include/linux/serialP.h --- linux-2.4.26.old/include/linux/serialP.h 2002-08-03 02:39:45.000000000 +0200 +++ linux-2.4.26/include/linux/serialP.h 2004-05-07 14:06:30.000000000 +0200 @@ -68,6 +68,8 @@ struct async_struct { int timeout; int quot; int x_char; /* xon/xoff character */ + int status_flow; /* status mask hw-flowcontrol */ + int modem_flow; /* modem mask hw-flowcontrol */ int close_delay; unsigned short closing_wait; unsigned short closing_wait2; It's only i386 yet, but please comment on it!
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |