void jsm_input(struct jsm_channel *ch) { struct jsm_board *bd; struct tty_struct *tp; u32 rmask; u16 head; u16 tail; int data_len; unsigned long lock_flags; int len = 0; int n = 0; int s = 0; int i = 0; jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); if (!ch) return; tp = ch->uart_port.state->port.tty; bd = ch->ch_bd; if(!bd) return; spin_lock_irqsave(&ch->ch_lock, lock_flags); /* *Figure the number of characters in the buffer. *Exit immediately if none. */ rmask = RQUEUEMASK; head = ch->ch_r_head & rmask; tail = ch->ch_r_tail & rmask; data_len = (head - tail) & rmask; if (data_len == 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); return; } jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); /* *If the device is not open, or CREAD is off, flush *input data and return immediately. */ if (!tp || !(tp->termios->c_cflag & CREAD) ) { jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); ch->ch_r_head = tail; /* Force queue flow control to be released, if needed */ jsm_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); return; } /* * If we are throttled, simply don't read any data. */ if (ch->ch_flags & CH_STOPI) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Port %d throttled, not reading any data. head: %x tail: %x\n", ch->ch_portnum, head, tail); return; } jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n"); if (data_len <= 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); return; } len = tty_buffer_request_room(tp, data_len); n = len; /* * n now contains the most amount of data we can copy, * bounded either by the flip buffer size or the amount * of data the card actually has pending... */ while (n) { s = ((head >= tail) ? head : RQUEUESIZE) - tail; s = min(s, n); if (s <= 0) break; /* * If conditions are such that ld needs to see all * UART errors, we will have to walk each character * and error byte and send them to the buffer one at * a time. */ if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { for (i = 0; i < s; i++) { /* * Give the Linux ld the flags in the * format it likes. */ if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK); else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY); else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); else tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); } } else { tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; } tail += s; n -= s; /* Flip queue if needed */ tail &= rmask; } ch->ch_r_tail = tail & rmask; ch->ch_e_tail = tail & rmask; jsm_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); /* Tell the tty layer its okay to "eat" the data now */ tty_flip_buffer_push(tp); jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); }
/* * Parse the ISR register. */ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) { struct jsm_channel *ch; u8 isr; u8 cause; unsigned long lock_flags; if (!brd) return; if (port > brd->maxports) return; 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); /* Bail if no pending interrupt */ 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); jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "%s:%d isr: %x\n", __FILE__, __LINE__, isr); 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, lock_flags); jsm_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } if (isr & UART_IIR_THRI) { /* Transfer data (if any) from Write Queue -> UART. */ spin_lock_irqsave(&ch->ch_lock, lock_flags); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); neo_copy_data_from_queue_to_uart(ch); } if (isr & UART_17158_IIR_XONXOFF) { cause = readb(&ch->ch_neo_uart->xoffchar1); jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "Port %d. Got ISR_XONXOFF: cause:%x\n", port, cause); /* * 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. */ spin_lock_irqsave(&ch->ch_lock, lock_flags); if (cause == UART_17158_XON_DETECT) { /* Is output stopped right now, if so, resume it */ if (brd->channels[port]->ch_flags & CH_STOP) { ch->ch_flags &= ~(CH_STOP); } jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "Port %d. XON detected in incoming data\n", port); } else if (cause == UART_17158_XOFF_DETECT) { if (!(brd->channels[port]->ch_flags & CH_STOP)) { ch->ch_flags |= CH_STOP; jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "Setting CH_STOP\n"); } jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "Port: %d. XOFF detected in incoming data\n", port); } spin_unlock_irqrestore(&ch->ch_lock, 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? */ spin_lock_irqsave(&ch->ch_lock, lock_flags); if ((cause & 0x4) == 0) { if (cause & UART_MCR_RTS) ch->ch_mostat |= UART_MCR_RTS; else ch->ch_mostat &= ~(UART_MCR_RTS); } else { if (cause & UART_MCR_DTR) ch->ch_mostat |= UART_MCR_DTR; else ch->ch_mostat &= ~(UART_MCR_DTR); } spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } /* Parse any modem signal changes */ jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "MOD_STAT: sending to parse_modem_sigs\n"); neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); } }
static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) { struct jsm_channel *ch; int linestatus; unsigned long lock_flags; if (!brd) return; if (port > brd->maxports) return; ch = brd->channels[port]; if (!ch) return; linestatus = readb(&ch->ch_neo_uart->lsr); jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, "%s:%d port: %d linestatus: %x\n", __FILE__, __LINE__, port, linestatus); ch->ch_cached_lsr |= linestatus; if (ch->ch_cached_lsr & UART_LSR_DR) { /* Read data from uart -> queue */ neo_copy_data_from_uart_to_queue(ch); spin_lock_irqsave(&ch->ch_lock, lock_flags); jsm_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } /* * This is a special flag. It indicates that at least 1 * RX error (parity, framing, or break) has happened. * Mark this in our struct, which will tell me that I have *to do the special RX+LSR read for this FIFO load. */ if (linestatus & UART_17158_RX_FIFO_DATA_ERROR) jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, "%s:%d Port: %d Got an RX error, need to parse LSR\n", __FILE__, __LINE__, port); /* * 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++; jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, "%s:%d Port: %d. PAR ERR!\n", __FILE__, __LINE__, port); } if (linestatus & UART_LSR_FE) { ch->ch_err_frame++; jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, "%s:%d Port: %d. FRM ERR!\n", __FILE__, __LINE__, port); } if (linestatus & UART_LSR_BI) { ch->ch_err_break++; jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, "%s:%d Port: %d. BRK INTR!\n", __FILE__, __LINE__, port); } 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++; jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, "%s:%d Port: %d. Rx Overrun!\n", __FILE__, __LINE__, port); } if (linestatus & UART_LSR_THRE) { spin_lock_irqsave(&ch->ch_lock, lock_flags); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); /* Transfer data (if any) from Write Queue -> UART. */ neo_copy_data_from_queue_to_uart(ch); } else if (linestatus & UART_17158_TX_AND_FIFO_CLR) { spin_lock_irqsave(&ch->ch_lock, lock_flags); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); /* Transfer data (if any) from Write Queue -> UART. */ neo_copy_data_from_queue_to_uart(ch); } }
void jsm_input(struct jsm_channel *ch) { struct jsm_board *bd; struct tty_struct *tp; u32 rmask; u16 head; u16 tail; int data_len; unsigned long lock_flags; int flip_len; int len = 0; int n = 0; char *buf = NULL; char *buf2 = NULL; int s = 0; int i = 0; jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); if (!ch) return; tp = ch->uart_port.info->tty; bd = ch->ch_bd; if(!bd) return; spin_lock_irqsave(&ch->ch_lock, lock_flags); /* *Figure the number of characters in the buffer. *Exit immediately if none. */ rmask = RQUEUEMASK; head = ch->ch_r_head & rmask; tail = ch->ch_r_tail & rmask; data_len = (head - tail) & rmask; if (data_len == 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); return; } jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); /* *If the device is not open, or CREAD is off, flush *input data and return immediately. */ if (!tp || !(tp->termios->c_cflag & CREAD) ) { jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); ch->ch_r_head = tail; /* Force queue flow control to be released, if needed */ jsm_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); return; } /* * If we are throttled, simply don't read any data. */ if (ch->ch_flags & CH_STOPI) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Port %d throttled, not reading any data. head: %x tail: %x\n", ch->ch_portnum, head, tail); return; } jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n"); /* * If the rxbuf is empty and we are not throttled, put as much * as we can directly into the linux TTY flip buffer. * The jsm_rawreadok case takes advantage of carnal knowledge that * the char_buf and the flag_buf are next to each other and * are each of (2 * TTY_FLIPBUF_SIZE) size. * * NOTE: if(!tty->real_raw), the call to ldisc.receive_buf *actually still uses the flag buffer, so you can't *use it for input data */ if (jsm_rawreadok) { if (tp->real_raw) flip_len = MYFLIPLEN; else flip_len = 2 * TTY_FLIPBUF_SIZE; } else flip_len = TTY_FLIPBUF_SIZE - tp->flip.count; len = min(data_len, flip_len); len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); if (len <= 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); return; } /* * If we're bypassing flip buffers on rx, we can blast it * right into the beginning of the buffer. */ if (jsm_rawreadok) { if (tp->real_raw) { if (ch->ch_flags & CH_FLIPBUF_IN_USE) { jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "JSM - FLIPBUF in use. delaying input\n"); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); return; } ch->ch_flags |= CH_FLIPBUF_IN_USE; buf = ch->ch_bd->flipbuf; buf2 = NULL; } else { buf = tp->flip.char_buf; buf2 = tp->flip.flag_buf; } } else { buf = tp->flip.char_buf_ptr; buf2 = tp->flip.flag_buf_ptr; } n = len; /* * n now contains the most amount of data we can copy, * bounded either by the flip buffer size or the amount * of data the card actually has pending... */ while (n) { s = ((head >= tail) ? head : RQUEUESIZE) - tail; s = min(s, n); if (s <= 0) break; memcpy(buf, ch->ch_rqueue + tail, s); /* buf2 is only set when port isn't raw */ if (buf2) memcpy(buf2, ch->ch_equeue + tail, s); tail += s; buf += s; if (buf2) buf2 += s; n -= s; /* Flip queue if needed */ tail &= rmask; } /* * In high performance mode, we don't have to update * flag_buf or any of the counts or pointers into flip buf. */ if (!jsm_rawreadok) { if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { for (i = 0; i < len; i++) { /* * Give the Linux ld the flags in the * format it likes. */ if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI) tp->flip.flag_buf_ptr[i] = TTY_BREAK; else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE) tp->flip.flag_buf_ptr[i] = TTY_PARITY; else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE) tp->flip.flag_buf_ptr[i] = TTY_FRAME; else tp->flip.flag_buf_ptr[i] = TTY_NORMAL; } } else { memset(tp->flip.flag_buf_ptr, 0, len); } tp->flip.char_buf_ptr += len; tp->flip.flag_buf_ptr += len; tp->flip.count += len; } else if (!tp->real_raw) { if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { for (i = 0; i < len; i++) { /* * Give the Linux ld the flags in the * format it likes. */ if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI) tp->flip.flag_buf_ptr[i] = TTY_BREAK; else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE) tp->flip.flag_buf_ptr[i] = TTY_PARITY; else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE) tp->flip.flag_buf_ptr[i] = TTY_FRAME; else tp->flip.flag_buf_ptr[i] = TTY_NORMAL; } } else memset(tp->flip.flag_buf, 0, len); } /* * If we're doing raw reads, jam it right into the * line disc bypassing the flip buffers. */ if (jsm_rawreadok) { if (tp->real_raw) { ch->ch_r_tail = tail & rmask; ch->ch_e_tail = tail & rmask; jsm_check_queue_flow_control(ch); /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */ spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input. %d real_raw len:%d calling receive_buf for board %d\n", __LINE__, len, ch->ch_bd->boardnum); tp->ldisc.receive_buf(tp, ch->ch_bd->flipbuf, NULL, len); /* Allow use of channel flip buffer again */ spin_lock_irqsave(&ch->ch_lock, lock_flags); ch->ch_flags &= ~CH_FLIPBUF_IN_USE; spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } else { ch->ch_r_tail = tail & rmask; ch->ch_e_tail = tail & rmask; jsm_check_queue_flow_control(ch); /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */ spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input. %d not real_raw len:%d calling receive_buf for board %d\n", __LINE__, len, ch->ch_bd->boardnum); tp->ldisc.receive_buf(tp, tp->flip.char_buf, tp->flip.flag_buf, len); } } else { ch->ch_r_tail = tail & rmask; ch->ch_e_tail = tail & rmask; jsm_check_queue_flow_control(ch); spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input. %d not jsm_read raw okay scheduling flip\n", __LINE__); tty_schedule_flip(tp); } jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); }