diff options
Diffstat (limited to 'drivers/serial')
30 files changed, 171 insertions, 470 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index b5cf39468d18..221999bcf8fe 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -94,15 +94,6 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r | |||
94 | 94 | ||
95 | status = *CSR_UARTFLG; | 95 | status = *CSR_UARTFLG; |
96 | while (!(status & 0x10) && max_count--) { | 96 | while (!(status & 0x10) && max_count--) { |
97 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
98 | if (tty->low_latency) | ||
99 | tty_flip_buffer_push(tty); | ||
100 | /* | ||
101 | * If this failed then we will throw away the | ||
102 | * bytes but must do so to clear interrupts | ||
103 | */ | ||
104 | } | ||
105 | |||
106 | ch = *CSR_UARTDR; | 97 | ch = *CSR_UARTDR; |
107 | flag = TTY_NORMAL; | 98 | flag = TTY_NORMAL; |
108 | port->icount.rx++; | 99 | port->icount.rx++; |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 67e9afa000c1..4dd5c3f98167 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -294,7 +294,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
294 | { | 294 | { |
295 | struct tty_struct *tty = info->tty; | 295 | struct tty_struct *tty = info->tty; |
296 | m68328_uart *uart = &uart_addr[info->line]; | 296 | m68328_uart *uart = &uart_addr[info->line]; |
297 | unsigned char ch; | 297 | unsigned char ch, flag; |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * This do { } while() loop will get ALL chars out of Rx FIFO | 300 | * This do { } while() loop will get ALL chars out of Rx FIFO |
@@ -332,26 +332,24 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
332 | /* | 332 | /* |
333 | * Make sure that we do not overflow the buffer | 333 | * Make sure that we do not overflow the buffer |
334 | */ | 334 | */ |
335 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 335 | if (tty_request_buffer_room(tty, 1) == 0) { |
336 | schedule_work(&tty->flip.work); | 336 | schedule_work(&tty->flip.work); |
337 | return; | 337 | return; |
338 | } | 338 | } |
339 | 339 | ||
340 | flag = TTY_NORMAL; | ||
341 | |||
340 | if(rx & URX_PARITY_ERROR) { | 342 | if(rx & URX_PARITY_ERROR) { |
341 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 343 | flag = TTY_PARITY; |
342 | status_handle(info, rx); | 344 | status_handle(info, rx); |
343 | } else if(rx & URX_OVRUN) { | 345 | } else if(rx & URX_OVRUN) { |
344 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 346 | flag = TTY_OVERRUN; |
345 | status_handle(info, rx); | 347 | status_handle(info, rx); |
346 | } else if(rx & URX_FRAME_ERROR) { | 348 | } else if(rx & URX_FRAME_ERROR) { |
347 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 349 | flag = TTY_FRAME; |
348 | status_handle(info, rx); | 350 | status_handle(info, rx); |
349 | } else { | ||
350 | *tty->flip.flag_buf_ptr++ = 0; /* XXX */ | ||
351 | } | 351 | } |
352 | *tty->flip.char_buf_ptr++ = ch; | 352 | tty_insert_flip_char(tty, ch, flag); |
353 | tty->flip.count++; | ||
354 | |||
355 | #ifndef CONFIG_XCOPILOT_BUGS | 353 | #ifndef CONFIG_XCOPILOT_BUGS |
356 | } while((rx = uart->urx.w) & URX_DATA_READY); | 354 | } while((rx = uart->urx.w) & URX_DATA_READY); |
357 | #endif | 355 | #endif |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 170c9d2a749c..60f5a5dc17f1 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -394,7 +394,7 @@ static void rs_360_start(struct tty_struct *tty) | |||
394 | static _INLINE_ void receive_chars(ser_info_t *info) | 394 | static _INLINE_ void receive_chars(ser_info_t *info) |
395 | { | 395 | { |
396 | struct tty_struct *tty = info->tty; | 396 | struct tty_struct *tty = info->tty; |
397 | unsigned char ch, *cp; | 397 | unsigned char ch, flag, *cp; |
398 | /*int ignored = 0;*/ | 398 | /*int ignored = 0;*/ |
399 | int i; | 399 | int i; |
400 | ushort status; | 400 | ushort status; |
@@ -438,24 +438,15 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
438 | cp = (char *)bdp->buf; | 438 | cp = (char *)bdp->buf; |
439 | status = bdp->status; | 439 | status = bdp->status; |
440 | 440 | ||
441 | /* Check to see if there is room in the tty buffer for | ||
442 | * the characters in our BD buffer. If not, we exit | ||
443 | * now, leaving the BD with the characters. We'll pick | ||
444 | * them up again on the next receive interrupt (which could | ||
445 | * be a timeout). | ||
446 | */ | ||
447 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) | ||
448 | break; | ||
449 | |||
450 | while (i-- > 0) { | 441 | while (i-- > 0) { |
451 | ch = *cp++; | 442 | ch = *cp++; |
452 | *tty->flip.char_buf_ptr = ch; | ||
453 | icount->rx++; | 443 | icount->rx++; |
454 | 444 | ||
455 | #ifdef SERIAL_DEBUG_INTR | 445 | #ifdef SERIAL_DEBUG_INTR |
456 | printk("DR%02x:%02x...", ch, status); | 446 | printk("DR%02x:%02x...", ch, status); |
457 | #endif | 447 | #endif |
458 | *tty->flip.flag_buf_ptr = 0; | 448 | flag = TTY_NORMAL; |
449 | |||
459 | if (status & (BD_SC_BR | BD_SC_FR | | 450 | if (status & (BD_SC_BR | BD_SC_FR | |
460 | BD_SC_PR | BD_SC_OV)) { | 451 | BD_SC_PR | BD_SC_OV)) { |
461 | /* | 452 | /* |
@@ -490,30 +481,18 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
490 | if (info->flags & ASYNC_SAK) | 481 | if (info->flags & ASYNC_SAK) |
491 | do_SAK(tty); | 482 | do_SAK(tty); |
492 | } else if (status & BD_SC_PR) | 483 | } else if (status & BD_SC_PR) |
493 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 484 | flag = TTY_PARITY; |
494 | else if (status & BD_SC_FR) | 485 | else if (status & BD_SC_FR) |
495 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 486 | flag = TTY_FRAME; |
496 | if (status & BD_SC_OV) { | ||
497 | /* | ||
498 | * Overrun is special, since it's | ||
499 | * reported immediately, and doesn't | ||
500 | * affect the current character | ||
501 | */ | ||
502 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
503 | tty->flip.count++; | ||
504 | tty->flip.flag_buf_ptr++; | ||
505 | tty->flip.char_buf_ptr++; | ||
506 | *tty->flip.flag_buf_ptr = | ||
507 | TTY_OVERRUN; | ||
508 | } | ||
509 | } | ||
510 | } | 487 | } |
511 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 488 | tty_insert_flip_char(tty, ch, flag); |
512 | break; | 489 | if (status & BD_SC_OV) |
513 | 490 | /* | |
514 | tty->flip.flag_buf_ptr++; | 491 | * Overrun is special, since it's |
515 | tty->flip.char_buf_ptr++; | 492 | * reported immediately, and doesn't |
516 | tty->flip.count++; | 493 | * affect the current character |
494 | */ | ||
495 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
517 | } | 496 | } |
518 | 497 | ||
519 | /* This BD is ready to be used again. Clear status. | 498 | /* This BD is ready to be used again. Clear status. |
@@ -541,12 +520,7 @@ static _INLINE_ void receive_break(ser_info_t *info) | |||
541 | /* Check to see if there is room in the tty buffer for | 520 | /* Check to see if there is room in the tty buffer for |
542 | * the break. If not, we exit now, losing the break. FIXME | 521 | * the break. If not, we exit now, losing the break. FIXME |
543 | */ | 522 | */ |
544 | if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE) | 523 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
545 | return; | ||
546 | *(tty->flip.flag_buf_ptr++) = TTY_BREAK; | ||
547 | *(tty->flip.char_buf_ptr++) = 0; | ||
548 | tty->flip.count++; | ||
549 | |||
550 | schedule_work(&tty->flip.work); | 524 | schedule_work(&tty->flip.work); |
551 | } | 525 | } |
552 | 526 | ||
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index e8454611cb65..54e5cc0dd5f8 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -1142,19 +1142,6 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
1142 | char flag; | 1142 | char flag; |
1143 | 1143 | ||
1144 | do { | 1144 | do { |
1145 | /* The following is not allowed by the tty layer and | ||
1146 | unsafe. It should be fixed ASAP */ | ||
1147 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
1148 | if (tty->low_latency) { | ||
1149 | spin_unlock(&up->port.lock); | ||
1150 | tty_flip_buffer_push(tty); | ||
1151 | spin_lock(&up->port.lock); | ||
1152 | } | ||
1153 | /* | ||
1154 | * If this failed then we will throw away the | ||
1155 | * bytes but must do so to clear interrupts | ||
1156 | */ | ||
1157 | } | ||
1158 | ch = serial_inp(up, UART_RX); | 1145 | ch = serial_inp(up, UART_RX); |
1159 | flag = TTY_NORMAL; | 1146 | flag = TTY_NORMAL; |
1160 | up->port.icount.rx++; | 1147 | up->port.icount.rx++; |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 48f6e872314b..3490022e9fdc 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -154,15 +154,6 @@ pl010_rx_chars(struct uart_port *port) | |||
154 | 154 | ||
155 | status = UART_GET_FR(port); | 155 | status = UART_GET_FR(port); |
156 | while (UART_RX_DATA(status) && max_count--) { | 156 | while (UART_RX_DATA(status) && max_count--) { |
157 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
158 | if (tty->low_latency) | ||
159 | tty_flip_buffer_push(tty); | ||
160 | /* | ||
161 | * If this failed then we will throw away the | ||
162 | * bytes but must do so to clear interrupts. | ||
163 | */ | ||
164 | } | ||
165 | |||
166 | ch = UART_GET_CHAR(port); | 157 | ch = UART_GET_CHAR(port); |
167 | flag = TTY_NORMAL; | 158 | flag = TTY_NORMAL; |
168 | 159 | ||
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 129670556162..034a029e356e 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -120,15 +120,6 @@ pl011_rx_chars(struct uart_amba_port *uap) | |||
120 | 120 | ||
121 | status = readw(uap->port.membase + UART01x_FR); | 121 | status = readw(uap->port.membase + UART01x_FR); |
122 | while ((status & UART01x_FR_RXFE) == 0 && max_count--) { | 122 | while ((status & UART01x_FR_RXFE) == 0 && max_count--) { |
123 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
124 | if (tty->low_latency) | ||
125 | tty_flip_buffer_push(tty); | ||
126 | /* | ||
127 | * If this failed then we will throw away the | ||
128 | * bytes but must do so to clear interrupts | ||
129 | */ | ||
130 | } | ||
131 | |||
132 | ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; | 123 | ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; |
133 | flag = TTY_NORMAL; | 124 | flag = TTY_NORMAL; |
134 | uap->port.icount.rx++; | 125 | uap->port.icount.rx++; |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index a274ebf256a1..ceb5d7f37bbd 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c | |||
@@ -241,18 +241,12 @@ static _INLINE_ void | |||
241 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | 241 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) |
242 | { | 242 | { |
243 | struct tty_struct *tty = up->port.info->tty; | 243 | struct tty_struct *tty = up->port.info->tty; |
244 | unsigned char ch; | 244 | unsigned char ch, flag; |
245 | int max_count = 256; | 245 | int max_count = 256; |
246 | 246 | ||
247 | do { | 247 | do { |
248 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
249 | tty->flip.work.func((void *)tty); | ||
250 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
251 | return; // if TTY_DONT_FLIP is set | ||
252 | } | ||
253 | ch = serial_inp(up, UART_RX); | 248 | ch = serial_inp(up, UART_RX); |
254 | *tty->flip.char_buf_ptr = ch; | 249 | flag = TTY_NORMAL; |
255 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
256 | up->port.icount.rx++; | 250 | up->port.icount.rx++; |
257 | 251 | ||
258 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 252 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
@@ -292,30 +286,23 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
292 | #endif | 286 | #endif |
293 | if (*status & UART_LSR_BI) { | 287 | if (*status & UART_LSR_BI) { |
294 | DEBUG_INTR("handling break...."); | 288 | DEBUG_INTR("handling break...."); |
295 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 289 | flag = TTY_BREAK; |
296 | } else if (*status & UART_LSR_PE) | 290 | } else if (*status & UART_LSR_PE) |
297 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 291 | flag = TTY_PARITY; |
298 | else if (*status & UART_LSR_FE) | 292 | else if (*status & UART_LSR_FE) |
299 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 293 | flag = TTY_FRAME; |
300 | } | 294 | } |
301 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 295 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
302 | goto ignore_char; | 296 | goto ignore_char; |
303 | if ((*status & up->port.ignore_status_mask) == 0) { | 297 | if ((*status & up->port.ignore_status_mask) == 0) |
304 | tty->flip.flag_buf_ptr++; | 298 | tty_insert_flip_char(tty, ch, flag); |
305 | tty->flip.char_buf_ptr++; | 299 | if (*status & UART_LSR_OE) |
306 | tty->flip.count++; | ||
307 | } | ||
308 | if ((*status & UART_LSR_OE) && | ||
309 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
310 | /* | 300 | /* |
311 | * Overrun is special, since it's reported | 301 | * Overrun is special, since it's reported |
312 | * immediately, and doesn't affect the current | 302 | * immediately, and doesn't affect the current |
313 | * character. | 303 | * character. |
314 | */ | 304 | */ |
315 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | 305 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
316 | tty->flip.flag_buf_ptr++; | ||
317 | tty->flip.char_buf_ptr++; | ||
318 | tty->flip.count++; | ||
319 | } | 306 | } |
320 | ignore_char: | 307 | ignore_char: |
321 | *status = serial_inp(up, UART_LSR); | 308 | *status = serial_inp(up, UART_LSR); |
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 87ef368384fb..8ef999481f93 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c | |||
@@ -104,8 +104,6 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re | |||
104 | while (!(status & SYSFLG_URXFE)) { | 104 | while (!(status & SYSFLG_URXFE)) { |
105 | ch = clps_readl(UARTDR(port)); | 105 | ch = clps_readl(UARTDR(port)); |
106 | 106 | ||
107 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
108 | goto ignore_char; | ||
109 | port->icount.rx++; | 107 | port->icount.rx++; |
110 | 108 | ||
111 | flg = TTY_NORMAL; | 109 | flg = TTY_NORMAL; |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index 4d8516d1bb71..a64ba26a94e8 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -216,8 +216,6 @@ static inline void dz_receive_chars(struct dz_port *dport) | |||
216 | 216 | ||
217 | if (!tty) | 217 | if (!tty) |
218 | break; | 218 | break; |
219 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
220 | break; | ||
221 | 219 | ||
222 | icount->rx++; | 220 | icount->rx++; |
223 | 221 | ||
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index eb31125c6a30..144a7a352b28 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -729,19 +729,20 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
729 | unsigned short int status; | 729 | unsigned short int status; |
730 | struct uart_icount *icount; | 730 | struct uart_icount *icount; |
731 | unsigned long offset; | 731 | unsigned long offset; |
732 | unsigned char flag; | ||
732 | 733 | ||
733 | trace(icom_port, "RCV_COMPLETE", 0); | 734 | trace(icom_port, "RCV_COMPLETE", 0); |
734 | rcv_buff = icom_port->next_rcv; | 735 | rcv_buff = icom_port->next_rcv; |
735 | 736 | ||
736 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); | 737 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); |
737 | while (status & SA_FL_RCV_DONE) { | 738 | while (status & SA_FL_RCV_DONE) { |
739 | int first = -1; | ||
738 | 740 | ||
739 | trace(icom_port, "FID_STATUS", status); | 741 | trace(icom_port, "FID_STATUS", status); |
740 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); | 742 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); |
741 | 743 | ||
744 | count = tty_buffer_request_room(tty, count); | ||
742 | trace(icom_port, "RCV_COUNT", count); | 745 | trace(icom_port, "RCV_COUNT", count); |
743 | if (count > (TTY_FLIPBUF_SIZE - tty->flip.count)) | ||
744 | count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
745 | 746 | ||
746 | trace(icom_port, "REAL_COUNT", count); | 747 | trace(icom_port, "REAL_COUNT", count); |
747 | 748 | ||
@@ -749,15 +750,10 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
749 | cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) - | 750 | cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) - |
750 | icom_port->recv_buf_pci; | 751 | icom_port->recv_buf_pci; |
751 | 752 | ||
752 | memcpy(tty->flip.char_buf_ptr,(unsigned char *) | 753 | /* Block copy all but the last byte as this may have status */ |
753 | ((unsigned long)icom_port->recv_buf + offset), count); | ||
754 | |||
755 | if (count > 0) { | 754 | if (count > 0) { |
756 | tty->flip.count += count - 1; | 755 | first = icom_port->recv_buf[offset]; |
757 | tty->flip.char_buf_ptr += count - 1; | 756 | tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1); |
758 | |||
759 | memset(tty->flip.flag_buf_ptr, 0, count); | ||
760 | tty->flip.flag_buf_ptr += count - 1; | ||
761 | } | 757 | } |
762 | 758 | ||
763 | icount = &icom_port->uart_port.icount; | 759 | icount = &icom_port->uart_port.icount; |
@@ -765,12 +761,14 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
765 | 761 | ||
766 | /* Break detect logic */ | 762 | /* Break detect logic */ |
767 | if ((status & SA_FLAGS_FRAME_ERROR) | 763 | if ((status & SA_FLAGS_FRAME_ERROR) |
768 | && (tty->flip.char_buf_ptr[0] == 0x00)) { | 764 | && first == 0) { |
769 | status &= ~SA_FLAGS_FRAME_ERROR; | 765 | status &= ~SA_FLAGS_FRAME_ERROR; |
770 | status |= SA_FLAGS_BREAK_DET; | 766 | status |= SA_FLAGS_BREAK_DET; |
771 | trace(icom_port, "BREAK_DET", 0); | 767 | trace(icom_port, "BREAK_DET", 0); |
772 | } | 768 | } |
773 | 769 | ||
770 | flag = TTY_NORMAL; | ||
771 | |||
774 | if (status & | 772 | if (status & |
775 | (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR | | 773 | (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR | |
776 | SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) { | 774 | SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) { |
@@ -797,33 +795,26 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
797 | status &= icom_port->read_status_mask; | 795 | status &= icom_port->read_status_mask; |
798 | 796 | ||
799 | if (status & SA_FLAGS_BREAK_DET) { | 797 | if (status & SA_FLAGS_BREAK_DET) { |
800 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 798 | flag = TTY_BREAK; |
801 | } else if (status & SA_FLAGS_PARITY_ERROR) { | 799 | } else if (status & SA_FLAGS_PARITY_ERROR) { |
802 | trace(icom_port, "PARITY_ERROR", 0); | 800 | trace(icom_port, "PARITY_ERROR", 0); |
803 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 801 | flag = TTY_PARITY; |
804 | } else if (status & SA_FLAGS_FRAME_ERROR) | 802 | } else if (status & SA_FLAGS_FRAME_ERROR) |
805 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 803 | flag = TTY_FRAME; |
806 | 804 | ||
807 | if (status & SA_FLAGS_OVERRUN) { | ||
808 | /* | ||
809 | * Overrun is special, since it's | ||
810 | * reported immediately, and doesn't | ||
811 | * affect the current character | ||
812 | */ | ||
813 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
814 | tty->flip.count++; | ||
815 | tty->flip.flag_buf_ptr++; | ||
816 | tty->flip.char_buf_ptr++; | ||
817 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
818 | } | ||
819 | } | ||
820 | } | 805 | } |
821 | 806 | ||
822 | tty->flip.flag_buf_ptr++; | 807 | tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag); |
823 | tty->flip.char_buf_ptr++; | 808 | |
824 | tty->flip.count++; | 809 | if (status & SA_FLAGS_OVERRUN) |
825 | ignore_char: | 810 | /* |
826 | icom_port->statStg->rcv[rcv_buff].flags = 0; | 811 | * Overrun is special, since it's |
812 | * reported immediately, and doesn't | ||
813 | * affect the current character | ||
814 | */ | ||
815 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
816 | ignore_char: | ||
817 | icom_port->statStg->rcv[rcv_buff].flags = 0; | ||
827 | icom_port->statStg->rcv[rcv_buff].leLength = 0; | 818 | icom_port->statStg->rcv[rcv_buff].leLength = 0; |
828 | icom_port->statStg->rcv[rcv_buff].WorkingLength = | 819 | icom_port->statStg->rcv[rcv_buff].WorkingLength = |
829 | (unsigned short int) cpu_to_le16(RCV_BUFF_SZ); | 820 | (unsigned short int) cpu_to_le16(RCV_BUFF_SZ); |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 83c4c1216587..5c098be9346b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -256,9 +256,6 @@ static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs) | |||
256 | error_return: | 256 | error_return: |
257 | tty_insert_flip_char(tty, rx, flg); | 257 | tty_insert_flip_char(tty, rx, flg); |
258 | 258 | ||
259 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
260 | goto out; | ||
261 | |||
262 | ignore_char: | 259 | ignore_char: |
263 | rx = URXD0((u32)sport->port.membase); | 260 | rx = URXD0((u32)sport->port.membase); |
264 | } while(rx & URXD_CHARRDY); | 261 | } while(rx & URXD_CHARRDY); |
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index 771676abee60..1d85533d46d2 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -2327,19 +2327,13 @@ static void receive_chars(struct uart_port *the_port) | |||
2327 | spin_lock_irqsave(&the_port->lock, pflags); | 2327 | spin_lock_irqsave(&the_port->lock, pflags); |
2328 | tty = info->tty; | 2328 | tty = info->tty; |
2329 | 2329 | ||
2330 | if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count) | 2330 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS - 2); |
2331 | request_count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
2332 | 2331 | ||
2333 | if (request_count > 0) { | 2332 | if (request_count > 0) { |
2334 | icount = &the_port->icount; | 2333 | icount = &the_port->icount; |
2335 | read_count = do_read(the_port, ch, request_count); | 2334 | read_count = do_read(the_port, ch, request_count); |
2336 | if (read_count > 0) { | 2335 | if (read_count > 0) { |
2337 | flip = 1; | 2336 | tty_insert_flip_string(tty, ch, read_count); |
2338 | memcpy(tty->flip.char_buf_ptr, ch, read_count); | ||
2339 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count); | ||
2340 | tty->flip.char_buf_ptr += read_count; | ||
2341 | tty->flip.flag_buf_ptr += read_count; | ||
2342 | tty->flip.count += read_count; | ||
2343 | icount->rx += read_count; | 2337 | icount->rx += read_count; |
2344 | } | 2338 | } |
2345 | } | 2339 | } |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index ef132349f310..66f117d15065 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -259,13 +259,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | |||
259 | struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ | 259 | struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ |
260 | 260 | ||
261 | while (1) { | 261 | while (1) { |
262 | unsigned char ch, r1; | 262 | unsigned char ch, r1, flag; |
263 | |||
264 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
265 | tty->flip.work.func((void *)tty); | ||
266 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
267 | return; /* XXX Ignores SysRq when we need it most. Fix. */ | ||
268 | } | ||
269 | 263 | ||
270 | r1 = read_zsreg(channel, R1); | 264 | r1 = read_zsreg(channel, R1); |
271 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { | 265 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { |
@@ -303,8 +297,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | |||
303 | } | 297 | } |
304 | 298 | ||
305 | /* A real serial line, record the character and status. */ | 299 | /* A real serial line, record the character and status. */ |
306 | *tty->flip.char_buf_ptr = ch; | 300 | flag = TTY_NORMAL; |
307 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
308 | up->port.icount.rx++; | 301 | up->port.icount.rx++; |
309 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { | 302 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { |
310 | if (r1 & BRK_ABRT) { | 303 | if (r1 & BRK_ABRT) { |
@@ -321,28 +314,21 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | |||
321 | up->port.icount.overrun++; | 314 | up->port.icount.overrun++; |
322 | r1 &= up->port.read_status_mask; | 315 | r1 &= up->port.read_status_mask; |
323 | if (r1 & BRK_ABRT) | 316 | if (r1 & BRK_ABRT) |
324 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 317 | flag = TTY_BREAK; |
325 | else if (r1 & PAR_ERR) | 318 | else if (r1 & PAR_ERR) |
326 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 319 | flag = TTY_PARITY; |
327 | else if (r1 & CRC_ERR) | 320 | else if (r1 & CRC_ERR) |
328 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 321 | flag = TTY_FRAME; |
329 | } | 322 | } |
330 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 323 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
331 | goto next_char; | 324 | goto next_char; |
332 | 325 | ||
333 | if (up->port.ignore_status_mask == 0xff || | 326 | if (up->port.ignore_status_mask == 0xff || |
334 | (r1 & up->port.ignore_status_mask) == 0) { | 327 | (r1 & up->port.ignore_status_mask) == 0) |
335 | tty->flip.flag_buf_ptr++; | 328 | tty_insert_flip_char(tty, ch, flag); |
336 | tty->flip.char_buf_ptr++; | 329 | |
337 | tty->flip.count++; | 330 | if (r1 & Rx_OVR) |
338 | } | 331 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
339 | if ((r1 & Rx_OVR) && | ||
340 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
341 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
342 | tty->flip.flag_buf_ptr++; | ||
343 | tty->flip.char_buf_ptr++; | ||
344 | tty->flip.count++; | ||
345 | } | ||
346 | next_char: | 332 | next_char: |
347 | ch = readb(&channel->control); | 333 | ch = readb(&channel->control); |
348 | ZSDELAY(); | 334 | ZSDELAY(); |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index b0ecc7537ce5..b48066a64a7d 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -331,17 +331,12 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, | |||
331 | { | 331 | { |
332 | struct tty_struct *tty = up->port.info->tty; | 332 | struct tty_struct *tty = up->port.info->tty; |
333 | unsigned char ch; | 333 | unsigned char ch; |
334 | unsigned char flag; | ||
334 | int max_count = 256; | 335 | int max_count = 256; |
335 | 336 | ||
336 | do { | 337 | do { |
337 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
338 | tty->flip.work.func((void *)tty); | ||
339 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
340 | return; // if TTY_DONT_FLIP is set | ||
341 | } | ||
342 | ch = sio_in(up, SIORXB); | 338 | ch = sio_in(up, SIORXB); |
343 | *tty->flip.char_buf_ptr = ch; | 339 | flag = TTY_NORMAL; |
344 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
345 | up->port.icount.rx++; | 340 | up->port.icount.rx++; |
346 | 341 | ||
347 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 342 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
@@ -380,30 +375,24 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, | |||
380 | 375 | ||
381 | if (*status & UART_LSR_BI) { | 376 | if (*status & UART_LSR_BI) { |
382 | DEBUG_INTR("handling break...."); | 377 | DEBUG_INTR("handling break...."); |
383 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 378 | flag = TTY_BREAK; |
384 | } else if (*status & UART_LSR_PE) | 379 | } else if (*status & UART_LSR_PE) |
385 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 380 | flag = TTY_PARITY; |
386 | else if (*status & UART_LSR_FE) | 381 | else if (*status & UART_LSR_FE) |
387 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 382 | flag = TTY_FRAME; |
388 | } | 383 | } |
389 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 384 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
390 | goto ignore_char; | 385 | goto ignore_char; |
391 | if ((*status & up->port.ignore_status_mask) == 0) { | 386 | if ((*status & up->port.ignore_status_mask) == 0) |
392 | tty->flip.flag_buf_ptr++; | 387 | tty_insert_flip_char(tty, ch, flag); |
393 | tty->flip.char_buf_ptr++; | 388 | |
394 | tty->flip.count++; | 389 | if (*status & UART_LSR_OE) { |
395 | } | ||
396 | if ((*status & UART_LSR_OE) && | ||
397 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
398 | /* | 390 | /* |
399 | * Overrun is special, since it's reported | 391 | * Overrun is special, since it's reported |
400 | * immediately, and doesn't affect the current | 392 | * immediately, and doesn't affect the current |
401 | * character. | 393 | * character. |
402 | */ | 394 | */ |
403 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | 395 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
404 | tty->flip.flag_buf_ptr++; | ||
405 | tty->flip.char_buf_ptr++; | ||
406 | tty->flip.count++; | ||
407 | } | 396 | } |
408 | ignore_char: | 397 | ignore_char: |
409 | *status = serial_in(up, UART_LSR); | 398 | *status = serial_in(up, UART_LSR); |
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 47f7404cb045..f2a51e61eec7 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -313,7 +313,7 @@ static inline void receive_chars(struct mcf_serial *info) | |||
313 | { | 313 | { |
314 | volatile unsigned char *uartp; | 314 | volatile unsigned char *uartp; |
315 | struct tty_struct *tty = info->tty; | 315 | struct tty_struct *tty = info->tty; |
316 | unsigned char status, ch; | 316 | unsigned char status, ch, flag; |
317 | 317 | ||
318 | if (!tty) | 318 | if (!tty) |
319 | return; | 319 | return; |
@@ -321,10 +321,6 @@ static inline void receive_chars(struct mcf_serial *info) | |||
321 | uartp = info->addr; | 321 | uartp = info->addr; |
322 | 322 | ||
323 | while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { | 323 | while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { |
324 | |||
325 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
326 | break; | ||
327 | |||
328 | ch = uartp[MCFUART_URB]; | 324 | ch = uartp[MCFUART_URB]; |
329 | info->stats.rx++; | 325 | info->stats.rx++; |
330 | 326 | ||
@@ -335,29 +331,24 @@ static inline void receive_chars(struct mcf_serial *info) | |||
335 | } | 331 | } |
336 | #endif | 332 | #endif |
337 | 333 | ||
338 | tty->flip.count++; | 334 | flag = TTY_NORMAL; |
339 | if (status & MCFUART_USR_RXERR) { | 335 | if (status & MCFUART_USR_RXERR) { |
340 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; | 336 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; |
341 | if (status & MCFUART_USR_RXBREAK) { | 337 | if (status & MCFUART_USR_RXBREAK) { |
342 | info->stats.rxbreak++; | 338 | info->stats.rxbreak++; |
343 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 339 | flag = TTY_BREAK; |
344 | } else if (status & MCFUART_USR_RXPARITY) { | 340 | } else if (status & MCFUART_USR_RXPARITY) { |
345 | info->stats.rxparity++; | 341 | info->stats.rxparity++; |
346 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 342 | flag = TTY_PARITY; |
347 | } else if (status & MCFUART_USR_RXOVERRUN) { | 343 | } else if (status & MCFUART_USR_RXOVERRUN) { |
348 | info->stats.rxoverrun++; | 344 | info->stats.rxoverrun++; |
349 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 345 | flag = TTY_OVERRUN; |
350 | } else if (status & MCFUART_USR_RXFRAMING) { | 346 | } else if (status & MCFUART_USR_RXFRAMING) { |
351 | info->stats.rxframing++; | 347 | info->stats.rxframing++; |
352 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 348 | flag = TTY_FRAME; |
353 | } else { | ||
354 | /* This should never happen... */ | ||
355 | *tty->flip.flag_buf_ptr++ = 0; | ||
356 | } | 349 | } |
357 | } else { | ||
358 | *tty->flip.flag_buf_ptr++ = 0; | ||
359 | } | 350 | } |
360 | *tty->flip.char_buf_ptr++ = ch; | 351 | tty_insert_flip_char(tty, ch, flag); |
361 | } | 352 | } |
362 | 353 | ||
363 | schedule_work(&tty->flip.work); | 354 | schedule_work(&tty->flip.work); |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 1288d6203e94..61dd17d7bace 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -405,17 +405,13 @@ static inline int | |||
405 | mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) | 405 | mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) |
406 | { | 406 | { |
407 | struct tty_struct *tty = port->info->tty; | 407 | struct tty_struct *tty = port->info->tty; |
408 | unsigned char ch; | 408 | unsigned char ch, flag; |
409 | unsigned short status; | 409 | unsigned short status; |
410 | 410 | ||
411 | /* While we can read, do so ! */ | 411 | /* While we can read, do so ! */ |
412 | while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & | 412 | while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & |
413 | MPC52xx_PSC_SR_RXRDY) { | 413 | MPC52xx_PSC_SR_RXRDY) { |
414 | 414 | ||
415 | /* If we are full, just stop reading */ | ||
416 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
417 | break; | ||
418 | |||
419 | /* Get the char */ | 415 | /* Get the char */ |
420 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); | 416 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); |
421 | 417 | ||
@@ -428,45 +424,35 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) | |||
428 | #endif | 424 | #endif |
429 | 425 | ||
430 | /* Store it */ | 426 | /* Store it */ |
431 | *tty->flip.char_buf_ptr = ch; | 427 | |
432 | *tty->flip.flag_buf_ptr = 0; | 428 | flag = TTY_NORMAL; |
433 | port->icount.rx++; | 429 | port->icount.rx++; |
434 | 430 | ||
435 | if ( status & (MPC52xx_PSC_SR_PE | | 431 | if ( status & (MPC52xx_PSC_SR_PE | |
436 | MPC52xx_PSC_SR_FE | | 432 | MPC52xx_PSC_SR_FE | |
437 | MPC52xx_PSC_SR_RB | | 433 | MPC52xx_PSC_SR_RB) ) { |
438 | MPC52xx_PSC_SR_OE) ) { | ||
439 | 434 | ||
440 | if (status & MPC52xx_PSC_SR_RB) { | 435 | if (status & MPC52xx_PSC_SR_RB) { |
441 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 436 | flag = TTY_BREAK; |
442 | uart_handle_break(port); | 437 | uart_handle_break(port); |
443 | } else if (status & MPC52xx_PSC_SR_PE) | 438 | } else if (status & MPC52xx_PSC_SR_PE) |
444 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 439 | flag = TTY_PARITY; |
445 | else if (status & MPC52xx_PSC_SR_FE) | 440 | else if (status & MPC52xx_PSC_SR_FE) |
446 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 441 | flag = TTY_FRAME; |
447 | if (status & MPC52xx_PSC_SR_OE) { | ||
448 | /* | ||
449 | * Overrun is special, since it's | ||
450 | * reported immediately, and doesn't | ||
451 | * affect the current character | ||
452 | */ | ||
453 | if (tty->flip.count < (TTY_FLIPBUF_SIZE-1)) { | ||
454 | tty->flip.flag_buf_ptr++; | ||
455 | tty->flip.char_buf_ptr++; | ||
456 | tty->flip.count++; | ||
457 | } | ||
458 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
459 | } | ||
460 | 442 | ||
461 | /* Clear error condition */ | 443 | /* Clear error condition */ |
462 | out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); | 444 | out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); |
463 | 445 | ||
464 | } | 446 | } |
465 | 447 | tty_insert_flip_char(tty, ch, flag); | |
466 | tty->flip.char_buf_ptr++; | 448 | if (status & MPC52xx_PSC_SR_OE) { |
467 | tty->flip.flag_buf_ptr++; | 449 | /* |
468 | tty->flip.count++; | 450 | * Overrun is special, since it's |
469 | 451 | * reported immediately, and doesn't | |
452 | * affect the current character | ||
453 | */ | ||
454 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
455 | } | ||
470 | } | 456 | } |
471 | 457 | ||
472 | tty_flip_buffer_push(tty); | 458 | tty_flip_buffer_push(tty); |
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 8f83e4007ecd..0ca83ac31d07 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -769,12 +769,12 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs) | |||
769 | bytes_in = be16_to_cpu(rxre->bytecnt); | 769 | bytes_in = be16_to_cpu(rxre->bytecnt); |
770 | 770 | ||
771 | /* Following use of tty struct directly is deprecated */ | 771 | /* Following use of tty struct directly is deprecated */ |
772 | if (unlikely((tty->flip.count + bytes_in) >= TTY_FLIPBUF_SIZE)){ | 772 | if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) { |
773 | if (tty->low_latency) | 773 | if (tty->low_latency) |
774 | tty_flip_buffer_push(tty); | 774 | tty_flip_buffer_push(tty); |
775 | /* | 775 | /* |
776 | * If this failed then we will throw awa the bytes | 776 | * If this failed then we will throw away the bytes |
777 | * but mst do so to clear interrupts. | 777 | * but must do so to clear interrupts. |
778 | */ | 778 | */ |
779 | } | 779 | } |
780 | 780 | ||
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 7633132a10aa..4e49168c3176 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
@@ -223,11 +223,6 @@ static void mux_read(struct uart_port *port) | |||
223 | if (MUX_EOFIFO(data)) | 223 | if (MUX_EOFIFO(data)) |
224 | break; | 224 | break; |
225 | 225 | ||
226 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
227 | continue; | ||
228 | |||
229 | *tty->flip.char_buf_ptr = data & 0xffu; | ||
230 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
231 | port->icount.rx++; | 226 | port->icount.rx++; |
232 | 227 | ||
233 | if (MUX_BREAK(data)) { | 228 | if (MUX_BREAK(data)) { |
@@ -239,9 +234,7 @@ static void mux_read(struct uart_port *port) | |||
239 | if (uart_handle_sysrq_char(port, data & 0xffu, NULL)) | 234 | if (uart_handle_sysrq_char(port, data & 0xffu, NULL)) |
240 | continue; | 235 | continue; |
241 | 236 | ||
242 | tty->flip.flag_buf_ptr++; | 237 | tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); |
243 | tty->flip.char_buf_ptr++; | ||
244 | tty->flip.count++; | ||
245 | } | 238 | } |
246 | 239 | ||
247 | if (start_count != port->icount.rx) { | 240 | if (start_count != port->icount.rx) { |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index ea24129eb6b9..f330d6c0e0df 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -210,10 +210,9 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
210 | struct pt_regs *regs) | 210 | struct pt_regs *regs) |
211 | { | 211 | { |
212 | struct tty_struct *tty = NULL; | 212 | struct tty_struct *tty = NULL; |
213 | unsigned char ch, r1, drop, error; | 213 | unsigned char ch, r1, drop, error, flag; |
214 | int loops = 0; | 214 | int loops = 0; |
215 | 215 | ||
216 | retry: | ||
217 | /* The interrupt can be enabled when the port isn't open, typically | 216 | /* The interrupt can be enabled when the port isn't open, typically |
218 | * that happens when using one port is open and the other closed (stale | 217 | * that happens when using one port is open and the other closed (stale |
219 | * interrupt) or when one port is used as a console. | 218 | * interrupt) or when one port is used as a console. |
@@ -246,20 +245,6 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
246 | error = 0; | 245 | error = 0; |
247 | drop = 0; | 246 | drop = 0; |
248 | 247 | ||
249 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
250 | /* Have to drop the lock here */ | ||
251 | pmz_debug("pmz: flip overflow\n"); | ||
252 | spin_unlock(&uap->port.lock); | ||
253 | tty->flip.work.func((void *)tty); | ||
254 | spin_lock(&uap->port.lock); | ||
255 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
256 | drop = 1; | ||
257 | if (ZS_IS_ASLEEP(uap)) | ||
258 | return NULL; | ||
259 | if (!ZS_IS_OPEN(uap)) | ||
260 | goto retry; | ||
261 | } | ||
262 | |||
263 | r1 = read_zsreg(uap, R1); | 248 | r1 = read_zsreg(uap, R1); |
264 | ch = read_zsdata(uap); | 249 | ch = read_zsdata(uap); |
265 | 250 | ||
@@ -295,8 +280,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
295 | if (drop) | 280 | if (drop) |
296 | goto next_char; | 281 | goto next_char; |
297 | 282 | ||
298 | *tty->flip.char_buf_ptr = ch; | 283 | flag = TTY_NORMAL; |
299 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
300 | uap->port.icount.rx++; | 284 | uap->port.icount.rx++; |
301 | 285 | ||
302 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { | 286 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { |
@@ -316,26 +300,19 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
316 | uap->port.icount.overrun++; | 300 | uap->port.icount.overrun++; |
317 | r1 &= uap->port.read_status_mask; | 301 | r1 &= uap->port.read_status_mask; |
318 | if (r1 & BRK_ABRT) | 302 | if (r1 & BRK_ABRT) |
319 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 303 | flag = TTY_BREAK; |
320 | else if (r1 & PAR_ERR) | 304 | else if (r1 & PAR_ERR) |
321 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 305 | flag = TTY_PARITY; |
322 | else if (r1 & CRC_ERR) | 306 | else if (r1 & CRC_ERR) |
323 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 307 | flag = TTY_FRAME; |
324 | } | 308 | } |
325 | 309 | ||
326 | if (uap->port.ignore_status_mask == 0xff || | 310 | if (uap->port.ignore_status_mask == 0xff || |
327 | (r1 & uap->port.ignore_status_mask) == 0) { | 311 | (r1 & uap->port.ignore_status_mask) == 0) { |
328 | tty->flip.flag_buf_ptr++; | 312 | tty_insert_flip_char(tty, ch, flag); |
329 | tty->flip.char_buf_ptr++; | ||
330 | tty->flip.count++; | ||
331 | } | ||
332 | if ((r1 & Rx_OVR) && | ||
333 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
334 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
335 | tty->flip.flag_buf_ptr++; | ||
336 | tty->flip.char_buf_ptr++; | ||
337 | tty->flip.count++; | ||
338 | } | 313 | } |
314 | if (r1 & Rx_OVR) | ||
315 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
339 | next_char: | 316 | next_char: |
340 | /* We can get stuck in an infinite loop getting char 0 when the | 317 | /* We can get stuck in an infinite loop getting char 0 when the |
341 | * line is in a wrong HW state, we break that here. | 318 | * line is in a wrong HW state, we break that here. |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index cc998b99a19f..10535f00301f 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -107,14 +107,6 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs) | |||
107 | int max_count = 256; | 107 | int max_count = 256; |
108 | 108 | ||
109 | do { | 109 | do { |
110 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
111 | if (tty->low_latency) | ||
112 | tty_flip_buffer_push(tty); | ||
113 | /* | ||
114 | * If this failed then we will throw away the | ||
115 | * bytes but must do so to clear interrupts | ||
116 | */ | ||
117 | } | ||
118 | ch = serial_in(up, UART_RX); | 110 | ch = serial_in(up, UART_RX); |
119 | flag = TTY_NORMAL; | 111 | flag = TTY_NORMAL; |
120 | up->port.icount.rx++; | 112 | up->port.icount.rx++; |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index fe83ce6fef52..eb4883efb7c6 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -323,16 +323,6 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs) | |||
323 | if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) | 323 | if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) |
324 | break; | 324 | break; |
325 | 325 | ||
326 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
327 | if (tty->low_latency) | ||
328 | tty_flip_buffer_push(tty); | ||
329 | |||
330 | /* | ||
331 | * If this failed then we will throw away the | ||
332 | * bytes but must do so to clear interrupts | ||
333 | */ | ||
334 | } | ||
335 | |||
336 | uerstat = rd_regl(port, S3C2410_UERSTAT); | 326 | uerstat = rd_regl(port, S3C2410_UERSTAT); |
337 | ch = rd_regb(port, S3C2410_URXH); | 327 | ch = rd_regb(port, S3C2410_URXH); |
338 | 328 | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 25a086458ab9..1bd93168f504 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -201,8 +201,6 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) | |||
201 | while (status & UTSR1_TO_SM(UTSR1_RNE)) { | 201 | while (status & UTSR1_TO_SM(UTSR1_RNE)) { |
202 | ch = UART_GET_CHAR(sport); | 202 | ch = UART_GET_CHAR(sport); |
203 | 203 | ||
204 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
205 | goto ignore_char; | ||
206 | sport->port.icount.rx++; | 204 | sport->port.icount.rx++; |
207 | 205 | ||
208 | flg = TTY_NORMAL; | 206 | flg = TTY_NORMAL; |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d01dbe5da3b9..d4a1f0e798c1 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -148,15 +148,6 @@ lh7a40xuart_rx_chars (struct uart_port* port) | |||
148 | unsigned int data, flag;/* Received data and status */ | 148 | unsigned int data, flag;/* Received data and status */ |
149 | 149 | ||
150 | while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { | 150 | while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { |
151 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
152 | if (tty->low_latency) | ||
153 | tty_flip_buffer_push(tty); | ||
154 | /* | ||
155 | * If this failed then we will throw away the | ||
156 | * bytes but must do so to clear interrupts | ||
157 | */ | ||
158 | } | ||
159 | |||
160 | data = UR (port, UART_R_DATA); | 151 | data = UR (port, UART_R_DATA); |
161 | flag = TTY_NORMAL; | 152 | flag = TTY_NORMAL; |
162 | ++port->icount.rx; | 153 | ++port->icount.rx; |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 995d9dd9ddd5..fdd1f1915a42 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -303,17 +303,6 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
303 | char flag; | 303 | char flag; |
304 | 304 | ||
305 | do { | 305 | do { |
306 | /* The following is not allowed by the tty layer and | ||
307 | unsafe. It should be fixed ASAP */ | ||
308 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
309 | if (tty->low_latency) { | ||
310 | spin_unlock(&up->port.lock); | ||
311 | tty_flip_buffer_push(tty); | ||
312 | spin_lock(&up->port.lock); | ||
313 | } | ||
314 | /* If this failed then we will throw away the | ||
315 | bytes but must do so to clear interrupts */ | ||
316 | } | ||
317 | ch = sio_in(up, TXX9_SIRFIFO); | 306 | ch = sio_in(up, TXX9_SIRFIFO); |
318 | flag = TTY_NORMAL; | 307 | flag = TTY_NORMAL; |
319 | up->port.icount.rx++; | 308 | up->port.icount.rx++; |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 430754ebac8a..a9e070759628 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -482,6 +482,7 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
482 | struct tty_struct *tty = port->info->tty; | 482 | struct tty_struct *tty = port->info->tty; |
483 | int i, count, copied = 0; | 483 | int i, count, copied = 0; |
484 | unsigned short status; | 484 | unsigned short status; |
485 | unsigned char flag; | ||
485 | 486 | ||
486 | status = sci_in(port, SCxSR); | 487 | status = sci_in(port, SCxSR); |
487 | if (!(status & SCxSR_RDxF(port))) | 488 | if (!(status & SCxSR_RDxF(port))) |
@@ -499,8 +500,7 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
499 | #endif | 500 | #endif |
500 | 501 | ||
501 | /* Don't copy more bytes than there is room for in the buffer */ | 502 | /* Don't copy more bytes than there is room for in the buffer */ |
502 | if (tty->flip.count + count > TTY_FLIPBUF_SIZE) | 503 | count = tty_buffer_request_room(tty, count); |
503 | count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
504 | 504 | ||
505 | /* If for any reason we can't copy more data, we're done! */ | 505 | /* If for any reason we can't copy more data, we're done! */ |
506 | if (count == 0) | 506 | if (count == 0) |
@@ -512,8 +512,7 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
512 | || uart_handle_sysrq_char(port, c, regs)) { | 512 | || uart_handle_sysrq_char(port, c, regs)) { |
513 | count = 0; | 513 | count = 0; |
514 | } else { | 514 | } else { |
515 | tty->flip.char_buf_ptr[0] = c; | 515 | tty_insert_flip_char(tty, c, TTY_NORMAL); |
516 | tty->flip.flag_buf_ptr[0] = TTY_NORMAL; | ||
517 | } | 516 | } |
518 | } else { | 517 | } else { |
519 | for (i=0; i<count; i++) { | 518 | for (i=0; i<count; i++) { |
@@ -542,26 +541,21 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
542 | } | 541 | } |
543 | 542 | ||
544 | /* Store data and status */ | 543 | /* Store data and status */ |
545 | tty->flip.char_buf_ptr[i] = c; | ||
546 | if (status&SCxSR_FER(port)) { | 544 | if (status&SCxSR_FER(port)) { |
547 | tty->flip.flag_buf_ptr[i] = TTY_FRAME; | 545 | flag = TTY_FRAME; |
548 | pr_debug("sci: frame error\n"); | 546 | pr_debug("sci: frame error\n"); |
549 | } else if (status&SCxSR_PER(port)) { | 547 | } else if (status&SCxSR_PER(port)) { |
550 | tty->flip.flag_buf_ptr[i] = TTY_PARITY; | 548 | flag = TTY_PARITY; |
551 | pr_debug("sci: parity error\n"); | 549 | pr_debug("sci: parity error\n"); |
552 | } else { | 550 | } else |
553 | tty->flip.flag_buf_ptr[i] = TTY_NORMAL; | 551 | flag = TTY_NORMAL; |
554 | } | 552 | tty_insert_flip_char(tty, c, flag); |
555 | } | 553 | } |
556 | } | 554 | } |
557 | 555 | ||
558 | sci_in(port, SCxSR); /* dummy read */ | 556 | sci_in(port, SCxSR); /* dummy read */ |
559 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 557 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
560 | 558 | ||
561 | /* Update the kernel buffer end */ | ||
562 | tty->flip.count += count; | ||
563 | tty->flip.char_buf_ptr += count; | ||
564 | tty->flip.flag_buf_ptr += count; | ||
565 | copied += count; | 559 | copied += count; |
566 | port->icount.rx += count; | 560 | port->icount.rx += count; |
567 | } | 561 | } |
@@ -608,48 +602,45 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
608 | unsigned short status = sci_in(port, SCxSR); | 602 | unsigned short status = sci_in(port, SCxSR); |
609 | struct tty_struct *tty = port->info->tty; | 603 | struct tty_struct *tty = port->info->tty; |
610 | 604 | ||
611 | if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { | 605 | if (status&SCxSR_ORER(port)) { |
612 | /* overrun error */ | 606 | /* overrun error */ |
613 | copied++; | 607 | if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) |
614 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 608 | copied++; |
615 | pr_debug("sci: overrun error\n"); | 609 | pr_debug("sci: overrun error\n"); |
616 | } | 610 | } |
617 | 611 | ||
618 | if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { | 612 | if (status&SCxSR_FER(port)) { |
619 | if (sci_rxd_in(port) == 0) { | 613 | if (sci_rxd_in(port) == 0) { |
620 | /* Notify of BREAK */ | 614 | /* Notify of BREAK */ |
621 | struct sci_port * sci_port = (struct sci_port *)port; | 615 | struct sci_port * sci_port = (struct sci_port *)port; |
622 | if(!sci_port->break_flag) { | 616 | if(!sci_port->break_flag) { |
623 | sci_port->break_flag = 1; | 617 | sci_port->break_flag = 1; |
624 | sci_schedule_break_timer((struct sci_port *)port); | 618 | sci_schedule_break_timer((struct sci_port *)port); |
625 | /* Do sysrq handling. */ | 619 | /* Do sysrq handling. */ |
626 | if(uart_handle_break(port)) { | 620 | if(uart_handle_break(port)) |
627 | return 0; | 621 | return 0; |
628 | } | ||
629 | pr_debug("sci: BREAK detected\n"); | 622 | pr_debug("sci: BREAK detected\n"); |
630 | copied++; | 623 | if(tty_insert_flip_char(tty, 0, TTY_BREAK)) |
631 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 624 | copied++; |
632 | } | 625 | } |
633 | } | 626 | } |
634 | else { | 627 | else { |
635 | /* frame error */ | 628 | /* frame error */ |
636 | copied++; | 629 | if(tty_insert_flip_char(tty, 0, TTY_FRAME)) |
637 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 630 | copied++; |
638 | pr_debug("sci: frame error\n"); | 631 | pr_debug("sci: frame error\n"); |
639 | } | 632 | } |
640 | } | 633 | } |
641 | 634 | ||
642 | if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { | 635 | if (status&SCxSR_PER(port)) { |
636 | if(tty_insert_flip_char(tty, 0, TTY_PARITY)) | ||
637 | copied++; | ||
643 | /* parity error */ | 638 | /* parity error */ |
644 | copied++; | ||
645 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | ||
646 | pr_debug("sci: parity error\n"); | 639 | pr_debug("sci: parity error\n"); |
647 | } | 640 | } |
648 | 641 | ||
649 | if (copied) { | 642 | if (copied) |
650 | tty->flip.count += copied; | ||
651 | tty_flip_buffer_push(tty); | 643 | tty_flip_buffer_push(tty); |
652 | } | ||
653 | 644 | ||
654 | return copied; | 645 | return copied; |
655 | } | 646 | } |
@@ -661,15 +652,14 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
661 | struct tty_struct *tty = port->info->tty; | 652 | struct tty_struct *tty = port->info->tty; |
662 | struct sci_port *s = &sci_ports[port->line]; | 653 | struct sci_port *s = &sci_ports[port->line]; |
663 | 654 | ||
664 | if (!s->break_flag && status & SCxSR_BRK(port) && | 655 | if (!s->break_flag && status & SCxSR_BRK(port)) |
665 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
666 | #if defined(CONFIG_CPU_SH3) | 656 | #if defined(CONFIG_CPU_SH3) |
667 | /* Debounce break */ | 657 | /* Debounce break */ |
668 | s->break_flag = 1; | 658 | s->break_flag = 1; |
669 | #endif | 659 | #endif |
670 | /* Notify of BREAK */ | 660 | /* Notify of BREAK */ |
671 | copied++; | 661 | if(tty_insert_flip_char(tty, 0, TTY_BREAK)) |
672 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 662 | copied++; |
673 | pr_debug("sci: BREAK detected\n"); | 663 | pr_debug("sci: BREAK detected\n"); |
674 | } | 664 | } |
675 | 665 | ||
@@ -677,19 +667,15 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
677 | /* XXX: Handle SCIF overrun error */ | 667 | /* XXX: Handle SCIF overrun error */ |
678 | if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { | 668 | if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { |
679 | sci_out(port, SCLSR, 0); | 669 | sci_out(port, SCLSR, 0); |
680 | if(tty->flip.count<TTY_FLIPBUF_SIZE) { | 670 | if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { |
681 | copied++; | 671 | copied++; |
682 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | ||
683 | pr_debug("sci: overrun error\n"); | 672 | pr_debug("sci: overrun error\n"); |
684 | } | 673 | } |
685 | } | 674 | } |
686 | #endif | 675 | #endif |
687 | 676 | ||
688 | if (copied) { | 677 | if (copied) |
689 | tty->flip.count += copied; | ||
690 | tty_flip_buffer_push(tty); | 678 | tty_flip_buffer_push(tty); |
691 | } | ||
692 | |||
693 | return copied; | 679 | return copied; |
694 | } | 680 | } |
695 | 681 | ||
@@ -732,12 +718,9 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs) | |||
732 | struct tty_struct *tty = port->info->tty; | 718 | struct tty_struct *tty = port->info->tty; |
733 | 719 | ||
734 | sci_out(port, SCLSR, 0); | 720 | sci_out(port, SCLSR, 0); |
735 | if(tty->flip.count<TTY_FLIPBUF_SIZE) { | 721 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
736 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 722 | tty_flip_buffer_push(tty); |
737 | tty->flip.count++; | 723 | pr_debug("scif: overrun error\n"); |
738 | tty_flip_buffer_push(tty); | ||
739 | pr_debug("scif: overrun error\n"); | ||
740 | } | ||
741 | } | 724 | } |
742 | #endif | 725 | #endif |
743 | sci_rx_interrupt(irq, ptr, regs); | 726 | sci_rx_interrupt(irq, ptr, regs); |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 313f9df24a2d..5468e5a767e2 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -519,11 +519,7 @@ sn_receive_chars(struct sn_cons_port *port, struct pt_regs *regs, | |||
519 | 519 | ||
520 | /* record the character to pass up to the tty layer */ | 520 | /* record the character to pass up to the tty layer */ |
521 | if (tty) { | 521 | if (tty) { |
522 | *tty->flip.char_buf_ptr = ch; | 522 | if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) |
523 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
524 | tty->flip.char_buf_ptr++; | ||
525 | tty->flip.count++; | ||
526 | if (tty->flip.count == TTY_FLIPBUF_SIZE) | ||
527 | break; | 523 | break; |
528 | } | 524 | } |
529 | port->sc_port.icount.rx++; | 525 | port->sc_port.icount.rx++; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index ba9381fd3f2d..7e773ff76c61 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -159,21 +159,14 @@ receive_chars(struct uart_sunsab_port *up, | |||
159 | saw_console_brk = 1; | 159 | saw_console_brk = 1; |
160 | 160 | ||
161 | for (i = 0; i < count; i++) { | 161 | for (i = 0; i < count; i++) { |
162 | unsigned char ch = buf[i]; | 162 | unsigned char ch = buf[i], flag; |
163 | 163 | ||
164 | if (tty == NULL) { | 164 | if (tty == NULL) { |
165 | uart_handle_sysrq_char(&up->port, ch, regs); | 165 | uart_handle_sysrq_char(&up->port, ch, regs); |
166 | continue; | 166 | continue; |
167 | } | 167 | } |
168 | 168 | ||
169 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | 169 | flag = TTY_NORMAL; |
170 | tty->flip.work.func((void *)tty); | ||
171 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
172 | return tty; // if TTY_DONT_FLIP is set | ||
173 | } | ||
174 | |||
175 | *tty->flip.char_buf_ptr = ch; | ||
176 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
177 | up->port.icount.rx++; | 170 | up->port.icount.rx++; |
178 | 171 | ||
179 | if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR | | 172 | if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR | |
@@ -209,34 +202,21 @@ receive_chars(struct uart_sunsab_port *up, | |||
209 | stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff); | 202 | stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff); |
210 | 203 | ||
211 | if (stat->sreg.isr1 & SAB82532_ISR1_BRK) { | 204 | if (stat->sreg.isr1 & SAB82532_ISR1_BRK) { |
212 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 205 | flag = TTY_BREAK; |
213 | } else if (stat->sreg.isr0 & SAB82532_ISR0_PERR) | 206 | } else if (stat->sreg.isr0 & SAB82532_ISR0_PERR) |
214 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 207 | flag = TTY_PARITY; |
215 | else if (stat->sreg.isr0 & SAB82532_ISR0_FERR) | 208 | else if (stat->sreg.isr0 & SAB82532_ISR0_FERR) |
216 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 209 | flag = TTY_FRAME; |
217 | } | 210 | } |
218 | 211 | ||
219 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 212 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
220 | continue; | 213 | continue; |
221 | 214 | ||
222 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && | 215 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && |
223 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0){ | 216 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) |
224 | tty->flip.flag_buf_ptr++; | 217 | tty_insert_flip_char(tty, ch, flag); |
225 | tty->flip.char_buf_ptr++; | 218 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
226 | tty->flip.count++; | 219 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
227 | } | ||
228 | if ((stat->sreg.isr0 & SAB82532_ISR0_RFO) && | ||
229 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
230 | /* | ||
231 | * Overrun is special, since it's reported | ||
232 | * immediately, and doesn't affect the current | ||
233 | * character. | ||
234 | */ | ||
235 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
236 | tty->flip.flag_buf_ptr++; | ||
237 | tty->flip.char_buf_ptr++; | ||
238 | tty->flip.count++; | ||
239 | } | ||
240 | } | 220 | } |
241 | 221 | ||
242 | if (saw_console_brk) | 222 | if (saw_console_brk) |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index f0738533f39a..9a3665b34d97 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -323,19 +323,13 @@ static _INLINE_ struct tty_struct * | |||
323 | receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) | 323 | receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) |
324 | { | 324 | { |
325 | struct tty_struct *tty = up->port.info->tty; | 325 | struct tty_struct *tty = up->port.info->tty; |
326 | unsigned char ch; | 326 | unsigned char ch, flag; |
327 | int max_count = 256; | 327 | int max_count = 256; |
328 | int saw_console_brk = 0; | 328 | int saw_console_brk = 0; |
329 | 329 | ||
330 | do { | 330 | do { |
331 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
332 | tty->flip.work.func((void *)tty); | ||
333 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
334 | return tty; // if TTY_DONT_FLIP is set | ||
335 | } | ||
336 | ch = serial_inp(up, UART_RX); | 331 | ch = serial_inp(up, UART_RX); |
337 | *tty->flip.char_buf_ptr = ch; | 332 | flag = TTY_NORMAL; |
338 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
339 | up->port.icount.rx++; | 333 | up->port.icount.rx++; |
340 | 334 | ||
341 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 335 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
@@ -377,31 +371,23 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs | |||
377 | } | 371 | } |
378 | 372 | ||
379 | if (*status & UART_LSR_BI) { | 373 | if (*status & UART_LSR_BI) { |
380 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 374 | flag = TTY_BREAK; |
381 | } else if (*status & UART_LSR_PE) | 375 | } else if (*status & UART_LSR_PE) |
382 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 376 | flag = TTY_PARITY; |
383 | else if (*status & UART_LSR_FE) | 377 | else if (*status & UART_LSR_FE) |
384 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 378 | flag = TTY_FRAME; |
385 | } | 379 | } |
386 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 380 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
387 | goto ignore_char; | 381 | goto ignore_char; |
388 | if ((*status & up->port.ignore_status_mask) == 0) { | 382 | if ((*status & up->port.ignore_status_mask) == 0) |
389 | tty->flip.flag_buf_ptr++; | 383 | tty_insert_flip_char(tty, ch, flag); |
390 | tty->flip.char_buf_ptr++; | 384 | if (*status & UART_LSR_OE) |
391 | tty->flip.count++; | ||
392 | } | ||
393 | if ((*status & UART_LSR_OE) && | ||
394 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
395 | /* | 385 | /* |
396 | * Overrun is special, since it's reported | 386 | * Overrun is special, since it's reported |
397 | * immediately, and doesn't affect the current | 387 | * immediately, and doesn't affect the current |
398 | * character. | 388 | * character. |
399 | */ | 389 | */ |
400 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | 390 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
401 | tty->flip.flag_buf_ptr++; | ||
402 | tty->flip.char_buf_ptr++; | ||
403 | tty->flip.count++; | ||
404 | } | ||
405 | ignore_char: | 391 | ignore_char: |
406 | *status = serial_inp(up, UART_LSR); | 392 | *status = serial_inp(up, UART_LSR); |
407 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 393 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 7653d6cf05af..3c72484adea7 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -319,7 +319,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
319 | struct pt_regs *regs) | 319 | struct pt_regs *regs) |
320 | { | 320 | { |
321 | struct tty_struct *tty; | 321 | struct tty_struct *tty; |
322 | unsigned char ch, r1; | 322 | unsigned char ch, r1, flag; |
323 | 323 | ||
324 | tty = NULL; | 324 | tty = NULL; |
325 | if (up->port.info != NULL && /* Unopened serial console */ | 325 | if (up->port.info != NULL && /* Unopened serial console */ |
@@ -362,19 +362,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
362 | continue; | 362 | continue; |
363 | } | 363 | } |
364 | 364 | ||
365 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
366 | tty->flip.work.func((void *)tty); | ||
367 | /* | ||
368 | * The 8250 bails out of the loop here, | ||
369 | * but we need to read everything, or die. | ||
370 | */ | ||
371 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
372 | continue; | ||
373 | } | ||
374 | |||
375 | /* A real serial line, record the character and status. */ | 365 | /* A real serial line, record the character and status. */ |
376 | *tty->flip.char_buf_ptr = ch; | 366 | flag = TTY_NORMAL; |
377 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
378 | up->port.icount.rx++; | 367 | up->port.icount.rx++; |
379 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { | 368 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { |
380 | if (r1 & BRK_ABRT) { | 369 | if (r1 & BRK_ABRT) { |
@@ -391,28 +380,21 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
391 | up->port.icount.overrun++; | 380 | up->port.icount.overrun++; |
392 | r1 &= up->port.read_status_mask; | 381 | r1 &= up->port.read_status_mask; |
393 | if (r1 & BRK_ABRT) | 382 | if (r1 & BRK_ABRT) |
394 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 383 | flag = TTY_BREAK; |
395 | else if (r1 & PAR_ERR) | 384 | else if (r1 & PAR_ERR) |
396 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 385 | flag = TTY_PARITY; |
397 | else if (r1 & CRC_ERR) | 386 | else if (r1 & CRC_ERR) |
398 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 387 | flag = TTY_FRAME; |
399 | } | 388 | } |
400 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 389 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
401 | continue; | 390 | continue; |
402 | 391 | ||
403 | if (up->port.ignore_status_mask == 0xff || | 392 | if (up->port.ignore_status_mask == 0xff || |
404 | (r1 & up->port.ignore_status_mask) == 0) { | 393 | (r1 & up->port.ignore_status_mask) == 0) { |
405 | tty->flip.flag_buf_ptr++; | 394 | tty_insert_flip_char(tty, ch, flag); |
406 | tty->flip.char_buf_ptr++; | ||
407 | tty->flip.count++; | ||
408 | } | ||
409 | if ((r1 & Rx_OVR) && | ||
410 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
411 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
412 | tty->flip.flag_buf_ptr++; | ||
413 | tty->flip.char_buf_ptr++; | ||
414 | tty->flip.count++; | ||
415 | } | 395 | } |
396 | if (r1 & Rx_OVR) | ||
397 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
416 | } | 398 | } |
417 | 399 | ||
418 | return tty; | 400 | return tty; |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 865d4dea65df..0a28deeb098d 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -371,11 +371,6 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status, | |||
371 | lsr = *status; | 371 | lsr = *status; |
372 | 372 | ||
373 | do { | 373 | do { |
374 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
375 | if (tty->low_latency) | ||
376 | tty_flip_buffer_push(tty); | ||
377 | } | ||
378 | |||
379 | ch = siu_read(port, UART_RX); | 374 | ch = siu_read(port, UART_RX); |
380 | port->icount.rx++; | 375 | port->icount.rx++; |
381 | flag = TTY_NORMAL; | 376 | flag = TTY_NORMAL; |