/* * neo_param() * Send any/all changes to the line to the UART. */ static void neo_param(struct jsm_channel *ch) { u8 lcr = 0; u8 uart_lcr, ier; u32 baud; int quot; struct jsm_board *bd; bd = ch->ch_bd; if (!bd) return; /* * If baud rate is zero, flush queues, and set mval to drop DTR. */ if ((ch->ch_c_cflag & (CBAUD)) == 0) { ch->ch_r_head = ch->ch_r_tail = 0; ch->ch_e_head = ch->ch_e_tail = 0; ch->ch_w_head = ch->ch_w_tail = 0; neo_flush_uart_write(ch); neo_flush_uart_read(ch); ch->ch_flags |= (CH_BAUD0); ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); neo_assert_modem_signals(ch); ch->ch_old_baud = 0; return; } else if (ch->ch_custom_speed) { baud = ch->ch_custom_speed; if (ch->ch_flags & CH_BAUD0) ch->ch_flags &= ~(CH_BAUD0); } else { int i; unsigned int cflag; static struct { unsigned int rate; unsigned int cflag; } baud_rates[] = { { 921600, B921600 }, { 460800, B460800 }, { 230400, B230400 }, { 115200, B115200 }, { 57600, B57600 }, { 38400, B38400 }, { 19200, B19200 }, { 9600, B9600 }, { 4800, B4800 }, { 2400, B2400 }, { 1200, B1200 }, { 600, B600 }, { 300, B300 }, { 200, B200 }, { 150, B150 }, { 134, B134 }, { 110, B110 }, { 75, B75 }, { 50, B50 }, }; cflag = C_BAUD(ch->uart_port.state->port.tty); baud = 9600; for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { if (baud_rates[i].cflag == cflag) { baud = baud_rates[i].rate; break; } } if (ch->ch_flags & CH_BAUD0) ch->ch_flags &= ~(CH_BAUD0); } if (ch->ch_c_cflag & PARENB) lcr |= UART_LCR_PARITY; if (!(ch->ch_c_cflag & PARODD)) lcr |= UART_LCR_EPAR; /* * Not all platforms support mark/space parity, * so this will hide behind an ifdef. */ #ifdef CMSPAR if (ch->ch_c_cflag & CMSPAR) lcr |= UART_LCR_SPAR; #endif if (ch->ch_c_cflag & CSTOPB) lcr |= UART_LCR_STOP; switch (ch->ch_c_cflag & CSIZE) { case CS5: lcr |= UART_LCR_WLEN5; break; case CS6: lcr |= UART_LCR_WLEN6; break; case CS7: lcr |= UART_LCR_WLEN7; break; case CS8: default: lcr |= UART_LCR_WLEN8; break; } ier = readb(&ch->ch_neo_uart->ier); uart_lcr = readb(&ch->ch_neo_uart->lcr); if (baud == 0) baud = 9600; quot = ch->ch_bd->bd_dividend / baud; if (quot != 0) { ch->ch_old_baud = baud; writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); writeb((quot & 0xff), &ch->ch_neo_uart->txrx); writeb((quot >> 8), &ch->ch_neo_uart->ier); writeb(lcr, &ch->ch_neo_uart->lcr); }
/* * neo_param() * Send any/all changes to the line to the UART. */ static void neo_param(struct tty_struct *tty) { unsigned char lcr = 0; unsigned char uart_lcr = 0; unsigned char ier = 0; unsigned char uart_ier = 0; uint baud = 9600; int quot = 0; struct dgnc_board *bd; struct channel_t *ch; struct un_t *un; if (!tty || tty->magic != TTY_MAGIC) return; un = (struct un_t *)tty->driver_data; if (!un || un->magic != DGNC_UNIT_MAGIC) return; ch = un->un_ch; if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; bd = ch->ch_bd; if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; /* * If baud rate is zero, flush queues, and set mval to drop DTR. */ if ((ch->ch_c_cflag & (CBAUD)) == 0) { ch->ch_r_head = 0; ch->ch_r_tail = 0; ch->ch_e_head = 0; ch->ch_e_tail = 0; ch->ch_w_head = 0; ch->ch_w_tail = 0; neo_flush_uart_write(ch); neo_flush_uart_read(ch); /* The baudrate is B0 so all modem lines are to be dropped. */ ch->ch_flags |= (CH_BAUD0); ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); neo_assert_modem_signals(ch); ch->ch_old_baud = 0; return; } else if (ch->ch_custom_speed) { baud = ch->ch_custom_speed; /* Handle transition from B0 */ if (ch->ch_flags & CH_BAUD0) { ch->ch_flags &= ~(CH_BAUD0); /* * Bring back up RTS and DTR... * Also handle RTS or DTR toggle if set. */ if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)) ch->ch_mostat |= (UART_MCR_RTS); if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)) ch->ch_mostat |= (UART_MCR_DTR); } } else { int iindex = 0; int jindex = 0; ulong bauds[4][16] = { { /* slowbaud */ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 }, { /* slowbaud & CBAUDEX */ 0, 57600, 115200, 230400, 460800, 150, 200, 921600, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 }, { /* fastbaud */ 0, 57600, 76800, 115200, 131657, 153600, 230400, 460800, 921600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 }, { /* fastbaud & CBAUDEX */ 0, 57600, 115200, 230400, 460800, 150, 200, 921600, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 } }; /* Only use the TXPrint baud rate if the terminal unit is NOT open */ if (!(ch->ch_tun.un_flags & UN_ISOPEN) && (un->un_type == DGNC_PRINT)) baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; else baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; if (ch->ch_c_cflag & CBAUDEX) iindex = 1; if (ch->ch_digi.digi_flags & DIGI_FAST) iindex += 2; jindex = baud; if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) baud = bauds[iindex][jindex]; else baud = 0; if (baud == 0) baud = 9600; /* Handle transition from B0 */ if (ch->ch_flags & CH_BAUD0) { ch->ch_flags &= ~(CH_BAUD0); /* * Bring back up RTS and DTR... * Also handle RTS or DTR toggle if set. */ if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)) ch->ch_mostat |= (UART_MCR_RTS); if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)) ch->ch_mostat |= (UART_MCR_DTR); } } if (ch->ch_c_cflag & PARENB) lcr |= UART_LCR_PARITY; if (!(ch->ch_c_cflag & PARODD)) lcr |= UART_LCR_EPAR; /* * Not all platforms support mark/space parity, * so this will hide behind an ifdef. */ #ifdef CMSPAR if (ch->ch_c_cflag & CMSPAR) lcr |= UART_LCR_SPAR; #endif if (ch->ch_c_cflag & CSTOPB) lcr |= UART_LCR_STOP; switch (ch->ch_c_cflag & CSIZE) { case CS5: lcr |= UART_LCR_WLEN5; break; case CS6: lcr |= UART_LCR_WLEN6; break; case CS7: lcr |= UART_LCR_WLEN7; break; case CS8: default: lcr |= UART_LCR_WLEN8; break; } uart_ier = readb(&ch->ch_neo_uart->ier); ier = uart_ier; uart_lcr = readb(&ch->ch_neo_uart->lcr); if (baud == 0) baud = 9600; quot = ch->ch_bd->bd_dividend / baud; if (quot != 0 && ch->ch_old_baud != baud) { ch->ch_old_baud = baud; writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); writeb((quot & 0xff), &ch->ch_neo_uart->txrx); writeb((quot >> 8), &ch->ch_neo_uart->ier); writeb(lcr, &ch->ch_neo_uart->lcr); }
/* * neo_param() * Send any/all changes to the line to the UART. */ static void neo_param(struct jsm_channel *ch) { u8 lcr = 0; u8 uart_lcr = 0; u8 ier = 0; u32 baud = 9600; int quot = 0; struct jsm_board *bd; bd = ch->ch_bd; if (!bd) return; /* * If baud rate is zero, flush queues, and set mval to drop DTR. */ if ((ch->ch_c_cflag & (CBAUD)) == 0) { ch->ch_r_head = ch->ch_r_tail = 0; ch->ch_e_head = ch->ch_e_tail = 0; ch->ch_w_head = ch->ch_w_tail = 0; neo_flush_uart_write(ch); neo_flush_uart_read(ch); ch->ch_flags |= (CH_BAUD0); ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); neo_assert_modem_signals(ch); ch->ch_old_baud = 0; return; } else if (ch->ch_custom_speed) { baud = ch->ch_custom_speed; if (ch->ch_flags & CH_BAUD0) ch->ch_flags &= ~(CH_BAUD0); } else { int iindex = 0; int jindex = 0; const u64 bauds[4][16] = { { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 }, { 0, 57600, 115200, 230400, 460800, 150, 200, 921600, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 }, { 0, 57600, 76800, 115200, 131657, 153600, 230400, 460800, 921600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 }, { 0, 57600, 115200, 230400, 460800, 150, 200, 921600, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400 } }; baud = C_BAUD(ch->uart_port.info->tty) & 0xff; if (ch->ch_c_cflag & CBAUDEX) iindex = 1; jindex = baud; if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) baud = bauds[iindex][jindex]; else { jsm_printk(IOCTL, DEBUG, &ch->ch_bd->pci_dev, "baud indices were out of range (%d)(%d)", iindex, jindex); baud = 0; } if (baud == 0) baud = 9600; if (ch->ch_flags & CH_BAUD0) ch->ch_flags &= ~(CH_BAUD0); } if (ch->ch_c_cflag & PARENB) lcr |= UART_LCR_PARITY; if (!(ch->ch_c_cflag & PARODD)) lcr |= UART_LCR_EPAR; /* * Not all platforms support mark/space parity, * so this will hide behind an ifdef. */ #ifdef CMSPAR if (ch->ch_c_cflag & CMSPAR) lcr |= UART_LCR_SPAR; #endif if (ch->ch_c_cflag & CSTOPB) lcr |= UART_LCR_STOP; switch (ch->ch_c_cflag & CSIZE) { case CS5: lcr |= UART_LCR_WLEN5; break; case CS6: lcr |= UART_LCR_WLEN6; break; case CS7: lcr |= UART_LCR_WLEN7; break; case CS8: default: lcr |= UART_LCR_WLEN8; break; } ier = readb(&ch->ch_neo_uart->ier); uart_lcr = readb(&ch->ch_neo_uart->lcr); if (baud == 0) baud = 9600; quot = ch->ch_bd->bd_dividend / baud; if (quot != 0) { ch->ch_old_baud = baud; writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); writeb((quot & 0xff), &ch->ch_neo_uart->txrx); writeb((quot >> 8), &ch->ch_neo_uart->ier); writeb(lcr, &ch->ch_neo_uart->lcr); }