static void mxser_change_speed()

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);
}