aboutsummaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig6
-rw-r--r--drivers/char/amiserial.c33
-rw-r--r--drivers/char/cyclades.c89
-rw-r--r--drivers/char/epca.c17
-rw-r--r--drivers/char/esp.c67
-rw-r--r--drivers/char/hvc_console.c6
-rw-r--r--drivers/char/hvcs.c10
-rw-r--r--drivers/char/isicom.c24
-rw-r--r--drivers/char/istallion.c26
-rw-r--r--drivers/char/moxa.c73
-rw-r--r--drivers/char/mxser.c2
-rw-r--r--drivers/char/n_hdlc.c18
-rw-r--r--drivers/char/n_r3964.c10
-rw-r--r--drivers/char/n_tty.c66
-rw-r--r--drivers/char/pcmcia/synclink_cs.c28
-rw-r--r--drivers/char/pty.c4
-rw-r--r--drivers/char/rio/riointr.c13
-rw-r--r--drivers/char/riscom8.c39
-rw-r--r--drivers/char/rocket.c19
-rw-r--r--drivers/char/selection.c5
-rw-r--r--drivers/char/ser_a2232.c8
-rw-r--r--drivers/char/serial167.c35
-rw-r--r--drivers/char/specialix.c38
-rw-r--r--drivers/char/stallion.c50
-rw-r--r--drivers/char/sx.c13
-rw-r--r--drivers/char/synclink.c43
-rw-r--r--drivers/char/synclink_gt.c35
-rw-r--r--drivers/char/synclinkmp.c34
-rw-r--r--drivers/char/tty_io.c266
-rw-r--r--drivers/char/viocons.c3
-rw-r--r--drivers/char/vme_scc.c16
31 files changed, 536 insertions, 560 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 977a74e16ef..d6fcd0a36f9 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
config COMPUTONE
tristate "Computone IntelliPort Plus serial support"
- depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+ depends on SERIAL_NONSTANDARD
---help---
This driver supports the entire family of Intelliport II/Plus
controllers with the exception of the MicroChannel controllers and
@@ -153,7 +153,7 @@ config DIGIEPCA
config ESPSERIAL
tristate "Hayes ESP serial port support"
- depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP && ISA_DMA_API
+ depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API
help
This is a driver which supports Hayes ESP serial ports. Both single
port cards and multiport cards are supported. Make sure to read
@@ -166,7 +166,7 @@ config ESPSERIAL
config MOXA_INTELLIO
tristate "Moxa Intellio support"
- depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+ depends on SERIAL_NONSTANDARD
help
Say Y here if you have a Moxa Intellio multiport serial card.
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 10c81ecdace..869518e4035 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -265,8 +265,9 @@ static _INLINE_ void receive_chars(struct async_struct *info)
int status;
int serdatr;
struct tty_struct *tty = info->tty;
- unsigned char ch;
+ unsigned char ch, flag;
struct async_icount *icount;
+ int oe = 0;
icount = &info->state->icount;
@@ -282,15 +283,12 @@ static _INLINE_ void receive_chars(struct async_struct *info)
status |= UART_LSR_OE;
ch = serdatr & 0xff;
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- goto ignore_char;
- *tty->flip.char_buf_ptr = ch;
icount->rx++;
#ifdef SERIAL_DEBUG_INTR
printk("DR%02x:%02x...", ch, status);
#endif
- *tty->flip.flag_buf_ptr = 0;
+ flag = TTY_NORMAL;
/*
* We don't handle parity or frame errors - but I have left
@@ -319,7 +317,7 @@ static _INLINE_ void receive_chars(struct async_struct *info)
* should be ignored.
*/
if (status & info->ignore_status_mask)
- goto ignore_char;
+ goto out;
status &= info->read_status_mask;
@@ -327,33 +325,28 @@ static _INLINE_ void receive_chars(struct async_struct *info)
#ifdef SERIAL_DEBUG_INTR
printk("handling break....");
#endif
- *tty->flip.flag_buf_ptr = TTY_BREAK;
+ flag = TTY_BREAK;
if (info->flags & ASYNC_SAK)
do_SAK(tty);
} else if (status & UART_LSR_PE)
- *tty->flip.flag_buf_ptr = TTY_PARITY;
+ flag = TTY_PARITY;
else if (status & UART_LSR_FE)
- *tty->flip.flag_buf_ptr = TTY_FRAME;
+ flag = TTY_FRAME;
if (status & UART_LSR_OE) {
/*
* Overrun is special, since it's
* reported immediately, and doesn't
* affect the current character
*/
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- *tty->flip.flag_buf_ptr = TTY_OVERRUN;
- }
+ oe = 1;
}
}
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- tty->flip.count++;
- ignore_char:
-
+ tty_insert_flip_char(tty, ch, flag);
+ if (oe == 1)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
tty_flip_buffer_push(tty);
+out:
+ return;
}
static _INLINE_ void transmit_chars(struct async_struct *info)
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index c8e7daecad7..39c61a71176 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -641,6 +641,7 @@ static char rcsid[] =
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
+#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/major.h>
#include <linux/string.h>
@@ -1086,7 +1087,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
int had_work;
int mdm_change;
int mdm_status;
-
+ int len;
if((cinfo = (struct cyclades_card *)dev_id) == 0){
#ifdef CY_DEBUG_INTERRUPTS
printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
@@ -1163,63 +1164,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
info->icount.rx++;
continue;
}
- if (tty->flip.count < TTY_FLIPBUF_SIZE){
- tty->flip.count++;
+ if (tty_buffer_request_room(tty, 1)) {
if (data & info->read_status_mask){
if(data & CyBREAK){
- *tty->flip.flag_buf_ptr++ =
- TTY_BREAK;
- *tty->flip.char_buf_ptr++ =
- cy_readb(base_addr+(CyRDSR<<index));
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
info->icount.rx++;
if (info->flags & ASYNC_SAK){
do_SAK(tty);
}
}else if(data & CyFRAME){
- *tty->flip.flag_buf_ptr++ =
- TTY_FRAME;
- *tty->flip.char_buf_ptr++ =
- cy_readb(base_addr+(CyRDSR<<index));
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
info->icount.rx++;
info->idle_stats.frame_errs++;
}else if(data & CyPARITY){
- *tty->flip.flag_buf_ptr++ =
- TTY_PARITY;
- *tty->flip.char_buf_ptr++ =
- cy_readb(base_addr+(CyRDSR<<index));
+ /* Pieces of seven... */
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
info->icount.rx++;
info->idle_stats.parity_errs++;
}else if(data & CyOVERRUN){
- *tty->flip.flag_buf_ptr++ =
- TTY_OVERRUN;
- *tty->flip.char_buf_ptr++ = 0;
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
info->icount.rx++;
/* If the flip buffer itself is
overflowing, we still lose
the next incoming character.
*/
- if(tty->flip.count
- < TTY_FLIPBUF_SIZE){
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ =
- TTY_NORMAL;
- *tty->flip.char_buf_ptr++ =
- cy_readb(base_addr+(CyRDSR<<index));
- info->icount.rx++;
- }
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
+ info->icount.rx++;
info->idle_stats.overruns++;
/* These two conditions may imply */
/* a normal read should be done. */
/* }else if(data & CyTIMEOUT){ */
/* }else if(data & CySPECHAR){ */
- }else{
- *tty->flip.flag_buf_ptr++ = 0;
- *tty->flip.char_buf_ptr++ = 0;
- info->icount.rx++;
+ }else {
+ tty_insert_flip_char(tty, 0, TTY_NORMAL);
+ info->icount.rx++;
}
}else{
- *tty->flip.flag_buf_ptr++ = 0;
- *tty->flip.char_buf_ptr++ = 0;
+ tty_insert_flip_char(tty, 0, TTY_NORMAL);
info->icount.rx++;
}
}else{
@@ -1240,14 +1221,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
info->mon.char_max = char_count;
info->mon.char_last = char_count;
#endif
- while(char_count--){
- if (tty->flip.count >= TTY_FLIPBUF_SIZE){
- break;
- }
- tty->flip.count++;
+ len = tty_buffer_request_room(tty, char_count);
+ while(len--){
data = cy_readb(base_addr+(CyRDSR<<index));
- *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
- *tty->flip.char_buf_ptr++ = data;
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
info->idle_stats.recv_bytes++;
info->icount.rx++;
#ifdef CY_16Y_HACK
@@ -1256,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
info->idle_stats.recv_idle = jiffies;
}
- schedule_delayed_work(&tty->flip.work, 1);
+ schedule_delayed_work(&tty->buf.work, 1);
}
/* end of service */
cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
@@ -1551,6 +1528,7 @@ cyz_handle_rx(struct cyclades_port *info,
struct cyclades_card *cinfo = &cy_card[info->card];
struct tty_struct *tty = info->tty;
volatile int char_count;
+ int len;
#ifdef BLOCKMOVE
int small_count;
#else
@@ -1606,18 +1584,11 @@ cyz_handle_rx(struct cyclades_port *info,
tty->flip.count += small_count;
}
#else
- while(char_count--){
- if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt)
- break;
-
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- break;
-
+ len = tty_buffer_request_room(tty, char_count);
+ while(len--){
data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);
new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
- *tty->flip.char_buf_ptr++ = data;
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
info->idle_stats.recv_bytes++;
info->icount.rx++;
}
@@ -1635,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info,
}
#endif
info->idle_stats.recv_idle = jiffies;
- schedule_delayed_work(&tty->flip.work, 1);
+ schedule_delayed_work(&tty->buf.work, 1);
}
/* Update rx_get */
cy_writel(&buf_ctrl->rx_get, new_rx_get);
@@ -1763,23 +1734,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
switch(cmd) {
case C_CM_PR_ERROR:
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = TTY_PARITY;
- *tty->flip.char_buf_ptr++ = 0;
+ tty_insert_flip_char(tty, 0, TTY_PARITY);
info->icount.rx++;
special_count++;
break;
case C_CM_FR_ERROR:
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = TTY_FRAME;
- *tty->flip.char_buf_ptr++ = 0;
+ tty_insert_flip_char(tty, 0, TTY_FRAME);
info->icount.rx++;
special_count++;
break;
case C_CM_RXBRK:
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = TTY_BREAK;
- *tty->flip.char_buf_ptr++ = 0;
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
info->icount.rx++;
special_count++;
break;
@@ -1844,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
if(delta_count)
cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
if(special_count)
- schedule_delayed_work(&tty->flip.work, 1);
+ schedule_delayed_work(&tty->buf.work, 1);
}
}
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 407708a001e..765c5c108bf 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -1786,9 +1786,7 @@ static void doevent(int crd)
if (tty) { /* Begin if valid tty */
if (event & BREAK_IND) { /* Begin if BREAK_IND */
/* A break has been indicated */
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = TTY_BREAK;
- *tty->flip.char_buf_ptr++ = 0;
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
} else if (event & LOWTX_IND) { /* Begin LOWTX_IND */
if (ch->statusflags & LOWWAIT)
@@ -2124,7 +2122,6 @@ static void receive_data(struct channel *ch)
int dataToRead, wrapgap, bytesAvailable;
unsigned int tail, head;
unsigned int wrapmask;
- int rc;
/* ---------------------------------------------------------------
This routine is called by doint when a receive data event
@@ -2162,16 +2159,15 @@ static void receive_data(struct channel *ch)
return;
}
- if (tty->flip.count == TTY_FLIPBUF_SIZE)
+ if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0)
return;
if (readb(&bc->orun)) {
writeb(0, &bc->orun);
printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name);
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
rxwinon(ch);
- rptr = tty->flip.char_buf_ptr;
- rc = tty->flip.count;
while (bytesAvailable > 0) { /* Begin while there is data on the card */
wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
/* ---------------------------------------------------------------
@@ -2183,8 +2179,7 @@ static void receive_data(struct channel *ch)
/* --------------------------------------------------------------
Make sure we don't overflow the buffer
----------------------------------------------------------------- */
- if ((rc + dataToRead) > TTY_FLIPBUF_SIZE)
- dataToRead = TTY_FLIPBUF_SIZE - rc;
+ dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
if (dataToRead == 0)
break;
/* ---------------------------------------------------------------
@@ -2192,13 +2187,9 @@ static void receive_data(struct channel *ch)
for translation if necessary.
------------------------------------------------------------------ */
memcpy_fromio(rptr, ch->rxptr + tail, dataToRead);
- rc += dataToRead;
- rptr += dataToRead;
tail = (tail + dataToRead) & wrapmask;
bytesAvailable -= dataToRead;
} /* End while there is data on the card */
- tty->flip.count = rc;
- tty->flip.char_buf_ptr = rptr;
globalwinon(ch);
writew(tail, &bc->rout);
/* Must be called with global data */
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 9f53d2fcc36..e469f641c72 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -345,26 +345,22 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
for (i = 0; i < num_bytes; i++) {
if (!(err_buf->data[i] & status_mask)) {
- *(tty->flip.char_buf_ptr++) = pio_buf->data[i];
+ int flag = 0;
if (err_buf->data[i] & 0x04) {
- *(tty->flip.flag_buf_ptr++) = TTY_BREAK;
-
+ flag = TTY_BREAK;
if (info->flags & ASYNC_SAK)
do_SAK(tty);
}
else if (err_buf->data[i] & 0x02)
- *(tty->flip.flag_buf_ptr++) = TTY_FRAME;
+ flag = TTY_FRAME;
else if (err_buf->data[i] & 0x01)
- *(tty->flip.flag_buf_ptr++) = TTY_PARITY;
- else
- *(tty->flip.flag_buf_ptr++) = 0;
-
- tty->flip.count++;
+ flag = TTY_PARITY;
+ tty_insert_flip_char(tty, pio_buf->data[i], flag);
}
}
- schedule_delayed_work(&tty->flip.work, 1);
+ schedule_delayed_work(&tty->buf.work, 1);
info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
release_pio_buffer(pio_buf);
@@ -397,7 +393,6 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
int num_bytes;
unsigned long flags;
-
flags=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
@@ -408,38 +403,31 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
info->icount.rx += num_bytes;
- memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes);
- tty->flip.char_buf_ptr += num_bytes;
- tty->flip.count += num_bytes;
- memset(tty->flip.flag_buf_ptr, 0, num_bytes);
- tty->flip.flag_buf_ptr += num_bytes;
-
if (num_bytes > 0) {
- tty->flip.flag_buf_ptr--;
+ tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
status &= (0x1c & info->read_status_mask);
+
+ /* Is the status significant or do we throw the last byte ? */
+ if (!(status & info->ignore_status_mask)) {
+ int statflag = 0;
- if (status & info->ignore_status_mask) {
- tty->flip.count--;
- tty->flip.char_buf_ptr--;
- tty->flip.flag_buf_ptr--;
- } else if (status & 0x10) {
- *tty->flip.flag_buf_ptr = TTY_BREAK;
- (info->icount.brk)++;
- if (info->flags & ASYNC_SAK)
- do_SAK(tty);
- } else if (status & 0x08) {
- *tty->flip.flag_buf_ptr = TTY_FRAME;
- (info->icount.frame)++;
- }
- else if (status & 0x04) {
- *tty->flip.flag_buf_ptr = TTY_PARITY;
- (info->icount.parity)++;
+ if (status & 0x10) {
+ statflag = TTY_BREAK;
+ (info->icount.brk)++;
+ if (info->flags & ASYNC_SAK)
+ do_SAK(tty);
+ } else if (status & 0x08) {
+ statflag = TTY_FRAME;
+ (info->icount.frame)++;
+ }
+ else if (status & 0x04) {
+ statflag = TTY_PARITY;
+ (info->icount.parity)++;
+ }
+ tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag);
}
-
- tty->flip.flag_buf_ptr++;
-
- schedule_delayed_work(&tty->flip.work, 1);
+ schedule_delayed_work(&tty->buf.work, 1);
}
if (dma_bytes != num_bytes) {
@@ -693,8 +681,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id,
num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
num_bytes |= serial_in(info, UART_ESI_STAT2);
- if (num_bytes > (TTY_FLIPBUF_SIZE - info->tty->flip.count))
- num_bytes = TTY_FLIPBUF_SIZE - info->tty->flip.count;
+ num_bytes = tty_buffer_request_room(info->tty, num_bytes);
if (num_bytes) {
if (dma_bytes ||
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index f9217763467..1994a92d473 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -597,9 +597,7 @@ static int hvc_poll(struct hvc_struct *hp)
/* Read data if any */
for (;;) {
- int count = N_INBUF;
- if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
- count = TTY_FLIPBUF_SIZE - tty->flip.count;
+ int count = tty_buffer_request_room(tty, N_INBUF);
/* If flip is full, just reschedule a later read */
if (count == 0) {
@@ -635,7 +633,7 @@ static int hvc_poll(struct hvc_struct *hp)
tty_insert_flip_char(tty, buf[i], 0);
}
- if (tty->flip.count)
+ if (count)
tty_schedule_flip(tty);
/*
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 53dc77c760f..831eb4e8d9d 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -456,12 +456,11 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
/* remove the read masks */
hvcsd->todo_mask &= ~(HVCS_READ_MASK);
- if ((tty->flip.count + HVCS_BUFF_LEN) < TTY_FLIPBUF_SIZE) {
+ if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) {
got = hvc_get_chars(unit_address,
&buf[0],
HVCS_BUFF_LEN);
- for (i=0;got && i<got;i++)
- tty_insert_flip_char(tty, buf[i], TTY_NORMAL);
+ tty_insert_flip_string(tty, buf, got);
}
/* Give the TTY time to process the data we just sent. */
@@ -469,10 +468,9 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
hvcsd->todo_mask |= HVCS_QUICK_READ;
spin_unlock_irqrestore(&hvcsd->lock, flags);
- if (tty->flip.count) {
- /* This is synch because tty->low_latency == 1 */
+ /* This is synch because tty->low_latency == 1 */
+ if(got)
tty_flip_buffer_push(tty);
- }
if (!got) {
/* Do this _after_ the flip_buffer_push */
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 1bbf507adda..86033bed5d6 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -115,6 +115,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/tty.h>
+#include <linux/tty_flip.h>
#include <linux/termios.h>
#include <linux/fs.h>
#include <linux/sched.h>
@@ -773,6 +774,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id,
unsigned short base, header, word_count, count;
unsigned char channel;
short byte_count;
+ unsigned char *rp;
card = (struct isi_board *) dev_id;
@@ -903,14 +905,10 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id,
break;
case 1: /* Received Break !!! */
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- break;
- *tty->flip.flag_buf_ptr++ = TTY_BREAK;
- *tty->flip.char_buf_ptr++ = 0;
- tty->flip.count++;
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
if (port->flags & ASYNC_SAK)
do_SAK(tty);
- schedule_delayed_work(&tty->flip.work, 1);
+ tty_flip_buffer_push(tty);
break;
case 2: /* Statistics */
@@ -923,23 +921,19 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id,
}
}
else { /* Data Packet */
- count = min_t(unsigned short, byte_count, (TTY_FLIPBUF_SIZE - tty->flip.count));
+
+ count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
#ifdef ISICOM_DEBUG
printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n",
count, byte_count);
#endif
word_count = count >> 1;
- insw(base, tty->flip.char_buf_ptr, word_count);
- tty->flip.char_buf_ptr += (word_count << 1);
+ insw(base, rp, word_count);
byte_count -= (word_count << 1);
if (count & 0x0001) {
- *tty->flip.char_buf_ptr++ = (char)(inw(base) & 0xff);
+ tty_insert_flip_char(tty, inw(base) & 0xff, TTY_NORMAL);
byte_count -= 2;
}
- memset(tty->flip.flag_buf_ptr, 0, count);
- tty->flip.flag_buf_ptr += count;
- tty->flip.count += count;
-
if (byte_count > 0) {
printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n",
base, channel+1);
@@ -948,7 +942,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id,
byte_count -= 2;
}
}
- schedule_delayed_work(&tty->flip.work, 1);
+ tty_flip_buffer_push(tty);
}
if (card->isa == YES)
ClearInterrupt(base);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 24435f8daa6..28c5a3193b8 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -2711,17 +2711,13 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp)
stlen = size - tail;
}
- len = MIN(len, (TTY_FLIPBUF_SIZE - tty->flip.count));
+ len = tty_buffer_request_room(tty, len);
+ /* FIXME : iomap ? */
shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
while (len > 0) {
stlen = MIN(len, stlen);
- memcpy(tty->flip.char_buf_ptr, (char *) (shbuf + tail), stlen);
- memset(tty->flip.flag_buf_ptr, 0, stlen);
- tty->flip.char_buf_ptr += stlen;
- tty->flip.flag_buf_ptr += stlen;
- tty->flip.count += stlen;
-
+ tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen);
len -= stlen;
tail += stlen;
if (tail >= size) {
@@ -2906,16 +2902,12 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
if (tty != (struct tty_struct *) NULL) {
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = TTY_BREAK;
- *tty->flip.char_buf_ptr++ = 0;
- if (portp->flags & ASYNC_SAK) {
- do_SAK(tty);
- EBRDENABLE(brdp);
- }
- tty_schedule_flip(tty);
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
+ if (portp->flags & ASYNC_SAK) {
+ do_SAK(tty);
+ EBRDENABLE(brdp);
}
+ tty_schedule_flip(tty);
}
}
@@ -4940,7 +4932,7 @@ static int stli_portcmdstats(stliport_t *portp)
if (portp->tty != (struct tty_struct *) NULL) {
if (portp->tty->driver_data == portp) {
stli_comstats.ttystate = portp->tty->flags;
- stli_comstats.rxbuffered = portp->tty->flip.count;
+ stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/;
if (portp->tty->termios != (struct termios *) NULL) {
stli_comstats.cflags = portp->tty->termios->c_cflag;
stli_comstats.iflags = portp->tty->termios->c_iflag;
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 46a3a8ccd65..5e3ef552219 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -269,7 +269,7 @@ static int MoxaPortDCDChange(int);
static int MoxaPortDCDON(int);
static void MoxaPortFlushData(int, int);
static int MoxaPortWriteData(int, unsigned char *, int);
-static int MoxaPortReadData(int, unsigned char *, int);
+static int MoxaPortReadData(int, struct tty_struct *tty);
static int MoxaPortTxQueue(int);
static int MoxaPortRxQueue(int);
static int MoxaPortTxFree(int);
@@ -301,6 +301,8 @@ static struct tty_operations moxa_ops = {
.tiocmset = moxa_tiocmset,
};
+static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED;
+
#ifdef CONFIG_PCI
static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
{
@@ -645,10 +647,10 @@ static int moxa_write(struct tty_struct *tty,
if (ch == NULL)
return (0);
port = ch->port;
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&moxa_lock, flags);
len = MoxaPortWriteData(port, (unsigned char *) buf, count);
- restore_flags(flags);
+ spin_unlock_irqrestore(&moxa_lock, flags);
/*********************************************
if ( !(ch->statusflags & LOWWAIT) &&
@@ -723,11 +725,10 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
if (ch == NULL)
return;
port = ch->port;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&moxa_lock, flags);
moxaXmitBuff[0] = c;
MoxaPortWriteData(port, moxaXmitBuff, 1);
- restore_flags(flags);
+ spin_unlock_irqrestore(&moxa_lock, flags);
/************************************************
if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
*************************************************/
@@ -1030,12 +1031,12 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
printk("block_til_ready before block: ttys%d, count = %d\n",
ch->line, ch->count);
#endif
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&moxa_lock, flags);
if (!tty_hung_up_p(filp))
ch->count--;
- restore_flags(flags);
ch->blocked_open++;
+ spin_unlock_irqrestore(&moxa_lock, flags);
+
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
@@ -1062,17 +1063,21 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&ch->open_wait, &wait);
+
+ spin_lock_irqsave(&moxa_lock, flags);
if (!tty_hung_up_p(filp))
ch->count++;
ch->blocked_open--;
+ spin_unlock_irqrestore(&moxa_lock, flags);
#ifdef SERIAL_DEBUG_OPEN
printk("block_til_ready after blocking: ttys%d, count = %d\n",
ch->line, ch->count);
#endif
if (retval)
return (retval);
+ /* FIXME: review to see if we need to use set_bit on these */
ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
- return (0);
+ return 0;
}
static void setup_empty_event(struct tty_struct *tty)
@@ -1080,15 +1085,14 @@ static void setup_empty_event(struct tty_struct *tty)
struct moxa_str *ch = tty->driver_data;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&moxa_lock, flags);
ch->statusflags |= EMPTYWAIT;
moxaEmptyTimer_on[ch->port] = 0;
del_timer(&moxaEmptyTimer[ch->port]);
moxaEmptyTimer[ch->port].expires = jiffies + HZ;
moxaEmptyTimer_on[ch->port] = 1;
add_timer(&moxaEmptyTimer[ch->port]);
- restore_flags(flags);
+ spin_unlock_irqrestore(&moxa_lock, flags);
}
static void check_xmit_empty(unsigned long data)
@@ -1135,8 +1139,6 @@ static void receive_data(struct moxa_str