static void ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios) { ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; unsigned int cflag = tty->termios->c_cflag; ctc_tty_change_speed(info); /* Handle transition to B0 */ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) { info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS); ctc_tty_transmit_status(info); } /* Handle transition from B0 to other */ 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; } ctc_tty_transmit_status(info); } /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) tty->hw_stopped = 0; }
static int ctc_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; DBF_TEXT(trace, 4, __FUNCTION__); if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl")) return -ENODEV; if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; if (set & TIOCM_RTS) info->mcr |= UART_MCR_RTS; if (set & TIOCM_DTR) info->mcr |= UART_MCR_DTR; if (clear & TIOCM_RTS) info->mcr &= ~UART_MCR_RTS; if (clear & TIOCM_DTR) info->mcr &= ~UART_MCR_DTR; if ((set | clear) & (TIOCM_RTS|TIOCM_DTR)) ctc_tty_transmit_status(info); return 0; }
static void ctc_tty_change_speed(ctc_tty_info * info) { unsigned int cflag; unsigned int quot; int i; DBF_TEXT(trace, 3, __FUNCTION__); if (!info->tty || !info->tty->termios) return; cflag = info->tty->termios->c_cflag; quot = i = cflag & CBAUD; if (i & CBAUDEX) { i &= ~CBAUDEX; if (i < 1 || i > 2) info->tty->termios->c_cflag &= ~CBAUDEX; else i += 15; } if (quot) { info->mcr |= UART_MCR_DTR; info->mcr |= UART_MCR_RTS; ctc_tty_transmit_status(info); } else { info->mcr &= ~UART_MCR_DTR; info->mcr &= ~UART_MCR_RTS; ctc_tty_transmit_status(info); return; } /* CTS flow control flag and modem status interrupts */ if (cflag & CRTSCTS) { info->flags |= CTC_ASYNC_CTS_FLOW; } else info->flags &= ~CTC_ASYNC_CTS_FLOW; if (cflag & CLOCAL) info->flags &= ~CTC_ASYNC_CHECK_CD; else { info->flags |= CTC_ASYNC_CHECK_CD; } }
static void ctc_tty_unthrottle(struct tty_struct *tty) { ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; if (ctc_tty_paranoia_check(info, tty->device, "ctc_tty_unthrottle")) return; info->mcr |= UART_MCR_RTS; if (I_IXOFF(tty)) ctc_tty_inject(info, START_CHAR(tty)); ctc_tty_transmit_status(info); }
/* * ------------------------------------------------------------ * ctc_tty_throttle() * * This routine is called by the upper-layer tty layer to signal that * incoming characters should be throttled. * ------------------------------------------------------------ */ static void ctc_tty_throttle(struct tty_struct *tty) { ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; DBF_TEXT(trace, 4, __FUNCTION__); if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle")) return; info->mcr &= ~UART_MCR_RTS; if (I_IXOFF(tty)) ctc_tty_inject(info, STOP_CHAR(tty)); ctc_tty_transmit_status(info); }
static int ctc_tty_set_ctc_tty_info(ctc_tty_info * info, uint cmd, uint * value) { uint arg; int old_mcr = info->mcr & (UART_MCR_RTS | UART_MCR_DTR); get_user(arg, (uint *) value); switch (cmd) { case TIOCMBIS: #ifdef CTC_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "%s%d ioctl TIOCMBIS\n", CTC_TTY_NAME, info->line); #endif if (arg & TIOCM_RTS) info->mcr |= UART_MCR_RTS; if (arg & TIOCM_DTR) info->mcr |= UART_MCR_DTR; break; case TIOCMBIC: #ifdef CTC_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "%s%d ioctl TIOCMBIC\n", CTC_TTY_NAME, info->line); #endif if (arg & TIOCM_RTS) info->mcr &= ~UART_MCR_RTS; if (arg & TIOCM_DTR) info->mcr &= ~UART_MCR_DTR; break; case TIOCMSET: #ifdef CTC_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "%s%d ioctl TIOCMSET\n", CTC_TTY_NAME, info->line); #endif info->mcr = ((info->mcr & ~(UART_MCR_RTS | UART_MCR_DTR)) | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); break; default: return -EINVAL; } if ((info->mcr & (UART_MCR_RTS | UART_MCR_DTR)) != old_mcr) ctc_tty_transmit_status(info); return 0; }