handshake variable with DTR DSR DCD ...
RFC 1/1 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.
drivers/char/serial.c +65 -13
@@ -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_strucif (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_strelse 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_stif (!(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); }
include/asm-i386/ioctls.h +2 -0
@@ -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
include/asm-i386/termbits.h +1 -0
@@ -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 */
include/linux/serialP.h +2 -0
@@ -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!
On Fri, 2004-05-07 16:54:13 +0200, Michael Westermann <[email protected]> wrote in message <[email protected]>:
Quoted 5 lines
diff -Nurp
linux-2.4.26.old/drivers/char/serial.clinux-2.4.26/drivers/char/serial.cdrivers/char/serial.c +0
-0@@ -769,9 +769,12 @@ static _INLINE_ void check_modem_status( }
drivers/char/serial.c static _INLINE_ void check_modem_status( · line 777
Quoted 10 lines
drivers/char/serial.c +5
-2if (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);
A "\n" is missing here and was already missing in the initial version.
drivers/char/serial.c static _INLINE_ void check_modem_status( · line 791
Quoted 6 lines
drivers/char/serial.c +4
-1#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);
Dito.
Quoted 11 lines
include/asm-i386/termbits.h +1
-0@@ -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 */
Quoted 1 line
It's only i386 yet, but please comment on it!
I won't comment on the code itself, as I don't know the 2.4.x serial driver all that good:) Of course, non-i386 code would be cool, too:)
MfG, JBG
Signature · 4 lines
Jan-Benedict Glaw [email protected] . +49-172-7608481 "Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg fuer einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));