Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19662
b: refs/heads/master
c: 0a577ce
h: refs/heads/master
v: v3
  • Loading branch information
V. Ananda Krishnan authored and Linus Torvalds committed Feb 3, 2006
1 parent 6d387f6 commit c2a2340
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 158 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7d95c8f27d9be65bf160f1edaf653d33dfceb58c
refs/heads/master: 0a577ce34f703c885f807e2abc77dff02c7857af
28 changes: 14 additions & 14 deletions trunk/drivers/serial/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -892,20 +892,20 @@ config SERIAL_VR41XX_CONSOLE
a console on a serial port, say Y. Otherwise, say N.

config SERIAL_JSM
tristate "Digi International NEO PCI Support"
depends on PCI && BROKEN
select SERIAL_CORE
help
This is a driver for Digi International's Neo series
of cards which provide multiple serial ports. You would need
something like this to connect more than two modems to your Linux
box, for instance in order to become a dial-in server. This driver
supports PCI boards only.
If you have a card like this, say Y here and read the file
<file:Documentation/jsm.txt>.

To compile this driver as a module, choose M here: the
module will be called jsm.
tristate "Digi International NEO PCI Support"
depends on PCI
select SERIAL_CORE
help
This is a driver for Digi International's Neo series
of cards which provide multiple serial ports. You would need
something like this to connect more than two modems to your Linux
box, for instance in order to become a dial-in server. This driver
supports PCI boards only.
If you have a card like this, say Y here and read the file
<file:Documentation/jsm.txt>.

To compile this driver as a module, choose M here: the
module will be called jsm.

config SERIAL_SGI_IOC4
tristate "SGI IOC4 controller serial support"
Expand Down
208 changes: 65 additions & 143 deletions trunk/drivers/serial/jsm/jsm_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
} else {
buf = tp->flip.char_buf;
buf2 = tp->flip.flag_buf;
}
if (!ld) {
len = 0;
} else {
buf = tp->flip.char_buf_ptr;
buf2 = tp->flip.flag_buf_ptr;
/*
* 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;
}
}

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;

/*
Expand All @@ -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;
}
/*
* 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.
*/

/*
* 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++) {
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);
tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ;
}

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);
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 !!! */
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);

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(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);
}
if (ld)
tty_ldisc_deref(ld);

jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
}
Expand Down

0 comments on commit c2a2340

Please sign in to comment.