in mxser.c [578:700]
static void mxser_change_speed(struct tty_struct *tty, struct ktermios *old_termios)
{
struct mxser_port *info = tty->driver_data;
unsigned cflag, cval;
cflag = tty->termios.c_cflag;
if (mxser_set_baud(tty, tty_get_baud_rate(tty))) {
/* Use previous rate on a failure */
if (old_termios) {
speed_t baud = tty_termios_baud_rate(old_termios);
tty_encode_baud_rate(tty, baud, baud);
}
}
/* byte size and parity */
switch (cflag & CSIZE) {
default:
case CS5:
cval = UART_LCR_WLEN5;
break;
case CS6:
cval = UART_LCR_WLEN6;
break;
case CS7:
cval = UART_LCR_WLEN7;
break;
case CS8:
cval = UART_LCR_WLEN8;
break;
}
if (cflag & CSTOPB)
cval |= UART_LCR_STOP;
if (cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(cflag & PARODD))
cval |= UART_LCR_EPAR;
if (cflag & CMSPAR)
cval |= UART_LCR_SPAR;
info->FCR = 0;
if (info->board->must_hwid) {
info->FCR |= UART_FCR_ENABLE_FIFO |
MOXA_MUST_FCR_GDA_MODE_ENABLE;
mxser_set_must_fifo_value(info);
} else if (info->type != PORT_8250 && info->type != PORT_16450) {
info->FCR |= UART_FCR_ENABLE_FIFO;
switch (info->rx_high_water) {
case 1:
info->FCR |= UART_FCR_TRIGGER_1;
break;
case 4:
info->FCR |= UART_FCR_TRIGGER_4;
break;
case 8:
info->FCR |= UART_FCR_TRIGGER_8;
break;
default:
info->FCR |= UART_FCR_TRIGGER_14;
break;
}
}
/* CTS flow control flag and modem status interrupts */
info->IER &= ~UART_IER_MSI;
info->MCR &= ~UART_MCR_AFE;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
if (cflag & CRTSCTS) {
info->IER |= UART_IER_MSI;
if (mxser_16550A_or_MUST(info)) {
info->MCR |= UART_MCR_AFE;
} else {
mxser_handle_cts(tty, info,
inb(info->ioaddr + UART_MSR));
}
}
outb(info->MCR, info->ioaddr + UART_MCR);
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
if (~cflag & CLOCAL)
info->IER |= UART_IER_MSI;
outb(info->IER, info->ioaddr + UART_IER);
/*
* Set up parity check flag
*/
info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
if (I_INPCK(tty))
info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
if (I_BRKINT(tty) || I_PARMRK(tty))
info->read_status_mask |= UART_LSR_BI;
info->ignore_status_mask = 0;
if (I_IGNBRK(tty)) {
info->ignore_status_mask |= UART_LSR_BI;
info->read_status_mask |= UART_LSR_BI;
/*
* If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support).
*/
if (I_IGNPAR(tty)) {
info->ignore_status_mask |=
UART_LSR_OE |
UART_LSR_PE |
UART_LSR_FE;
info->read_status_mask |=
UART_LSR_OE |
UART_LSR_PE |
UART_LSR_FE;
}
}
if (info->board->must_hwid) {
mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty));
mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty));
mxser_must_set_rx_sw_flow_control(info->ioaddr, I_IXON(tty));
mxser_must_set_tx_sw_flow_control(info->ioaddr, I_IXOFF(tty));
}
outb(info->FCR, info->ioaddr + UART_FCR);
outb(cval, info->ioaddr + UART_LCR);
}