Loading drivers/serial/Kconfig +14 −14 Original line number Diff line number Diff line Loading @@ -893,7 +893,7 @@ config SERIAL_VR41XX_CONSOLE config SERIAL_JSM tristate "Digi International NEO PCI Support" depends on PCI && BROKEN depends on PCI select SERIAL_CORE help This is a driver for Digi International's Neo series Loading drivers/serial/jsm/jsm_tty.c +65 −143 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ * * Contact Information: * Scott H Kilau <Scott_Kilau@digi.com> * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> * * Ananda Venkatarman <mansarov@us.ibm.com> * Modifications: * 01/19/06: changed jsm_input routine to use the dynamically allocated * tty_buffer changes. Contributors: Scott Kilau and Ananda V. ***********************************************************************/ #include <linux/tty.h> #include <linux/tty_flip.h> Loading Loading @@ -497,16 +499,16 @@ void jsm_input(struct jsm_channel *ch) { struct jsm_board *bd; struct tty_struct *tp; struct tty_ldisc *ld; u32 rmask; u16 head; u16 tail; int data_len; unsigned long lock_flags; int flip_len; int flip_len = 0; int len = 0; int n = 0; char *buf = NULL; char *buf2 = NULL; int s = 0; int i = 0; Loading Loading @@ -574,56 +576,50 @@ void jsm_input(struct jsm_channel *ch) /* * 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. * as we can directly into the linux TTY buffer. * * 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; flip_len = TTY_FLIPBUF_SIZE; len = min(data_len, flip_len); len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); ld = tty_ldisc_ref(tp); 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 the DONT_FLIP flag is on, don't flush our buffer, and act * like the ld doesn't have any space to put the data right now. */ if (test_bit(TTY_DONT_FLIP, &tp->flags)) len = 0; /* * If we're bypassing flip buffers on rx, we can blast it * right into the beginning of the buffer. * If we were unable to get a reference to the ld, * don't flush our buffer, and act like the ld doesn't * have any space to put the data right now. */ 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; if (!ld) { len = 0; } else { buf = tp->flip.char_buf; buf2 = tp->flip.flag_buf; /* * If ld doesn't have a pointer to a receive_buf function, * flush the data, then act like the ld doesn't have any * space to put the data right now. */ if (!ld->receive_buf) { ch->ch_r_head = ch->ch_r_tail; len = 0; } } else { buf = tp->flip.char_buf_ptr; buf2 = tp->flip.flag_buf_ptr; } if (len <= 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); if (ld) tty_ldisc_deref(ld); return; } len = tty_buffer_request_room(tp, len); n = len; /* Loading @@ -638,121 +634,47 @@ void jsm_input(struct jsm_channel *ch) 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 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 (!jsm_rawreadok) { if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { for (i = 0; i < len; i++) { for (i = 0; i < s; 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; 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 tp->flip.flag_buf_ptr[i] = TTY_NORMAL; tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +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; tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; } } else memset(tp->flip.flag_buf, 0, len); tail += s; n -= s; /* Flip queue if needed */ tail &= rmask; } /* * 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); /* Tell the tty layer its okay to "eat" the data now */ tty_flip_buffer_push(tp); /* 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); } if (ld) tty_ldisc_deref(ld); jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); } Loading Loading
drivers/serial/Kconfig +14 −14 Original line number Diff line number Diff line Loading @@ -893,7 +893,7 @@ config SERIAL_VR41XX_CONSOLE config SERIAL_JSM tristate "Digi International NEO PCI Support" depends on PCI && BROKEN depends on PCI select SERIAL_CORE help This is a driver for Digi International's Neo series Loading
drivers/serial/jsm/jsm_tty.c +65 −143 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ * * Contact Information: * Scott H Kilau <Scott_Kilau@digi.com> * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> * * Ananda Venkatarman <mansarov@us.ibm.com> * Modifications: * 01/19/06: changed jsm_input routine to use the dynamically allocated * tty_buffer changes. Contributors: Scott Kilau and Ananda V. ***********************************************************************/ #include <linux/tty.h> #include <linux/tty_flip.h> Loading Loading @@ -497,16 +499,16 @@ void jsm_input(struct jsm_channel *ch) { struct jsm_board *bd; struct tty_struct *tp; struct tty_ldisc *ld; u32 rmask; u16 head; u16 tail; int data_len; unsigned long lock_flags; int flip_len; int flip_len = 0; int len = 0; int n = 0; char *buf = NULL; char *buf2 = NULL; int s = 0; int i = 0; Loading Loading @@ -574,56 +576,50 @@ void jsm_input(struct jsm_channel *ch) /* * 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. * as we can directly into the linux TTY buffer. * * 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; flip_len = TTY_FLIPBUF_SIZE; len = min(data_len, flip_len); len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); ld = tty_ldisc_ref(tp); 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 the DONT_FLIP flag is on, don't flush our buffer, and act * like the ld doesn't have any space to put the data right now. */ if (test_bit(TTY_DONT_FLIP, &tp->flags)) len = 0; /* * If we're bypassing flip buffers on rx, we can blast it * right into the beginning of the buffer. * If we were unable to get a reference to the ld, * don't flush our buffer, and act like the ld doesn't * have any space to put the data right now. */ 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; if (!ld) { len = 0; } else { buf = tp->flip.char_buf; buf2 = tp->flip.flag_buf; /* * If ld doesn't have a pointer to a receive_buf function, * flush the data, then act like the ld doesn't have any * space to put the data right now. */ if (!ld->receive_buf) { ch->ch_r_head = ch->ch_r_tail; len = 0; } } else { buf = tp->flip.char_buf_ptr; buf2 = tp->flip.flag_buf_ptr; } if (len <= 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); if (ld) tty_ldisc_deref(ld); return; } len = tty_buffer_request_room(tp, len); n = len; /* Loading @@ -638,121 +634,47 @@ void jsm_input(struct jsm_channel *ch) 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 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 (!jsm_rawreadok) { if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { for (i = 0; i < len; i++) { for (i = 0; i < s; 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; 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 tp->flip.flag_buf_ptr[i] = TTY_NORMAL; tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +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; tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; } } else memset(tp->flip.flag_buf, 0, len); tail += s; n -= s; /* Flip queue if needed */ tail &= rmask; } /* * 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); /* Tell the tty layer its okay to "eat" the data now */ tty_flip_buffer_push(tp); /* 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); } if (ld) tty_ldisc_deref(ld); jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); } Loading