aboutsummaryrefslogtreecommitdiff
path: root/drivers/serial/jsm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/jsm')
-rw-r--r--drivers/serial/jsm/jsm.h1
-rw-r--r--drivers/serial/jsm/jsm_driver.c3
-rw-r--r--drivers/serial/jsm/jsm_neo.c85
-rw-r--r--drivers/serial/jsm/jsm_tty.c209
4 files changed, 103 insertions, 195 deletions
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 18753193f59..dfc1e86d3aa 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -380,7 +380,6 @@ struct neo_uart_struct {
extern struct uart_driver jsm_uart_driver;
extern struct board_ops jsm_neo_ops;
extern int jsm_debug;
-extern int jsm_rawreadok;
/*************************************************************************
*
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index 7e56c782419..b1b66e71d28 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -49,11 +49,8 @@ struct uart_driver jsm_uart_driver = {
};
int jsm_debug;
-int jsm_rawreadok;
module_param(jsm_debug, int, 0);
-module_param(jsm_rawreadok, int, 0);
MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
-MODULE_PARM_DESC(jsm_rawreadok, "Bypass flip buffers on input");
static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 6f22b42d933..87e4e2cf8ce 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -965,56 +965,47 @@ static void neo_param(struct jsm_channel *ch)
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;
+ } 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.info->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 (baud == 0)
- baud = 9600;
-
- if (ch->ch_flags & CH_BAUD0)
- ch->ch_flags &= ~(CH_BAUD0);
}
+ if (ch->ch_flags & CH_BAUD0)
+ ch->ch_flags &= ~(CH_BAUD0);
+ }
+
if (ch->ch_c_cflag & PARENB)
lcr |= UART_LCR_PARITY;
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 6fa0d62d6f6..4d48b625cd3 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -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>
@@ -497,16 +499,15 @@ 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;
@@ -574,56 +575,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;
/*
@@ -638,121 +633,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");
}