summaryrefslogtreecommitdiffstats
path: root/drivers/staging/dgnc
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-01-15 21:00:00 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-01-17 15:02:55 +0100
commit945d2a60b5d041ffb35b332af0eeca8ed690deaa (patch)
treec6daccd74b292eafe482b9e6ac891e8d7a5eafa4 /drivers/staging/dgnc
parent2238965f42d62184af01c3d38d575b8395fca1aa (diff)
staging: dgnc: delete dgnc_neo.* files
As the Neo devices were never actually supported by the driver, delete the files that purported to control that type of device as they are not needed. This will let us shrink the driver a lot over time. Cc: Lidza Louina <lidza.louina@gmail.com> Cc: Mark Hounschell <markh@compro.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/dgnc')
-rw-r--r--drivers/staging/dgnc/Makefile1
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c1
-rw-r--r--drivers/staging/dgnc/dgnc_neo.c1681
-rw-r--r--drivers/staging/dgnc/dgnc_neo.h166
-rw-r--r--drivers/staging/dgnc/dgnc_tty.c1
5 files changed, 0 insertions, 1850 deletions
diff --git a/drivers/staging/dgnc/Makefile b/drivers/staging/dgnc/Makefile
index 818e2ea3d1b0..49633042fcc9 100644
--- a/drivers/staging/dgnc/Makefile
+++ b/drivers/staging/dgnc/Makefile
@@ -1,5 +1,4 @@
obj-$(CONFIG_DGNC) += dgnc.o
dgnc-objs := dgnc_cls.o dgnc_driver.o\
- dgnc_neo.o\
dgnc_tty.o
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
index e27794b133b4..a6a4119f083b 100644
--- a/drivers/staging/dgnc/dgnc_driver.c
+++ b/drivers/staging/dgnc/dgnc_driver.c
@@ -13,7 +13,6 @@
#include "dgnc_pci.h"
#include "dgnc_tty.h"
#include "dgnc_cls.h"
-#include "dgnc_neo.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Digi International, http://www.digi.com");
diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c
deleted file mode 100644
index ced1c22f0d0c..000000000000
--- a/drivers/staging/dgnc/dgnc_neo.c
+++ /dev/null
@@ -1,1681 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2003 Digi International (www.digi.com)
- * Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/serial.h>
-#include <linux/serial_reg.h>
-
-#include "dgnc_driver.h"
-#include "dgnc_neo.h"
-#include "dgnc_tty.h"
-
-static inline void neo_parse_lsr(struct dgnc_board *brd, uint port);
-static inline void neo_parse_isr(struct dgnc_board *brd, uint port);
-static void neo_copy_data_from_uart_to_queue(struct channel_t *ch);
-static inline void neo_clear_break(struct channel_t *ch, int force);
-static inline void neo_set_cts_flow_control(struct channel_t *ch);
-static inline void neo_set_rts_flow_control(struct channel_t *ch);
-static inline void neo_set_ixon_flow_control(struct channel_t *ch);
-static inline void neo_set_ixoff_flow_control(struct channel_t *ch);
-static inline void neo_set_no_output_flow_control(struct channel_t *ch);
-static inline void neo_set_no_input_flow_control(struct channel_t *ch);
-static inline void neo_set_new_start_stop_chars(struct channel_t *ch);
-static void neo_parse_modem(struct channel_t *ch, unsigned char signals);
-static void neo_tasklet(unsigned long data);
-static void neo_vpd(struct dgnc_board *brd);
-static void neo_uart_init(struct channel_t *ch);
-static void neo_uart_off(struct channel_t *ch);
-static int neo_drain(struct tty_struct *tty, uint seconds);
-static void neo_param(struct tty_struct *tty);
-static void neo_assert_modem_signals(struct channel_t *ch);
-static void neo_flush_uart_write(struct channel_t *ch);
-static void neo_flush_uart_read(struct channel_t *ch);
-static void neo_disable_receiver(struct channel_t *ch);
-static void neo_enable_receiver(struct channel_t *ch);
-static void neo_send_break(struct channel_t *ch, int msecs);
-static void neo_send_start_character(struct channel_t *ch);
-static void neo_send_stop_character(struct channel_t *ch);
-static void neo_copy_data_from_queue_to_uart(struct channel_t *ch);
-static uint neo_get_uart_bytes_left(struct channel_t *ch);
-static void neo_send_immediate_char(struct channel_t *ch, unsigned char c);
-static irqreturn_t neo_intr(int irq, void *voidbrd);
-
-struct board_ops dgnc_neo_ops = {
- .tasklet = neo_tasklet,
- .intr = neo_intr,
- .uart_init = neo_uart_init,
- .uart_off = neo_uart_off,
- .drain = neo_drain,
- .param = neo_param,
- .vpd = neo_vpd,
- .assert_modem_signals = neo_assert_modem_signals,
- .flush_uart_write = neo_flush_uart_write,
- .flush_uart_read = neo_flush_uart_read,
- .disable_receiver = neo_disable_receiver,
- .enable_receiver = neo_enable_receiver,
- .send_break = neo_send_break,
- .send_start_character = neo_send_start_character,
- .send_stop_character = neo_send_stop_character,
- .copy_data_from_queue_to_uart = neo_copy_data_from_queue_to_uart,
- .get_uart_bytes_left = neo_get_uart_bytes_left,
- .send_immediate_char = neo_send_immediate_char
-};
-
-/*
- * This function allows calls to ensure that all outstanding
- * PCI writes have been completed, by doing a PCI read against
- * a non-destructive, read-only location on the Neo card.
- *
- * In this case, we are reading the DVID (Read-only Device Identification)
- * value of the Neo card.
- */
-static inline void neo_pci_posting_flush(struct dgnc_board *bd)
-{
- readb(bd->re_map_membase + 0x8D);
-}
-
-static inline void neo_set_cts_flow_control(struct channel_t *ch)
-{
- unsigned char ier = readb(&ch->ch_neo_uart->ier);
- unsigned char efr = readb(&ch->ch_neo_uart->efr);
-
- /* Turn on auto CTS flow control */
- ier |= UART_17158_IER_CTSDSR;
- efr |= (UART_17158_EFR_ECB | UART_17158_EFR_CTSDSR);
-
- /* Turn off auto Xon flow control */
- efr &= ~UART_17158_EFR_IXON;
-
- /*
- * Why? Because Exar's spec says we have to zero it
- * out before setting it
- */
- writeb(0, &ch->ch_neo_uart->efr);
-
- /* Turn on UART enhanced bits */
- writeb(efr, &ch->ch_neo_uart->efr);
-
- /* Turn on table D, with 8 char hi/low watermarks */
- writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY,
- &ch->ch_neo_uart->fctr);
-
- /* Feed the UART our trigger levels */
- writeb(8, &ch->ch_neo_uart->tfifo);
- ch->ch_t_tlevel = 8;
-
- writeb(ier, &ch->ch_neo_uart->ier);
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-static inline void neo_set_rts_flow_control(struct channel_t *ch)
-{
- unsigned char ier = readb(&ch->ch_neo_uart->ier);
- unsigned char efr = readb(&ch->ch_neo_uart->efr);
-
- /* Turn on auto RTS flow control */
- ier |= UART_17158_IER_RTSDTR;
- efr |= (UART_17158_EFR_ECB | UART_17158_EFR_RTSDTR);
-
- /* Turn off auto Xoff flow control */
- ier &= ~UART_17158_IER_XOFF;
- efr &= ~UART_17158_EFR_IXOFF;
-
- /*
- * Why? Because Exar's spec says we have to zero it
- * out before setting it
- */
- writeb(0, &ch->ch_neo_uart->efr);
-
- /* Turn on UART enhanced bits */
- writeb(efr, &ch->ch_neo_uart->efr);
-
- writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY,
- &ch->ch_neo_uart->fctr);
- ch->ch_r_watermark = 4;
-
- writeb(32, &ch->ch_neo_uart->rfifo);
- ch->ch_r_tlevel = 32;
-
- writeb(ier, &ch->ch_neo_uart->ier);
-
- /*
- * From the Neo UART spec sheet:
- * The auto RTS/DTR function must be started by asserting
- * RTS/DTR# output pin (MCR bit-0 or 1 to logic 1 after
- * it is enabled.
- */
- ch->ch_mostat |= UART_MCR_RTS;
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-static inline void neo_set_ixon_flow_control(struct channel_t *ch)
-{
- unsigned char ier = readb(&ch->ch_neo_uart->ier);
- unsigned char efr = readb(&ch->ch_neo_uart->efr);
-
- /* Turn off auto CTS flow control */
- ier &= ~UART_17158_IER_CTSDSR;
- efr &= ~UART_17158_EFR_CTSDSR;
-
- /* Turn on auto Xon flow control */
- efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXON);
-
- /*
- * Why? Because Exar's spec says we have to zero it
- * out before setting it
- */
- writeb(0, &ch->ch_neo_uart->efr);
-
- /* Turn on UART enhanced bits */
- writeb(efr, &ch->ch_neo_uart->efr);
-
- writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY,
- &ch->ch_neo_uart->fctr);
- ch->ch_r_watermark = 4;
-
- writeb(32, &ch->ch_neo_uart->rfifo);
- ch->ch_r_tlevel = 32;
-
- /* Tell UART what start/stop chars it should be looking for */
- writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
- writeb(0, &ch->ch_neo_uart->xonchar2);
-
- writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1);
- writeb(0, &ch->ch_neo_uart->xoffchar2);
-
- writeb(ier, &ch->ch_neo_uart->ier);
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-static inline void neo_set_ixoff_flow_control(struct channel_t *ch)
-{
- unsigned char ier = readb(&ch->ch_neo_uart->ier);
- unsigned char efr = readb(&ch->ch_neo_uart->efr);
-
- /* Turn off auto RTS flow control */
- ier &= ~UART_17158_IER_RTSDTR;
- efr &= ~UART_17158_EFR_RTSDTR;
-
- /* Turn on auto Xoff flow control */
- ier |= UART_17158_IER_XOFF;
- efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXOFF);
-
- /*
- * Why? Because Exar's spec says we have to zero it
- * out before setting it
- */
- writeb(0, &ch->ch_neo_uart->efr);
-
- /* Turn on UART enhanced bits */
- writeb(efr, &ch->ch_neo_uart->efr);
-
- /* Turn on table D, with 8 char hi/low watermarks */
- writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY,
- &ch->ch_neo_uart->fctr);
-
- writeb(8, &ch->ch_neo_uart->tfifo);
- ch->ch_t_tlevel = 8;
-
- /* Tell UART what start/stop chars it should be looking for */
- writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
- writeb(0, &ch->ch_neo_uart->xonchar2);
-
- writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1);
- writeb(0, &ch->ch_neo_uart->xoffchar2);
-
- writeb(ier, &ch->ch_neo_uart->ier);
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-static inline void neo_set_no_input_flow_control(struct channel_t *ch)
-{
- unsigned char ier = readb(&ch->ch_neo_uart->ier);
- unsigned char efr = readb(&ch->ch_neo_uart->efr);
-
- /* Turn off auto RTS flow control */
- ier &= ~UART_17158_IER_RTSDTR;
- efr &= ~UART_17158_EFR_RTSDTR;
-
- /* Turn off auto Xoff flow control */
- ier &= ~UART_17158_IER_XOFF;
- if (ch->ch_c_iflag & IXON)
- efr &= ~(UART_17158_EFR_IXOFF);
- else
- efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXOFF);
-
- /*
- * Why? Because Exar's spec says we have to zero
- * it out before setting it
- */
- writeb(0, &ch->ch_neo_uart->efr);
-
- /* Turn on UART enhanced bits */
- writeb(efr, &ch->ch_neo_uart->efr);
-
- /* Turn on table D, with 8 char hi/low watermarks */
- writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY,
- &ch->ch_neo_uart->fctr);
-
- ch->ch_r_watermark = 0;
-
- writeb(16, &ch->ch_neo_uart->tfifo);
- ch->ch_t_tlevel = 16;
-
- writeb(16, &ch->ch_neo_uart->rfifo);
- ch->ch_r_tlevel = 16;
-
- writeb(ier, &ch->ch_neo_uart->ier);
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-static inline void neo_set_no_output_flow_control(struct channel_t *ch)
-{
- unsigned char ier = readb(&ch->ch_neo_uart->ier);
- unsigned char efr = readb(&ch->ch_neo_uart->efr);
-
- /* Turn off auto CTS flow control */
- ier &= ~UART_17158_IER_CTSDSR;
- efr &= ~UART_17158_EFR_CTSDSR;
-
- /* Turn off auto Xon flow control */
- if (ch->ch_c_iflag & IXOFF)
- efr &= ~UART_17158_EFR_IXON;
- else
- efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXON);
-
- /*
- * Why? Because Exar's spec says we have to zero it
- * out before setting it
- */
- writeb(0, &ch->ch_neo_uart->efr);
-
- /* Turn on UART enhanced bits */
- writeb(efr, &ch->ch_neo_uart->efr);
-
- /* Turn on table D, with 8 char hi/low watermarks */
- writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY,
- &ch->ch_neo_uart->fctr);
-
- ch->ch_r_watermark = 0;
-
- writeb(16, &ch->ch_neo_uart->tfifo);
- ch->ch_t_tlevel = 16;
-
- writeb(16, &ch->ch_neo_uart->rfifo);
- ch->ch_r_tlevel = 16;
-
- writeb(ier, &ch->ch_neo_uart->ier);
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-/* change UARTs start/stop chars */
-static inline void neo_set_new_start_stop_chars(struct channel_t *ch)
-{
- /* if hardware flow control is set, then skip this whole thing */
- if (ch->ch_digi.digi_flags & (CTSPACE | RTSPACE) ||
- ch->ch_c_cflag & CRTSCTS)
- return;
-
- /* Tell UART what start/stop chars it should be looking for */
- writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
- writeb(0, &ch->ch_neo_uart->xonchar2);
-
- writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1);
- writeb(0, &ch->ch_neo_uart->xoffchar2);
-
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-/* No locks are assumed to be held when calling this function. */
-static inline void neo_clear_break(struct channel_t *ch, int force)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ch->ch_lock, flags);
-
- if (!ch->ch_stop_sending_break) {
- spin_unlock_irqrestore(&ch->ch_lock, flags);
- return;
- }
-
- if (ch->ch_flags & CH_BREAK_SENDING) {
- if (force ||
- time_after_eq(jiffies, ch->ch_stop_sending_break)) {
- unsigned char temp = readb(&ch->ch_neo_uart->lcr);
-
- writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr);
- neo_pci_posting_flush(ch->ch_bd);
- ch->ch_flags &= ~(CH_BREAK_SENDING);
- ch->ch_stop_sending_break = 0;
- }
- }
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Parse the ISR register. */
-static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
-{
- struct channel_t *ch;
- unsigned char isr;
- unsigned char cause;
- unsigned long flags;
-
- ch = brd->channels[port];
- if (!ch)
- return;
-
- /* Here we try to figure out what caused the interrupt to happen */
- while (1) {
- isr = readb(&ch->ch_neo_uart->isr_fcr);
-
- if (isr & UART_IIR_NO_INT)
- break;
-
- /*
- * Yank off the upper 2 bits,
- * which just show that the FIFO's are enabled.
- */
- isr &= ~(UART_17158_IIR_FIFO_ENABLED);
-
- if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) {
- /* Read data from uart -> queue */
- neo_copy_data_from_uart_to_queue(ch);
- /*
- * Call our tty layer to enforce queue
- * flow control if needed.
- */
- spin_lock_irqsave(&ch->ch_lock, flags);
- dgnc_check_queue_flow_control(ch);
- spin_unlock_irqrestore(&ch->ch_lock, flags);
- }
-
- if (isr & UART_IIR_THRI) {
- spin_lock_irqsave(&ch->ch_lock, flags);
- ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
- spin_unlock_irqrestore(&ch->ch_lock, flags);
- neo_copy_data_from_queue_to_uart(ch);
- }
-
- if (isr & UART_17158_IIR_XONXOFF) {
- cause = readb(&ch->ch_neo_uart->xoffchar1);
-
- /*
- * Since the UART detected either an XON or
- * XOFF match, we need to figure out which
- * one it was, so we can suspend or resume data flow.
- */
- if (cause == UART_17158_XON_DETECT) {
- /* resume output if stopped */
- if (brd->channels[port]->ch_flags & CH_STOP) {
- spin_lock_irqsave(&ch->ch_lock,
- flags);
- ch->ch_flags &= ~(CH_STOP);
- spin_unlock_irqrestore(&ch->ch_lock,
- flags);
- }
- } else if (cause == UART_17158_XOFF_DETECT) {
- if (!(brd->channels[port]->ch_flags &
- CH_STOP)) {
- spin_lock_irqsave(&ch->ch_lock,
- flags);
- ch->ch_flags |= CH_STOP;
- spin_unlock_irqrestore(&ch->ch_lock,
- flags);
- }
- }
- }
-
- if (isr & UART_17158_IIR_HWFLOW_STATE_CHANGE) {
- /*
- * If we get here, this means the hardware is
- * doing auto flow control. Check to see whether
- * RTS/DTR or CTS/DSR caused this interrupt.
- */
- cause = readb(&ch->ch_neo_uart->mcr);
- /* Which pin is doing auto flow? RTS or DTR? */
- if ((cause & 0x4) == 0) {
- if (cause & UART_MCR_RTS) {
- spin_lock_irqsave(&ch->ch_lock,
- flags);
- ch->ch_mostat |= UART_MCR_RTS;
- spin_unlock_irqrestore(&ch->ch_lock,
- flags);
- } else {
- spin_lock_irqsave(&ch->ch_lock,
- flags);
- ch->ch_mostat &= ~(UART_MCR_RTS);
- spin_unlock_irqrestore(&ch->ch_lock,
- flags);
- }
- } else {
- if (cause & UART_MCR_DTR) {
- spin_lock_irqsave(&ch->ch_lock,
- flags);
- ch->ch_mostat |= UART_MCR_DTR;
- spin_unlock_irqrestore(&ch->ch_lock,
- flags);
- } else {
- spin_lock_irqsave(&ch->ch_lock,
- flags);
- ch->ch_mostat &= ~(UART_MCR_DTR);
- spin_unlock_irqrestore(&ch->ch_lock,
- flags);
- }
- }
- }
-
- neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr));
- }
-}
-
-static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
-{
- struct channel_t *ch;
- int linestatus;
- unsigned long flags;
-
- if (!brd)
- return;
-
- if (port >= brd->maxports)
- return;
-
- ch = brd->channels[port];
- if (!ch)
- return;
-
- linestatus = readb(&ch->ch_neo_uart->lsr);
-
- ch->ch_cached_lsr |= linestatus;
-
- if (ch->ch_cached_lsr & UART_LSR_DR) {
- neo_copy_data_from_uart_to_queue(ch);
- spin_lock_irqsave(&ch->ch_lock, flags);
- dgnc_check_queue_flow_control(ch);
- spin_unlock_irqrestore(&ch->ch_lock, flags);
- }
-
- /*
- * The next 3 tests should *NOT* happen, as the above test
- * should encapsulate all 3... At least, thats what Exar says.
- */
-
- if (linestatus & UART_LSR_PE)
- ch->ch_err_parity++;
-
- if (linestatus & UART_LSR_FE)
- ch->ch_err_frame++;
-
- if (linestatus & UART_LSR_BI)
- ch->ch_err_break++;
-
- if (linestatus & UART_LSR_OE) {
- /*
- * Rx Oruns. Exar says that an orun will NOT corrupt
- * the FIFO. It will just replace the holding register
- * with this new data byte. So basically just ignore this.
- * Probably we should eventually have an orun stat in our
- * driver...
- */
- ch->ch_err_overrun++;
- }
-
- if (linestatus & UART_LSR_THRE) {
- spin_lock_irqsave(&ch->ch_lock, flags);
- ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-
- neo_copy_data_from_queue_to_uart(ch);
- } else if (linestatus & UART_17158_TX_AND_FIFO_CLR) {
- spin_lock_irqsave(&ch->ch_lock, flags);
- ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-
- neo_copy_data_from_queue_to_uart(ch);
- }
-}
-
-/* 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)
- return;
-
- un = (struct un_t *)tty->driver_data;
- if (!un)
- return;
-
- ch = un->un_ch;
- if (!ch)
- return;
-
- 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 = 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;
-
-#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);
- }
-
- if (uart_lcr != lcr)
- writeb(lcr, &ch->ch_neo_uart->lcr);
-
- if (ch->ch_c_cflag & CREAD)
- ier |= (UART_IER_RDI | UART_IER_RLSI);
- else
- ier &= ~(UART_IER_RDI | UART_IER_RLSI);
-
- /*
- * Have the UART interrupt on modem signal changes ONLY when
- * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set.
- */
- if ((ch->ch_digi.digi_flags & CTSPACE) ||
- (ch->ch_digi.digi_flags & RTSPACE) ||
- (ch->ch_c_cflag & CRTSCTS) ||
- !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
- !(ch->ch_c_cflag & CLOCAL))
- ier |= UART_IER_MSI;
- else
- ier &= ~UART_IER_MSI;
-
- ier |= UART_IER_THRI;
-
- if (ier != uart_ier)
- writeb(ier, &ch->ch_neo_uart->ier);
-
- neo_set_new_start_stop_chars(ch);
-
- if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
- neo_set_cts_flow_control(ch);
- } else if (ch->ch_c_iflag & IXON) {
- if ((ch->ch_startc == _POSIX_VDISABLE) ||
- (ch->ch_stopc == _POSIX_VDISABLE))
- neo_set_no_output_flow_control(ch);
- else
- neo_set_ixon_flow_control(ch);
- } else {
- neo_set_no_output_flow_control(ch);
- }
-
- if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
- neo_set_rts_flow_control(ch);
- } else if (ch->ch_c_iflag & IXOFF) {
- if ((ch->ch_startc == _POSIX_VDISABLE) ||
- (ch->ch_stopc == _POSIX_VDISABLE))
- neo_set_no_input_flow_control(ch);
- else
- neo_set_ixoff_flow_control(ch);
- } else {
- neo_set_no_input_flow_control(ch);
- }
-
- /*
- * Adjust the RX FIFO Trigger level if baud is less than 9600.
- * Not exactly elegant, but this is needed because of the Exar chip's
- * delay on firing off the RX FIFO interrupt on slower baud rates.
- */
- if (baud < 9600) {
- writeb(1, &ch->ch_neo_uart->rfifo);
- ch->ch_r_tlevel = 1;
- }
-
- neo_assert_modem_signals(ch);
-
- neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr));
-}
-
-/* Board poller function. */
-static void neo_tasklet(unsigned long data)
-{
- struct dgnc_board *bd = (struct dgnc_board *)data;
- struct channel_t *ch;
- unsigned long flags;
- int i;
- int state = 0;
- int ports = 0;
-
- if (!bd)
- return;
-
- spin_lock_irqsave(&bd->bd_lock, flags);
- state = bd->state;
- ports = bd->nasync;
- spin_unlock_irqrestore(&bd->bd_lock, flags);
-
- /*
- * Do NOT allow the interrupt routine to read the intr registers
- * Until we release this lock.
- */
- spin_lock_irqsave(&bd->bd_intr_lock, flags);
-
- if ((state == BOARD_READY) && (ports > 0)) {
- for (i = 0; i < ports; i++) {
- ch = bd->channels[i];
- if (!ch)
- continue;
-
- /*
- * NOTE: Remember you CANNOT hold any channel
- * locks when calling the input routine.
- *
- * During input processing, its possible we
- * will call the Linux ld, which might in turn,
- * do a callback right back into us, resulting
- * in us trying to grab the channel lock twice!
- */
- dgnc_input(ch);
-
- /*
- * Channel lock is grabbed and then released
- * inside both of these routines, but neither
- * call anything else that could call back into us.
- */
- neo_copy_data_from_queue_to_uart(ch);
- dgnc_wakeup_writes(ch);
-
- dgnc_carrier(ch);
-
- /*
- * Check to see if we need to turn off a sending break.
- * The timing check is done inside clear_break()
- */
- if (ch->ch_stop_sending_break)
- neo_clear_break(ch, 0);
- }
- }
-
- spin_unlock_irqrestore(&bd->bd_intr_lock, flags);
-}
-
-/* Neo specific interrupt handler. */
-static irqreturn_t neo_intr(int irq, void *voidbrd)
-{
- struct dgnc_board *brd = voidbrd;
- struct channel_t *ch;
- int port = 0;
- int type;
- u32 uart_poll;
- unsigned long flags;
- unsigned long flags2;
-
- if (!brd)
- return IRQ_NONE;
-
- /* Lock out the slow poller from running on this board. */
- spin_lock_irqsave(&brd->bd_intr_lock, flags);
-
- /*
- * Read in "extended" IRQ information from the 32bit Neo register.
- * Bits 0-7: What port triggered the interrupt.
- * Bits 8-31: Each 3bits indicate what type of interrupt occurred.
- */
- uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET);
-
- /*
- * If 0, no interrupts pending.
- * This can happen if the IRQ is shared among a couple Neo/Classic
- * boards.
- */
- if (!uart_poll) {
- spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
- return IRQ_NONE;
- }
-
- while ((uart_poll & 0xff) != 0) {
- type = uart_poll >> (8 + (port * 3));
- type &= 0x7;
-
- uart_poll &= ~(0x01 << port);
-
- switch (type) {
- case UART_17158_RXRDY_TIMEOUT:
- /*
- * RXRDY Time-out is cleared by reading data in the
- * RX FIFO until it falls below the trigger level.
- */
-
- if (port >= brd->nasync)
- break;
-
- ch = brd->channels[port];
- neo_copy_data_from_uart_to_queue(ch);
-
- /*
- * Call our tty layer to enforce queue flow control if
- * needed.
- */
- spin_lock_irqsave(&ch->ch_lock, flags2);
- dgnc_check_queue_flow_control(ch);
- spin_unlock_irqrestore(&ch->ch_lock, flags2);
-
- break;
-
- case UART_17158_RX_LINE_STATUS:
-
- /* RXRDY and RX LINE Status (logic OR of LSR[4:1]) */
-
- neo_parse_lsr(brd, port);
- break;
-
- case UART_17158_TXRDY:
- /*
- * TXRDY interrupt clears after reading ISR register
- * for the UART channel.
- */
-
- /*
- * Yes, this is odd...
- * Why would I check EVERY possibility of type of
- * interrupt, when we know its TXRDY???
- * Becuz for some reason, even tho we got triggered for
- * TXRDY, it seems to be occasionally wrong. Instead of
- * TX, which it should be, I was getting things like
- * RXDY too. Weird.
- */
- neo_parse_isr(brd, port);
- break;
-
- case UART_17158_MSR:
- /* MSR or flow control was seen. */
- neo_parse_isr(brd, port);
- break;
-
- default:
- break;
- }
-
- port++;
- }
-
- tasklet_schedule(&brd->helper_tasklet);
-
- spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Neo specific way of turning off the receiver.
- * Used as a way to enforce queue flow control when in
- * hardware flow control mode.
- */
-static void neo_disable_receiver(struct channel_t *ch)
-{
- unsigned char tmp = readb(&ch->ch_neo_uart->ier);
-
- tmp &= ~(UART_IER_RDI);
- writeb(tmp, &ch->ch_neo_uart->ier);
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-/*
- * Neo specific way of turning on the receiver.
- * Used as a way to un-enforce queue flow control when in
- * hardware flow control mode.
- */
-static void neo_enable_receiver(struct channel_t *ch)
-{
- unsigned char tmp = readb(&ch->ch_neo_uart->ier);
-
- tmp |= (UART_IER_RDI);
- writeb(tmp, &ch->ch_neo_uart->ier);
- neo_pci_posting_flush(ch->ch_bd);
-}
-
-static void neo_copy_data_from_uart_to_queue(struct channel_t *ch)
-{
- int qleft = 0;
- unsigned char linestatus = 0;
- unsigned char error_mask = 0;
- int n = 0;
- int total = 0;
- ushort head;
- ushort tail;
- unsigned long flags;
-
- if (!ch)
- return;
-
- spin_lock_irqsave(&ch->ch_lock, flags);
-
- head = ch->ch_r_head & RQUEUEMASK;
- tail = ch->ch_r_tail & RQUEUEMASK;
-
- linestatus = ch->ch_cached_lsr;
- ch->ch_cached_lsr = 0;
-
- qleft = tail - head - 1;
- if (qleft < 0)
- qleft += RQUEUEMASK + 1;
-
- if (!(ch->ch_flags & CH_FIFO_ENABLED)) {
- /* force the FIFO copy to NOT be run */
- total = 0;
- } else {
- total = readb(&ch->ch_neo_uart->rfifo);
-
- /*
- * EXAR chip bug - RX FIFO COUNT - Fudge factor.
- *
- * This resolves a problem/bug with the Exar chip that sometimes
- * returns a bogus value in the rfifo register.
- * The count can be any where from 0-3 bytes "off".
- * Bizarre, but true.
- */
- if ((ch->ch_bd->dvid & 0xf0) >= UART_XR17E158_DVID)
- total -= 1;
- else
- total -= 3;
- }
-
- total = min(total, qleft);
-
- while (total > 0) {
- linestatus = readb(&ch->ch_neo_uart->lsr);
-
- if (linestatus & UART_17158_RX_FIFO_DATA_ERROR)
- break;
-
- /* Make sure we don't go over the end of our queue */
- n = min(((uint)total), (RQUEUESIZE - (uint)head));
-
- /*
- * Cut down n even further if needed, this is to fix
- * a problem with memcpy_fromio() with the Neo on the
- * IBM pSeries platform.
- * 15 bytes max appears to be the magic number.
- */
- n = min_t(uint, n, 12);
-
- /*
- * Since we are grabbing the linestatus register, which
- * will reset some bits after our read, we need to ensure
- * we don't miss our TX FIFO emptys.
- */
- if (linestatus & (UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR))
- ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-
- linestatus = 0;
-
- memcpy_fromio(ch->ch_rqueue + head,
- &ch->ch_neo_uart->txrxburst, n);
-
- /*
- * Since RX_FIFO_DATA_ERROR was 0, we are guaranteed
- * that all the data currently in the FIFO is free of
- * breaks and parity/frame/orun errors.
- */
- memset(ch->ch_equeue + head, 0, n);
-
- head = (head + n) & RQUEUEMASK;
- total -= n;
- qleft -= n;
- ch->ch_rxcount += n;
- }
-
- /*
- * Create a mask to determine whe