diff options
107 files changed, 1005 insertions, 1465 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index cd13b91b9ff6..ab0d0b170816 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -186,9 +186,6 @@ static void tty_receive_char(struct tty_struct *tty, char ch) | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | if((tty->flip.flag_buf_ptr == NULL) || | ||
190 | (tty->flip.char_buf_ptr == NULL)) | ||
191 | return; | ||
192 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 189 | tty_insert_flip_char(tty, ch, TTY_NORMAL); |
193 | } | 190 | } |
194 | 191 | ||
@@ -653,8 +650,7 @@ void chan_interrupt(struct list_head *chans, struct work_struct *task, | |||
653 | chan = list_entry(ele, struct chan, list); | 650 | chan = list_entry(ele, struct chan, list); |
654 | if(!chan->input || (chan->ops->read == NULL)) continue; | 651 | if(!chan->input || (chan->ops->read == NULL)) continue; |
655 | do { | 652 | do { |
656 | if((tty != NULL) && | 653 | if (tty && !tty_buffer_request_room(tty, 1)) { |
657 | (tty->flip.count >= TTY_FLIPBUF_SIZE)){ | ||
658 | schedule_delayed_work(task, 1); | 654 | schedule_delayed_work(task, 1); |
659 | goto out; | 655 | goto out; |
660 | } | 656 | } |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 573ff6c1be5f..613673b12fa6 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -279,6 +279,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
279 | 279 | ||
280 | tty->disc_data = hu; | 280 | tty->disc_data = hu; |
281 | hu->tty = tty; | 281 | hu->tty = tty; |
282 | tty->receive_room = 65536; | ||
282 | 283 | ||
283 | spin_lock_init(&hu->rx_lock); | 284 | spin_lock_init(&hu->rx_lock); |
284 | 285 | ||
@@ -348,20 +349,6 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) | |||
348 | hci_uart_tx_wakeup(hu); | 349 | hci_uart_tx_wakeup(hu); |
349 | } | 350 | } |
350 | 351 | ||
351 | /* hci_uart_tty_room() | ||
352 | * | ||
353 | * Callback function from tty driver. Return the amount of | ||
354 | * space left in the receiver's buffer to decide if remote | ||
355 | * transmitter is to be throttled. | ||
356 | * | ||
357 | * Arguments: tty pointer to associated tty instance data | ||
358 | * Return Value: number of bytes left in receive buffer | ||
359 | */ | ||
360 | static int hci_uart_tty_room (struct tty_struct *tty) | ||
361 | { | ||
362 | return 65536; | ||
363 | } | ||
364 | |||
365 | /* hci_uart_tty_receive() | 352 | /* hci_uart_tty_receive() |
366 | * | 353 | * |
367 | * Called by tty low level driver when receive data is | 354 | * Called by tty low level driver when receive data is |
@@ -544,7 +531,6 @@ static int __init hci_uart_init(void) | |||
544 | hci_uart_ldisc.write = hci_uart_tty_write; | 531 | hci_uart_ldisc.write = hci_uart_tty_write; |
545 | hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; | 532 | hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; |
546 | hci_uart_ldisc.poll = hci_uart_tty_poll; | 533 | hci_uart_ldisc.poll = hci_uart_tty_poll; |
547 | hci_uart_ldisc.receive_room = hci_uart_tty_room; | ||
548 | hci_uart_ldisc.receive_buf = hci_uart_tty_receive; | 534 | hci_uart_ldisc.receive_buf = hci_uart_tty_receive; |
549 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; | 535 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; |
550 | hci_uart_ldisc.owner = THIS_MODULE; | 536 | hci_uart_ldisc.owner = THIS_MODULE; |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 977a74e16efb..d6fcd0a36f9f 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD | |||
80 | 80 | ||
81 | config COMPUTONE | 81 | config COMPUTONE |
82 | tristate "Computone IntelliPort Plus serial support" | 82 | tristate "Computone IntelliPort Plus serial support" |
83 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 83 | depends on SERIAL_NONSTANDARD |
84 | ---help--- | 84 | ---help--- |
85 | This driver supports the entire family of Intelliport II/Plus | 85 | This driver supports the entire family of Intelliport II/Plus |
86 | controllers with the exception of the MicroChannel controllers and | 86 | controllers with the exception of the MicroChannel controllers and |
@@ -153,7 +153,7 @@ config DIGIEPCA | |||
153 | 153 | ||
154 | config ESPSERIAL | 154 | config ESPSERIAL |
155 | tristate "Hayes ESP serial port support" | 155 | tristate "Hayes ESP serial port support" |
156 | depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP && ISA_DMA_API | 156 | depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API |
157 | help | 157 | help |
158 | This is a driver which supports Hayes ESP serial ports. Both single | 158 | This is a driver which supports Hayes ESP serial ports. Both single |
159 | port cards and multiport cards are supported. Make sure to read | 159 | port cards and multiport cards are supported. Make sure to read |
@@ -166,7 +166,7 @@ config ESPSERIAL | |||
166 | 166 | ||
167 | config MOXA_INTELLIO | 167 | config MOXA_INTELLIO |
168 | tristate "Moxa Intellio support" | 168 | tristate "Moxa Intellio support" |
169 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 169 | depends on SERIAL_NONSTANDARD |
170 | help | 170 | help |
171 | Say Y here if you have a Moxa Intellio multiport serial card. | 171 | Say Y here if you have a Moxa Intellio multiport serial card. |
172 | 172 | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 10c81ecdace8..869518e4035f 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -265,8 +265,9 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
265 | int status; | 265 | int status; |
266 | int serdatr; | 266 | int serdatr; |
267 | struct tty_struct *tty = info->tty; | 267 | struct tty_struct *tty = info->tty; |
268 | unsigned char ch; | 268 | unsigned char ch, flag; |
269 | struct async_icount *icount; | 269 | struct async_icount *icount; |
270 | int oe = 0; | ||
270 | 271 | ||
271 | icount = &info->state->icount; | 272 | icount = &info->state->icount; |
272 | 273 | ||
@@ -282,15 +283,12 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
282 | status |= UART_LSR_OE; | 283 | status |= UART_LSR_OE; |
283 | 284 | ||
284 | ch = serdatr & 0xff; | 285 | ch = serdatr & 0xff; |
285 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
286 | goto ignore_char; | ||
287 | *tty->flip.char_buf_ptr = ch; | ||
288 | icount->rx++; | 286 | icount->rx++; |
289 | 287 | ||
290 | #ifdef SERIAL_DEBUG_INTR | 288 | #ifdef SERIAL_DEBUG_INTR |
291 | printk("DR%02x:%02x...", ch, status); | 289 | printk("DR%02x:%02x...", ch, status); |
292 | #endif | 290 | #endif |
293 | *tty->flip.flag_buf_ptr = 0; | 291 | flag = TTY_NORMAL; |
294 | 292 | ||
295 | /* | 293 | /* |
296 | * We don't handle parity or frame errors - but I have left | 294 | * 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) | |||
319 | * should be ignored. | 317 | * should be ignored. |
320 | */ | 318 | */ |
321 | if (status & info->ignore_status_mask) | 319 | if (status & info->ignore_status_mask) |
322 | goto ignore_char; | 320 | goto out; |
323 | 321 | ||
324 | status &= info->read_status_mask; | 322 | status &= info->read_status_mask; |
325 | 323 | ||
@@ -327,33 +325,28 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
327 | #ifdef SERIAL_DEBUG_INTR | 325 | #ifdef SERIAL_DEBUG_INTR |
328 | printk("handling break...."); | 326 | printk("handling break...."); |
329 | #endif | 327 | #endif |
330 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 328 | flag = TTY_BREAK; |
331 | if (info->flags & ASYNC_SAK) | 329 | if (info->flags & ASYNC_SAK) |
332 | do_SAK(tty); | 330 | do_SAK(tty); |
333 | } else if (status & UART_LSR_PE) | 331 | } else if (status & UART_LSR_PE) |
334 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 332 | flag = TTY_PARITY; |
335 | else if (status & UART_LSR_FE) | 333 | else if (status & UART_LSR_FE) |
336 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 334 | flag = TTY_FRAME; |
337 | if (status & UART_LSR_OE) { | 335 | if (status & UART_LSR_OE) { |
338 | /* | 336 | /* |
339 | * Overrun is special, since it's | 337 | * Overrun is special, since it's |
340 | * reported immediately, and doesn't | 338 | * reported immediately, and doesn't |
341 | * affect the current character | 339 | * affect the current character |
342 | */ | 340 | */ |
343 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 341 | oe = 1; |
344 | tty->flip.count++; | ||
345 | tty->flip.flag_buf_ptr++; | ||
346 | tty->flip.char_buf_ptr++; | ||
347 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
348 | } | ||
349 | } | 342 | } |
350 | } | 343 | } |
351 | tty->flip.flag_buf_ptr++; | 344 | tty_insert_flip_char(tty, ch, flag); |
352 | tty->flip.char_buf_ptr++; | 345 | if (oe == 1) |
353 | tty->flip.count++; | 346 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
354 | ignore_char: | ||
355 | |||
356 | tty_flip_buffer_push(tty); | 347 | tty_flip_buffer_push(tty); |
348 | out: | ||
349 | return; | ||
357 | } | 350 | } |
358 | 351 | ||
359 | static _INLINE_ void transmit_chars(struct async_struct *info) | 352 | static _INLINE_ void transmit_chars(struct async_struct *info) |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index c8e7daecad72..39c61a71176e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -641,6 +641,7 @@ static char rcsid[] = | |||
641 | #include <linux/timer.h> | 641 | #include <linux/timer.h> |
642 | #include <linux/interrupt.h> | 642 | #include <linux/interrupt.h> |
643 | #include <linux/tty.h> | 643 | #include <linux/tty.h> |
644 | #include <linux/tty_flip.h> | ||
644 | #include <linux/serial.h> | 645 | #include <linux/serial.h> |
645 | #include <linux/major.h> | 646 | #include <linux/major.h> |
646 | #include <linux/string.h> | 647 | #include <linux/string.h> |
@@ -1086,7 +1087,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1086 | int had_work; | 1087 | int had_work; |
1087 | int mdm_change; | 1088 | int mdm_change; |
1088 | int mdm_status; | 1089 | int mdm_status; |
1089 | 1090 | int len; | |
1090 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ | 1091 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ |
1091 | #ifdef CY_DEBUG_INTERRUPTS | 1092 | #ifdef CY_DEBUG_INTERRUPTS |
1092 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | 1093 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); |
@@ -1163,63 +1164,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1163 | info->icount.rx++; | 1164 | info->icount.rx++; |
1164 | continue; | 1165 | continue; |
1165 | } | 1166 | } |
1166 | if (tty->flip.count < TTY_FLIPBUF_SIZE){ | 1167 | if (tty_buffer_request_room(tty, 1)) { |
1167 | tty->flip.count++; | ||
1168 | if (data & info->read_status_mask){ | 1168 | if (data & info->read_status_mask){ |
1169 | if(data & CyBREAK){ | 1169 | if(data & CyBREAK){ |
1170 | *tty->flip.flag_buf_ptr++ = | 1170 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK); |
1171 | TTY_BREAK; | ||
1172 | *tty->flip.char_buf_ptr++ = | ||
1173 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1174 | info->icount.rx++; | 1171 | info->icount.rx++; |
1175 | if (info->flags & ASYNC_SAK){ | 1172 | if (info->flags & ASYNC_SAK){ |
1176 | do_SAK(tty); | 1173 | do_SAK(tty); |
1177 | } | 1174 | } |
1178 | }else if(data & CyFRAME){ | 1175 | }else if(data & CyFRAME){ |
1179 | *tty->flip.flag_buf_ptr++ = | 1176 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); |
1180 | TTY_FRAME; | ||
1181 | *tty->flip.char_buf_ptr++ = | ||
1182 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1183 | info->icount.rx++; | 1177 | info->icount.rx++; |
1184 | info->idle_stats.frame_errs++; | 1178 | info->idle_stats.frame_errs++; |
1185 | }else if(data & CyPARITY){ | 1179 | }else if(data & CyPARITY){ |
1186 | *tty->flip.flag_buf_ptr++ = | 1180 | /* Pieces of seven... */ |
1187 | TTY_PARITY; | 1181 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY); |
1188 | *tty->flip.char_buf_ptr++ = | ||
1189 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1190 | info->icount.rx++; | 1182 | info->icount.rx++; |
1191 | info->idle_stats.parity_errs++; | 1183 | info->idle_stats.parity_errs++; |
1192 | }else if(data & CyOVERRUN){ | 1184 | }else if(data & CyOVERRUN){ |
1193 | *tty->flip.flag_buf_ptr++ = | 1185 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1194 | TTY_OVERRUN; | ||
1195 | *tty->flip.char_buf_ptr++ = 0; | ||
1196 | info->icount.rx++; | 1186 | info->icount.rx++; |
1197 | /* If the flip buffer itself is | 1187 | /* If the flip buffer itself is |
1198 | overflowing, we still lose | 1188 | overflowing, we still lose |
1199 | the next incoming character. | 1189 | the next incoming character. |
1200 | */ | 1190 | */ |
1201 | if(tty->flip.count | 1191 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); |
1202 | < TTY_FLIPBUF_SIZE){ | 1192 | info->icount.rx++; |
1203 | tty->flip.count++; | ||
1204 | *tty->flip.flag_buf_ptr++ = | ||
1205 | TTY_NORMAL; | ||
1206 | *tty->flip.char_buf_ptr++ = | ||
1207 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1208 | info->icount.rx++; | ||
1209 | } | ||
1210 | info->idle_stats.overruns++; | 1193 | info->idle_stats.overruns++; |
1211 | /* These two conditions may imply */ | 1194 | /* These two conditions may imply */ |
1212 | /* a normal read should be done. */ | 1195 | /* a normal read should be done. */ |
1213 | /* }else if(data & CyTIMEOUT){ */ | 1196 | /* }else if(data & CyTIMEOUT){ */ |
1214 | /* }else if(data & CySPECHAR){ */ | 1197 | /* }else if(data & CySPECHAR){ */ |
1215 | }else{ | 1198 | }else { |
1216 | *tty->flip.flag_buf_ptr++ = 0; | 1199 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1217 | *tty->flip.char_buf_ptr++ = 0; | 1200 | info->icount.rx++; |
1218 | info->icount.rx++; | ||
1219 | } | 1201 | } |
1220 | }else{ | 1202 | }else{ |
1221 | *tty->flip.flag_buf_ptr++ = 0; | 1203 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1222 | *tty->flip.char_buf_ptr++ = 0; | ||
1223 | info->icount.rx++; | 1204 | info->icount.rx++; |
1224 | } | 1205 | } |
1225 | }else{ | 1206 | }else{ |
@@ -1240,14 +1221,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1240 | info->mon.char_max = char_count; | 1221 | info->mon.char_max = char_count; |
1241 | info->mon.char_last = char_count; | 1222 | info->mon.char_last = char_count; |
1242 | #endif | 1223 | #endif |
1243 | while(char_count--){ | 1224 | len = tty_buffer_request_room(tty, char_count); |
1244 | if (tty->flip.count >= TTY_FLIPBUF_SIZE){ | 1225 | while(len--){ |
1245 | break; | ||
1246 | } | ||
1247 | tty->flip.count++; | ||
1248 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1226 | data = cy_readb(base_addr+(CyRDSR<<index)); |
1249 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | 1227 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1250 | *tty->flip.char_buf_ptr++ = data; | ||
1251 | info->idle_stats.recv_bytes++; | 1228 | info->idle_stats.recv_bytes++; |
1252 | info->icount.rx++; | 1229 | info->icount.rx++; |
1253 | #ifdef CY_16Y_HACK | 1230 | #ifdef CY_16Y_HACK |
@@ -1256,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1256 | } | 1233 | } |
1257 | info->idle_stats.recv_idle = jiffies; | 1234 | info->idle_stats.recv_idle = jiffies; |
1258 | } | 1235 | } |
1259 | schedule_delayed_work(&tty->flip.work, 1); | 1236 | schedule_delayed_work(&tty->buf.work, 1); |
1260 | } | 1237 | } |
1261 | /* end of service */ | 1238 | /* end of service */ |
1262 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); | 1239 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); |
@@ -1551,6 +1528,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1551 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1528 | struct cyclades_card *cinfo = &cy_card[info->card]; |
1552 | struct tty_struct *tty = info->tty; | 1529 | struct tty_struct *tty = info->tty; |
1553 | volatile int char_count; | 1530 | volatile int char_count; |
1531 | int len; | ||
1554 | #ifdef BLOCKMOVE | 1532 | #ifdef BLOCKMOVE |
1555 | int small_count; | 1533 | int small_count; |
1556 | #else | 1534 | #else |
@@ -1606,18 +1584,11 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1606 | tty->flip.count += small_count; | 1584 | tty->flip.count += small_count; |
1607 | } | 1585 | } |
1608 | #else | 1586 | #else |
1609 | while(char_count--){ | 1587 | len = tty_buffer_request_room(tty, char_count); |
1610 | if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt) | 1588 | while(len--){ |
1611 | break; | ||
1612 | |||
1613 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1614 | break; | ||
1615 | |||
1616 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); | 1589 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); |
1617 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); | 1590 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); |
1618 | tty->flip.count++; | 1591 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1619 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
1620 | *tty->flip.char_buf_ptr++ = data; | ||
1621 | info->idle_stats.recv_bytes++; | 1592 | info->idle_stats.recv_bytes++; |
1622 | info->icount.rx++; | 1593 | info->icount.rx++; |
1623 | } | 1594 | } |
@@ -1635,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1635 | } | 1606 | } |
1636 | #endif | 1607 | #endif |
1637 | info->idle_stats.recv_idle = jiffies; | 1608 | info->idle_stats.recv_idle = jiffies; |
1638 | schedule_delayed_work(&tty->flip.work, 1); | 1609 | schedule_delayed_work(&tty->buf.work, 1); |
1639 | } | 1610 | } |
1640 | /* Update rx_get */ | 1611 | /* Update rx_get */ |
1641 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | 1612 | cy_writel(&buf_ctrl->rx_get, new_rx_get); |
@@ -1763,23 +1734,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1763 | 1734 | ||
1764 | switch(cmd) { | 1735 | switch(cmd) { |
1765 | case C_CM_PR_ERROR: | 1736 | case C_CM_PR_ERROR: |
1766 | tty->flip.count++; | 1737 | tty_insert_flip_char(tty, 0, TTY_PARITY); |
1767 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | ||
1768 | *tty->flip.char_buf_ptr++ = 0; | ||
1769 | info->icount.rx++; | 1738 | info->icount.rx++; |
1770 | special_count++; | 1739 | special_count++; |
1771 | break; | 1740 | break; |
1772 | case C_CM_FR_ERROR: | 1741 | case C_CM_FR_ERROR: |
1773 | tty->flip.count++; | 1742 | tty_insert_flip_char(tty, 0, TTY_FRAME); |
1774 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | ||
1775 | *tty->flip.char_buf_ptr++ = 0; | ||
1776 | info->icount.rx++; | 1743 | info->icount.rx++; |
1777 | special_count++; | 1744 | special_count++; |
1778 | break; | 1745 | break; |
1779 | case C_CM_RXBRK: | 1746 | case C_CM_RXBRK: |
1780 | tty->flip.count++; | 1747 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1781 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | ||
1782 | *tty->flip.char_buf_ptr++ = 0; | ||
1783 | info->icount.rx++; | 1748 | info->icount.rx++; |
1784 | special_count++; | 1749 | special_count++; |
1785 | break; | 1750 | break; |
@@ -1844,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1844 | if(delta_count) | 1809 | if(delta_count) |
1845 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1810 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); |
1846 | if(special_count) | 1811 | if(special_count) |
1847 | schedule_delayed_work(&tty->flip.work, 1); | 1812 | schedule_delayed_work(&tty->buf.work, 1); |
1848 | } | 1813 | } |
1849 | } | 1814 | } |
1850 | 1815 | ||
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 407708a001e4..765c5c108bf4 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -1786,9 +1786,7 @@ static void doevent(int crd) | |||
1786 | if (tty) { /* Begin if valid tty */ | 1786 | if (tty) { /* Begin if valid tty */ |
1787 | if (event & BREAK_IND) { /* Begin if BREAK_IND */ | 1787 | if (event & BREAK_IND) { /* Begin if BREAK_IND */ |
1788 | /* A break has been indicated */ | 1788 | /* A break has been indicated */ |
1789 | tty->flip.count++; | 1789 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1790 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | ||
1791 | *tty->flip.char_buf_ptr++ = 0; | ||
1792 | tty_schedule_flip(tty); | 1790 | tty_schedule_flip(tty); |
1793 | } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */ | 1791 | } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */ |
1794 | if (ch->statusflags & LOWWAIT) | 1792 | if (ch->statusflags & LOWWAIT) |
@@ -2124,7 +2122,6 @@ static void receive_data(struct channel *ch) | |||
2124 | int dataToRead, wrapgap, bytesAvailable; | 2122 | int dataToRead, wrapgap, bytesAvailable; |
2125 | unsigned int tail, head; | 2123 | unsigned int tail, head; |
2126 | unsigned int wrapmask; | 2124 | unsigned int wrapmask; |
2127 | int rc; | ||
2128 | 2125 | ||
2129 | /* --------------------------------------------------------------- | 2126 | /* --------------------------------------------------------------- |
2130 | This routine is called by doint when a receive data event | 2127 | This routine is called by doint when a receive data event |
@@ -2162,16 +2159,15 @@ static void receive_data(struct channel *ch) | |||
2162 | return; | 2159 | return; |
2163 | } | 2160 | } |
2164 | 2161 | ||
2165 | if (tty->flip.count == TTY_FLIPBUF_SIZE) | 2162 | if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0) |
2166 | return; | 2163 | return; |
2167 | 2164 | ||
2168 | if (readb(&bc->orun)) { | 2165 | if (readb(&bc->orun)) { |
2169 | writeb(0, &bc->orun); | 2166 | writeb(0, &bc->orun); |
2170 | printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name); | 2167 | printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name); |
2168 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
2171 | } | 2169 | } |
2172 | rxwinon(ch); | 2170 | rxwinon(ch); |
2173 | rptr = tty->flip.char_buf_ptr; | ||
2174 | rc = tty->flip.count; | ||
2175 | while (bytesAvailable > 0) { /* Begin while there is data on the card */ | 2171 | while (bytesAvailable > 0) { /* Begin while there is data on the card */ |
2176 | wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; | 2172 | wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; |
2177 | /* --------------------------------------------------------------- | 2173 | /* --------------------------------------------------------------- |
@@ -2183,8 +2179,7 @@ static void receive_data(struct channel *ch) | |||
2183 | /* -------------------------------------------------------------- | 2179 | /* -------------------------------------------------------------- |
2184 | Make sure we don't overflow the buffer | 2180 | Make sure we don't overflow the buffer |
2185 | ----------------------------------------------------------------- */ | 2181 | ----------------------------------------------------------------- */ |
2186 | if ((rc + dataToRead) > TTY_FLIPBUF_SIZE) | 2182 | dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); |
2187 | dataToRead = TTY_FLIPBUF_SIZE - rc; | ||
2188 | if (dataToRead == 0) | 2183 | if (dataToRead == 0) |
2189 | break; | 2184 | break; |
2190 | /* --------------------------------------------------------------- | 2185 | /* --------------------------------------------------------------- |
@@ -2192,13 +2187,9 @@ static void receive_data(struct channel *ch) | |||
2192 | for translation if necessary. | 2187 | for translation if necessary. |
2193 | ------------------------------------------------------------------ */ | 2188 | ------------------------------------------------------------------ */ |
2194 | memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); | 2189 | memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); |
2195 | rc += dataToRead; | ||
2196 | rptr += dataToRead; | ||
2197 | tail = (tail + dataToRead) & wrapmask; | 2190 | tail = (tail + dataToRead) & wrapmask; |
2198 | bytesAvailable -= dataToRead; | 2191 | bytesAvailable -= dataToRead; |
2199 | } /* End while there is data on the card */ | 2192 | } /* End while there is data on the card */ |
2200 | tty->flip.count = rc; | ||
2201 | tty->flip.char_buf_ptr = rptr; | ||
2202 | globalwinon(ch); | 2193 | globalwinon(ch); |
2203 | writew(tail, &bc->rout); | 2194 | writew(tail, &bc->rout); |
2204 | /* Must be called with global data */ | 2195 | /* Must be called with global data */ |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 9f53d2fcc360..e469f641c728 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) | |||
345 | 345 | ||
346 | for (i = 0; i < num_bytes; i++) { | 346 | for (i = 0; i < num_bytes; i++) { |
347 | if (!(err_buf->data[i] & status_mask)) { | 347 | if (!(err_buf->data[i] & status_mask)) { |
348 | *(tty->flip.char_buf_ptr++) = pio_buf->data[i]; | 348 | int flag = 0; |
349 | 349 | ||
350 | if (err_buf->data[i] & 0x04) { | 350 | if (err_buf->data[i] & 0x04) { |
351 | *(tty->flip.flag_buf_ptr++) = TTY_BREAK; | 351 | flag = TTY_BREAK; |
352 | |||
353 | if (info->flags & ASYNC_SAK) | 352 | if (info->flags & ASYNC_SAK) |
354 | do_SAK(tty); | 353 | do_SAK(tty); |
355 | } | 354 | } |
356 | else if (err_buf->data[i] & 0x02) | 355 | else if (err_buf->data[i] & 0x02) |
357 | *(tty->flip.flag_buf_ptr++) = TTY_FRAME; | 356 | flag = TTY_FRAME; |
358 | else if (err_buf->data[i] & 0x01) | 357 | else if (err_buf->data[i] & 0x01) |
359 | *(tty->flip.flag_buf_ptr++) = TTY_PARITY; | 358 | flag = TTY_PARITY; |
360 | else | 359 | tty_insert_flip_char(tty, pio_buf->data[i], flag); |
361 | *(tty->flip.flag_buf_ptr++) = 0; | ||
362 | |||
363 | tty->flip.count++; | ||
364 | } | 360 | } |
365 | } | 361 | } |
366 | 362 | ||
367 | schedule_delayed_work(&tty->flip.work, 1); | 363 | schedule_delayed_work(&tty->buf.work, 1); |
368 | 364 | ||
369 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | 365 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; |
370 | release_pio_buffer(pio_buf); | 366 | release_pio_buffer(pio_buf); |
@@ -397,7 +393,6 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
397 | int num_bytes; | 393 | int num_bytes; |
398 | unsigned long flags; | 394 | unsigned long flags; |
399 | 395 | ||
400 | |||
401 | flags=claim_dma_lock(); | 396 | flags=claim_dma_lock(); |
402 | disable_dma(dma); | 397 | disable_dma(dma); |
403 | clear_dma_ff(dma); | 398 | clear_dma_ff(dma); |
@@ -408,38 +403,31 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
408 | 403 | ||
409 | info->icount.rx += num_bytes; | 404 | info->icount.rx += num_bytes; |
410 | 405 | ||
411 | memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes); | ||
412 | tty->flip.char_buf_ptr += num_bytes; | ||
413 | tty->flip.count += num_bytes; | ||
414 | memset(tty->flip.flag_buf_ptr, 0, num_bytes); | ||
415 | tty->flip.flag_buf_ptr += num_bytes; | ||
416 | |||
417 | if (num_bytes > 0) { | 406 | if (num_bytes > 0) { |
418 | tty->flip.flag_buf_ptr--; | 407 | tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); |
419 | 408 | ||
420 | status &= (0x1c & info->read_status_mask); | 409 | status &= (0x1c & info->read_status_mask); |
410 | |||
411 | /* Is the status significant or do we throw the last byte ? */ | ||
412 | if (!(status & info->ignore_status_mask)) { | ||
413 | int statflag = 0; | ||
421 | 414 | ||
422 | if (status & info->ignore_status_mask) { | 415 | if (status & 0x10) { |
423 | tty->flip.count--; | 416 | statflag = TTY_BREAK; |
424 | tty->flip.char_buf_ptr--; | 417 | (info->icount.brk)++; |
425 | tty->flip.flag_buf_ptr--; | 418 | if (info->flags & ASYNC_SAK) |
426 | } else if (status & 0x10) { | 419 | do_SAK(tty); |
427 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 420 | } else if (status & 0x08) { |
428 | (info->icount.brk)++; | 421 | statflag = TTY_FRAME; |
429 | if (info->flags & ASYNC_SAK) | 422 | (info->icount.frame)++; |
430 | do_SAK(tty); | 423 | } |
431 | } else if (status & 0x08) { | 424 | else if (status & 0x04) { |
432 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 425 | statflag = TTY_PARITY; |
433 | (info->icount.frame)++; | 426 | (info->icount.parity)++; |
434 | } | 427 | } |
435 | else if (status & 0x04) { | 428 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag); |
436 | *tty->flip.flag_buf_ptr = TTY_PARITY; | ||
437 | (info->icount.parity)++; | ||
438 | } | 429 | } |
439 | 430 | schedule_delayed_work(&tty->buf.work, 1); | |
440 | tty->flip.flag_buf_ptr++; | ||
441 | |||
442 | schedule_delayed_work(&tty->flip.work, 1); | ||
443 | } | 431 | } |
444 | 432 | ||
445 | if (dma_bytes != num_bytes) { | 433 | if (dma_bytes != num_bytes) { |
@@ -693,8 +681,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id, | |||
693 | num_bytes = serial_in(info, UART_ESI_STAT1) << 8; | 681 | num_bytes = serial_in(info, UART_ESI_STAT1) << 8; |
694 | num_bytes |= serial_in(info, UART_ESI_STAT2); | 682 | num_bytes |= serial_in(info, UART_ESI_STAT2); |
695 | 683 | ||
696 | if (num_bytes > (TTY_FLIPBUF_SIZE - info->tty->flip.count)) | 684 | num_bytes = tty_buffer_request_room(info->tty, num_bytes); |
697 | num_bytes = TTY_FLIPBUF_SIZE - info->tty->flip.count; | ||
698 | 685 | ||
699 | if (num_bytes) { | 686 | if (num_bytes) { |
700 | if (dma_bytes || | 687 | if (dma_bytes || |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index f92177634677..1994a92d4733 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) | |||
597 | 597 | ||
598 | /* Read data if any */ | 598 | /* Read data if any */ |
599 | for (;;) { | 599 | for (;;) { |
600 | int count = N_INBUF; | 600 | int count = tty_buffer_request_room(tty, N_INBUF); |
601 | if (count > (TTY_FLIPBUF_SIZE - tty->flip.count)) | ||
602 | count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
603 | 601 | ||
604 | /* If flip is full, just reschedule a later read */ | 602 | /* If flip is full, just reschedule a later read */ |
605 | if (count == 0) { | 603 | if (count == 0) { |
@@ -635,7 +633,7 @@ static int hvc_poll(struct hvc_struct *hp) | |||
635 | tty_insert_flip_char(tty, buf[i], 0); | 633 | tty_insert_flip_char(tty, buf[i], 0); |
636 | } | 634 | } |
637 | 635 | ||
638 | if (tty->flip.count) | 636 | if (count) |
639 | tty_schedule_flip(tty); | 637 | tty_schedule_flip(tty); |
640 | 638 | ||
641 | /* | 639 | /* |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 53dc77c760fc..831eb4e8d9d3 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -456,12 +456,11 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
456 | /* remove the read masks */ | 456 | /* remove the read masks */ |
457 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); | 457 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); |
458 | 458 | ||
459 | if ((tty->flip.count + HVCS_BUFF_LEN) < TTY_FLIPBUF_SIZE) { | 459 | if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { |
460 | got = hvc_get_chars(unit_address, | 460 | got = hvc_get_chars(unit_address, |
461 | &buf[0], | 461 | &buf[0], |
462 | HVCS_BUFF_LEN); | 462 | HVCS_BUFF_LEN); |
463 | for (i=0;got && i<got;i++) | 463 | tty_insert_flip_string(tty, buf, got); |
464 | tty_insert_flip_char(tty, buf[i], TTY_NORMAL); | ||
465 | } | 464 | } |
466 | 465 | ||
467 | /* Give the TTY time to process the data we just sent. */ | 466 | /* Give the TTY time to process the data we just sent. */ |
@@ -469,10 +468,9 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
469 | hvcsd->todo_mask |= HVCS_QUICK_READ; | 468 | hvcsd->todo_mask |= HVCS_QUICK_READ; |
470 | 469 | ||
471 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 470 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
472 | if (tty->flip.count) { | 471 | /* This is synch because tty->low_latency == 1 */ |
473 | /* This is synch because tty->low_latency == 1 */ | 472 | if(got) |
474 | tty_flip_buffer_push(tty); | 473 | tty_flip_buffer_push(tty); |
475 | } | ||
476 | 474 | ||
477 | if (!got) { | 475 | if (!got) { |
478 | /* Do this _after_ the flip_buffer_push */ | 476 | /* Do this _after_ the flip_buffer_push */ |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 1bbf507adda5..86033bed5d6c 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -115,6 +115,7 @@ | |||
115 | #include <linux/module.h> | 115 | #include <linux/module.h> |
116 | #include <linux/kernel.h> | 116 | #include <linux/kernel.h> |
117 | #include <linux/tty.h> | 117 | #include <linux/tty.h> |
118 | #include <linux/tty_flip.h> | ||
118 | #include <linux/termios.h> | 119 | #include <linux/termios.h> |
119 | #include <linux/fs.h> | 120 | #include <linux/fs.h> |
120 | #include <linux/sched.h> | 121 | #include <linux/sched.h> |
@@ -773,6 +774,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, | |||
773 | unsigned short base, header, word_count, count; | 774 | unsigned short base, header, word_count, count; |
774 | unsigned char channel; | 775 | unsigned char channel; |
775 | short byte_count; | 776 | short byte_count; |
777 | unsigned char *rp; | ||
776 | 778 | ||
777 | card = (struct isi_board *) dev_id; | 779 | card = (struct isi_board *) dev_id; |
778 | 780 | ||
@@ -903,14 +905,10 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, | |||
903 | break; | 905 | break; |
904 | 906 | ||
905 | case 1: /* Received Break !!! */ | 907 | case 1: /* Received Break !!! */ |
906 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 908 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
907 | break; | ||
908 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | ||
909 | *tty->flip.char_buf_ptr++ = 0; | ||
910 | tty->flip.count++; | ||
911 | if (port->flags & ASYNC_SAK) | 909 | if (port->flags & ASYNC_SAK) |
912 | do_SAK(tty); | 910 | do_SAK(tty); |
913 | schedule_delayed_work(&tty->flip.work, 1); | 911 | tty_flip_buffer_push(tty); |
914 | break; | 912 | break; |
915 | 913 | ||
916 | case 2: /* Statistics */ | 914 | case 2: /* Statistics */ |
@@ -923,23 +921,19 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, | |||
923 | } | 921 | } |
924 | } | 922 | } |
925 | else { /* Data Packet */ | 923 | else { /* Data Packet */ |
926 | count = min_t(unsigned short, byte_count, (TTY_FLIPBUF_SIZE - tty->flip.count)); | 924 | |
925 | count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); | ||
927 | #ifdef ISICOM_DEBUG | 926 | #ifdef ISICOM_DEBUG |
928 | printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n", | 927 | printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n", |
929 | count, byte_count); | 928 | count, byte_count); |
930 | #endif | 929 | #endif |
931 | word_count = count >> 1; | 930 | word_count = count >> 1; |
932 | insw(base, tty->flip.char_buf_ptr, word_count); | 931 | insw(base, rp, word_count); |
933 | tty->flip.char_buf_ptr += (word_count << 1); | ||
934 | byte_count -= (word_count << 1); | 932 | byte_count -= (word_count << 1); |
935 | if (count & 0x0001) { | 933 | if (count & 0x0001) { |
936 | *tty->flip.char_buf_ptr++ = (char)(inw(base) & 0xff); | 934 | tty_insert_flip_char(tty, inw(base) & 0xff, TTY_NORMAL); |
937 | byte_count -= 2; | 935 | byte_count -= 2; |
938 | } | 936 | } |
939 | memset(tty->flip.flag_buf_ptr, 0, count); | ||
940 | tty->flip.flag_buf_ptr += count; | ||
941 | tty->flip.count += count; | ||
942 | |||
943 | if (byte_count > 0) { | 937 | if (byte_count > 0) { |
944 | printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n", | 938 | printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n", |
945 | base, channel+1); | 939 | base, channel+1); |
@@ -948,7 +942,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, | |||
948 | byte_count -= 2; | 942 | byte_count -= 2; |
949 | } | 943 | } |
950 | } | 944 | } |
951 | schedule_delayed_work(&tty->flip.work, 1); | 945 | tty_flip_buffer_push(tty); |
952 | } | 946 | } |
953 | if (card->isa == YES) | 947 | if (card->isa == YES) |
954 | ClearInterrupt(base); | 948 | ClearInterrupt(base); |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 24435f8daa68..28c5a3193b81 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) | |||
2711 | stlen = size - tail; | 2711 | stlen = size - tail; |
2712 | } | 2712 | } |
2713 | 2713 | ||
2714 | len = MIN(len, (TTY_FLIPBUF_SIZE - tty->flip.count)); | 2714 | len = tty_buffer_request_room(tty, len); |
2715 | /* FIXME : iomap ? */ | ||
2715 | shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); | 2716 | shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); |
2716 | 2717 | ||
2717 | while (len > 0) { | 2718 | while (len > 0) { |
2718 | stlen = MIN(len, stlen); | 2719 | stlen = MIN(len, stlen); |
2719 | memcpy(tty->flip.char_buf_ptr, (char *) (shbuf + tail), stlen); | 2720 | tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen); |
2720 | memset(tty->flip.flag_buf_ptr, 0, stlen); | ||
2721 | tty->flip.char_buf_ptr += stlen; | ||
2722 | tty->flip.flag_buf_ptr += stlen; | ||
2723 | tty->flip.count += stlen; | ||
2724 | |||
2725 | len -= stlen; | 2721 | len -= stlen; |
2726 | tail += stlen; | 2722 | tail += stlen; |
2727 | if (tail >= size) { | 2723 | if (tail >= size) { |
@@ -2906,16 +2902,12 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2906 | 2902 | ||
2907 | if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { | 2903 | if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { |
2908 | if (tty != (struct tty_struct *) NULL) { | 2904 | if (tty != (struct tty_struct *) NULL) { |
2909 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 2905 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
2910 | tty->flip.count++; | 2906 | if (portp->flags & ASYNC_SAK) { |
2911 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 2907 | do_SAK(tty); |
2912 | *tty->flip.char_buf_ptr++ = 0; | 2908 | EBRDENABLE(brdp); |
2913 | if (portp->flags & ASYNC_SAK) { | ||
2914 | do_SAK(tty); | ||
2915 | EBRDENABLE(brdp); | ||
2916 | } | ||
2917 | tty_schedule_flip(tty); | ||
2918 | } | 2909 | } |
2910 | tty_schedule_flip(tty); | ||
2919 | } | 2911 | } |
2920 | } | 2912 | } |
2921 | 2913 | ||
@@ -4940,7 +4932,7 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4940 | if (portp->tty != (struct tty_struct *) NULL) { | 4932 | if (portp->tty != (struct tty_struct *) NULL) { |
4941 | if (portp->tty->driver_data == portp) { | 4933 | if (portp->tty->driver_data == portp) { |
4942 | stli_comstats.ttystate = portp->tty->flags; | 4934 | stli_comstats.ttystate = portp->tty->flags; |
4943 | stli_comstats.rxbuffered = portp->tty->flip.count; | 4935 | stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/; |
4944 | if (portp->tty->termios != (struct termios *) NULL) { | 4936 | if (portp->tty->termios != (struct termios *) NULL) { |
4945 | stli_comstats.cflags = portp->tty->termios->c_cflag; | 4937 | stli_comstats.cflags = portp->tty->termios->c_cflag; |
4946 | stli_comstats.iflags = portp->tty->termios->c_iflag; | 4938 | stli_comstats.iflags = portp->tty->termios->c_iflag; |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 46a3a8ccd65f..5e3ef5522194 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -269,7 +269,7 @@ static int MoxaPortDCDChange(int); | |||
269 | static int MoxaPortDCDON(int); | 269 | static int MoxaPortDCDON(int); |
270 | static void MoxaPortFlushData(int, int); | 270 | static void MoxaPortFlushData(int, int); |
271 | static int MoxaPortWriteData(int, unsigned char *, int); | 271 | static int MoxaPortWriteData(int, unsigned char *, int); |
272 | static int MoxaPortReadData(int, unsigned char *, int); | 272 | static int MoxaPortReadData(int, struct tty_struct *tty); |
273 | static int MoxaPortTxQueue(int); | 273 | static int MoxaPortTxQueue(int); |
274 | static int MoxaPortRxQueue(int); | 274 | static int MoxaPortRxQueue(int); |
275 | static int MoxaPortTxFree(int); | 275 | static int MoxaPortTxFree(int); |
@@ -301,6 +301,8 @@ static struct tty_operations moxa_ops = { | |||
301 | .tiocmset = moxa_tiocmset, | 301 | .tiocmset = moxa_tiocmset, |
302 | }; | 302 | }; |
303 | 303 | ||
304 | static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; | ||
305 | |||
304 | #ifdef CONFIG_PCI | 306 | #ifdef CONFIG_PCI |
305 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) | 307 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) |
306 | { | 308 | { |
@@ -645,10 +647,10 @@ static int moxa_write(struct tty_struct *tty, | |||
645 | if (ch == NULL) | 647 | if (ch == NULL) |
646 | return (0); | 648 | return (0); |
647 | port = ch->port; | 649 | port = ch->port; |
648 | save_flags(flags); | 650 | |
649 | cli(); | 651 | spin_lock_irqsave(&moxa_lock, flags); |
650 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); | 652 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); |
651 | restore_flags(flags); | 653 | spin_unlock_irqrestore(&moxa_lock, flags); |
652 | 654 | ||
653 | /********************************************* | 655 | /********************************************* |
654 | if ( !(ch->statusflags & LOWWAIT) && | 656 | if ( !(ch->statusflags & LOWWAIT) && |
@@ -723,11 +725,10 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c) | |||
723 | if (ch == NULL) | 725 | if (ch == NULL) |
724 | return; | 726 | return; |
725 | port = ch->port; | 727 | port = ch->port; |
726 | save_flags(flags); | 728 | spin_lock_irqsave(&moxa_lock, flags); |
727 | cli(); | ||
728 | moxaXmitBuff[0] = c; | 729 | moxaXmitBuff[0] = c; |
729 | MoxaPortWriteData(port, moxaXmitBuff, 1); | 730 | MoxaPortWriteData(port, moxaXmitBuff, 1); |
730 | restore_flags(flags); | 731 | spin_unlock_irqrestore(&moxa_lock, flags); |
731 | /************************************************ | 732 | /************************************************ |
732 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) | 733 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) |
733 | *************************************************/ | 734 | *************************************************/ |
@@ -1030,12 +1031,12 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1030 | printk("block_til_ready before block: ttys%d, count = %d\n", | 1031 | printk("block_til_ready before block: ttys%d, count = %d\n", |
1031 | ch->line, ch->count); | 1032 | ch->line, ch->count); |
1032 | #endif | 1033 | #endif |
1033 | save_flags(flags); | 1034 | spin_lock_irqsave(&moxa_lock, flags); |
1034 | cli(); | ||
1035 | if (!tty_hung_up_p(filp)) | 1035 | if (!tty_hung_up_p(filp)) |
1036 | ch->count--; | 1036 | ch->count--; |
1037 | restore_flags(flags); | ||
1038 | ch->blocked_open++; | 1037 | ch->blocked_open++; |
1038 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1039 | |||
1039 | while (1) { | 1040 | while (1) { |
1040 | set_current_state(TASK_INTERRUPTIBLE); | 1041 | set_current_state(TASK_INTERRUPTIBLE); |
1041 | if (tty_hung_up_p(filp) || | 1042 | if (tty_hung_up_p(filp) || |
@@ -1062,17 +1063,21 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1062 | } | 1063 | } |
1063 | set_current_state(TASK_RUNNING); | 1064 | set_current_state(TASK_RUNNING); |
1064 | remove_wait_queue(&ch->open_wait, &wait); | 1065 | remove_wait_queue(&ch->open_wait, &wait); |
1066 | |||
1067 | spin_lock_irqsave(&moxa_lock, flags); | ||
1065 | if (!tty_hung_up_p(filp)) | 1068 | if (!tty_hung_up_p(filp)) |
1066 | ch->count++; | 1069 | ch->count++; |
1067 | ch->blocked_open--; | 1070 | ch->blocked_open--; |
1071 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1068 | #ifdef SERIAL_DEBUG_OPEN | 1072 | #ifdef SERIAL_DEBUG_OPEN |
1069 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | 1073 | printk("block_til_ready after blocking: ttys%d, count = %d\n", |
1070 | ch->line, ch->count); | 1074 | ch->line, ch->count); |
1071 | #endif | 1075 | #endif |
1072 | if (retval) | 1076 | if (retval) |
1073 | return (retval); | 1077 | return (retval); |
1078 | /* FIXME: review to see if we need to use set_bit on these */ | ||
1074 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; | 1079 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; |
1075 | return (0); | 1080 | return 0; |
1076 | } | 1081 | } |
1077 | 1082 | ||
1078 | static void setup_empty_event(struct tty_struct *tty) | 1083 | static void setup_empty_event(struct tty_struct *tty) |
@@ -1080,15 +1085,14 @@ static void setup_empty_event(struct tty_struct *tty) | |||
1080 | struct moxa_str *ch = tty->driver_data; | 1085 | struct moxa_str *ch = tty->driver_data; |
1081 | unsigned long flags; | 1086 | unsigned long flags; |
1082 | 1087 | ||
1083 | save_flags(flags); | 1088 | spin_lock_irqsave(&moxa_lock, flags); |
1084 | cli(); | ||
1085 | ch->statusflags |= EMPTYWAIT; | 1089 | ch->statusflags |= EMPTYWAIT; |
1086 | moxaEmptyTimer_on[ch->port] = 0; | 1090 | moxaEmptyTimer_on[ch->port] = 0; |
1087 | del_timer(&moxaEmptyTimer[ch->port]); | 1091 | del_timer(&moxaEmptyTimer[ch->port]); |
1088 | moxaEmptyTimer[ch->port].expires = jiffies + HZ; | 1092 | moxaEmptyTimer[ch->port].expires = jiffies + HZ; |
1089 | moxaEmptyTimer_on[ch->port] = 1; | 1093 | moxaEmptyTimer_on[ch->port] = 1; |
1090 | add_timer(&moxaEmptyTimer[ch->port]); | 1094 | add_timer(&moxaEmptyTimer[ch->port]); |
1091 | restore_flags(flags); | 1095 | spin_unlock_irqrestore(&moxa_lock, flags); |
1092 | } | 1096 | } |
1093 | 1097 | ||
1094 | static void check_xmit_empty(unsigned long data) | 1098 | static void check_xmit_empty(unsigned long data) |
@@ -1135,8 +1139,6 @@ static void receive_data(struct moxa_str *ch) | |||
1135 | { | 1139 | { |
1136 | struct tty_struct *tp; | 1140 | struct tty_struct *tp; |
1137 | struct termios *ts; | 1141 | struct termios *ts; |
1138 | int i, count, rc, space; | ||
1139 | unsigned char *charptr, *flagptr; | ||
1140 | unsigned long flags; | 1142 | unsigned long flags; |
1141 | 1143 | ||
1142 | ts = NULL; | 1144 | ts = NULL; |
@@ -1150,24 +1152,10 @@ static void receive_data(struct moxa_str *ch) | |||
1150 | MoxaPortFlushData(ch->port, 0); | 1152 | MoxaPortFlushData(ch->port, 0); |
1151 | return; | 1153 | return; |
1152 | } | 1154 | } |
1153 | space = TTY_FLIPBUF_SIZE - tp->flip.count; | 1155 | spin_lock_irqsave(&moxa_lock, flags); |
1154 | if (space <= 0) | 1156 | MoxaPortReadData(ch->port, tp); |
1155 | return; | 1157 | spin_unlock_irqrestore(&moxa_lock, flags); |
1156 | charptr = tp->flip.char_buf_ptr; | 1158 | tty_schedule_flip(tp); |
1157 | flagptr = tp->flip.flag_buf_ptr; | ||
1158 | rc = tp->flip.count; | ||
1159 | save_flags(flags); | ||
1160 | cli(); | ||
1161 | count = MoxaPortReadData(ch->port, charptr, space); | ||
1162 | restore_flags(flags); | ||
1163 | for (i = 0; i < count; i++) | ||
1164 | *flagptr++ = 0; | ||
1165 | charptr += count; | ||
1166 | rc += count; | ||
1167 | tp->flip.count = rc; | ||
1168 | tp->flip.char_buf_ptr = charptr; | ||
1169 | tp->flip.flag_buf_ptr = flagptr; | ||
1170 | tty_schedule_flip(ch->tty); | ||
1171 | } | 1159 | } |
1172 | 1160 | ||
1173 | #define Magic_code 0x404 | 1161 | #define Magic_code 0x404 |
@@ -1774,7 +1762,7 @@ int MoxaPortsOfCard(int cardno) | |||
1774 | * 14. MoxaPortDCDON(int port); * | 1762 | * 14. MoxaPortDCDON(int port); * |
1775 | * 15. MoxaPortFlushData(int port, int mode); * | 1763 | * 15. MoxaPortFlushData(int port, int mode); * |
1776 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * | 1764 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * |
1777 | * 17. MoxaPortReadData(int port, unsigned char * buffer, int length); * | 1765 | * 17. MoxaPortReadData(int port, struct tty_struct *tty); * |
1778 | * 18. MoxaPortTxBufSize(int port); * | 1766 | * 18. MoxaPortTxBufSize(int port); * |
1779 | * 19. MoxaPortRxBufSize(int port); * | 1767 | * 19. MoxaPortRxBufSize(int port); * |
1780 | * 20. MoxaPortTxQueue(int port); * | 1768 | * 20. MoxaPortTxQueue(int port); * |
@@ -2003,10 +1991,9 @@ int MoxaPortsOfCard(int cardno) | |||
2003 | * | 1991 | * |
2004 | * Function 21: Read data. | 1992 | * Function 21: Read data. |
2005 | * Syntax: | 1993 | * Syntax: |
2006 | * int MoxaPortReadData(int port, unsigned char * buffer, int length); | 1994 | * int MoxaPortReadData(int port, struct tty_struct *tty); |
2007 | * int port : port number (0 - 127) | 1995 | * int port : port number (0 - 127) |
2008 | * unsigned char * buffer : pointer to read data buffer. | 1996 | * struct tty_struct *tty : tty for data |
2009 | * int length : read data buffer length | ||
2010 | * | 1997 | * |
2011 | * return: 0 - length : real read data length | 1998 | * return: 0 - length : real read data length |
2012 | * | 1999 | * |
@@ -2504,7 +2491,7 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len) | |||
2504 | return (total); | 2491 | return (total); |
2505 | } | 2492 | } |
2506 | 2493 | ||
2507 | int MoxaPortReadData(int port, unsigned char * buffer, int space) | 2494 | int MoxaPortReadData(int port, struct tty_struct *tty) |
2508 | { | 2495 | { |
2509 | register ushort head, pageofs; | 2496 | register ushort head, pageofs; |
2510 | int i, count, cnt, len, total, remain; | 2497 | int i, count, cnt, len, total, remain; |
@@ -2522,9 +2509,9 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2522 | count = (tail >= head) ? (tail - head) | 2509 | count = (tail >= head) ? (tail - head) |
2523 | : (tail - head + rx_mask + 1); | 2510 | : (tail - head + rx_mask + 1); |
2524 | if (count == 0) | 2511 | if (count == 0) |
2525 | return (0); | 2512 | return 0; |
2526 | 2513 | ||
2527 | total = (space > count) ? count : space; | 2514 | total = count; |
2528 | remain = count - total; | 2515 | remain = count - total; |
2529 | moxaLog.rxcnt[port] += total; | 2516 | moxaLog.rxcnt[port] += total; |
2530 | count = total; | 2517 | count = total; |
@@ -2539,7 +2526,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2539 | len = (count > len) ? len : count; | 2526 | len = (count > len) ? len : count; |
2540 | ofs = baseAddr + DynPage_addr + bufhead + head; | 2527 | ofs = baseAddr + DynPage_addr + bufhead + head; |
2541 | for (i = 0; i < len; i++) | 2528 | for (i = 0; i < len; i++) |
2542 | *buffer++ = readb(ofs + i); | 2529 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); |
2543 | head = (head + len) & rx_mask; | 2530 | head = (head + len) & rx_mask; |
2544 | count -= len; | 2531 | count -= len; |
2545 | } | 2532 | } |
@@ -2556,7 +2543,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2556 | writew(pageno, baseAddr + Control_reg); | 2543 | writew(pageno, baseAddr + Control_reg); |
2557 | ofs = baseAddr + DynPage_addr + pageofs; | 2544 | ofs = baseAddr + DynPage_addr + pageofs; |
2558 | for (i = 0; i < cnt; i++) | 2545 | for (i = 0; i < cnt; i++) |
2559 | *buffer++ = readb(ofs + i); | 2546 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); |
2560 | if (count == 0) { | 2547 | if (count == 0) { |
2561 | writew((head + len) & rx_mask, ofsAddr + RXrptr); | 2548 | writew((head + len) & rx_mask, ofsAddr + RXrptr); |
2562 | break; | 2549 | break; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 51bb2a3cf8b3..ea725a9964e2 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -1982,7 +1982,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
1982 | 1982 | ||
1983 | spin_lock_irqsave(&info->slock, flags); | 1983 | spin_lock_irqsave(&info->slock, flags); |
1984 | 1984 | ||
1985 | recv_room = tty->ldisc.receive_room(tty); | 1985 | recv_room = tty->receive_room; |
1986 | if ((recv_room == 0) && (!info->ldisc_stop_rx)) { | 1986 | if ((recv_room == 0) && (!info->ldisc_stop_rx)) { |
1987 | //mxser_throttle(tty); | 1987 | //mxser_throttle(tty); |
1988 | mxser_stoprx(tty); | 1988 | mxser_stoprx(tty); |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index a133a62f3d55..70f487dd7b8d 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -212,7 +212,6 @@ static struct tty_ldisc n_hdlc_ldisc = { | |||
212 | .ioctl = n_hdlc_tty_ioctl, | 212 | .ioctl = n_hdlc_tty_ioctl, |
213 | .poll = n_hdlc_tty_poll, | 213 | .poll = n_hdlc_tty_poll, |
214 | .receive_buf = n_hdlc_tty_receive, | 214 | .receive_buf = n_hdlc_tty_receive, |
215 | .receive_room = n_hdlc_tty_room, | ||
216 | .write_wakeup = n_hdlc_tty_wakeup, | 215 | .write_wakeup = n_hdlc_tty_wakeup, |
217 | }; | 216 | }; |
218 | 217 | ||
@@ -337,6 +336,7 @@ static int n_hdlc_tty_open (struct tty_struct *tty) | |||
337 | 336 | ||
338 | tty->disc_data = n_hdlc; | 337 | tty->disc_data = n_hdlc; |
339 | n_hdlc->tty = tty; | 338 | n_hdlc->tty = tty; |
339 | tty->receive_room = 65536; | ||
340 | 340 | ||
341 | #if defined(TTY_NO_WRITE_SPLIT) | 341 | #if defined(TTY_NO_WRITE_SPLIT) |
342 | /* change tty_io write() to not split large writes into 8K chunks */ | 342 | /* change tty_io write() to not split large writes into 8K chunks */ |
@@ -478,22 +478,6 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) | |||
478 | } /* end of n_hdlc_tty_wakeup() */ | 478 | } /* end of n_hdlc_tty_wakeup() */ |
479 | 479 | ||
480 | /** | 480 | /** |
481 | * n_hdlc_tty_room - Return the amount of space left in the receiver's buffer | ||
482 | * @tty - pointer to associated tty instance data | ||
483 | * | ||
484 | * Callback function from tty driver. Return the amount of space left in the | ||
485 | * receiver's buffer to decide if remote transmitter is to be throttled. | ||
486 | */ | ||
487 | static int n_hdlc_tty_room(struct tty_struct *tty) | ||
488 | { | ||
489 | if (debuglevel >= DEBUG_LEVEL_INFO) | ||
490 | printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__); | ||
491 | /* always return a larger number to prevent */ | ||
492 | /* throttling of remote transmitter. */ | ||
493 | return 65536; | ||
494 | } /* end of n_hdlc_tty_root() */ | ||
495 | |||
496 | /** | ||
497 | * n_hdlc_tty_receive - Called by tty driver when receive data is available | 481 | * n_hdlc_tty_receive - Called by tty driver when receive data is available |
498 | * @tty - pointer to tty instance data | 482 | * @tty - pointer to tty instance data |
499 | * @data - pointer to received data | 483 | * @data - pointer to received data |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 853c98cee64f..c48de09d68f0 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -147,7 +147,6 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file, | |||
147 | struct poll_table_struct *wait); | 147 | struct poll_table_struct *wait); |
148 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 148 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
149 | char *fp, int count); | 149 | char *fp, int count); |
150 | static int r3964_receive_room(struct tty_struct *tty); | ||
151 | 150 | ||
152 | static struct tty_ldisc tty_ldisc_N_R3964 = { | 151 | static struct tty_ldisc tty_ldisc_N_R3964 = { |
153 | .owner = THIS_MODULE, | 152 | .owner = THIS_MODULE, |
@@ -161,7 +160,6 @@ static struct tty_ldisc tty_ldisc_N_R3964 = { | |||
161 | .set_termios = r3964_set_termios, | 160 | .set_termios = r3964_set_termios, |
162 | .poll = r3964_poll, | 161 | .poll = r3964_poll, |
163 | .receive_buf = r3964_receive_buf, | 162 | .receive_buf = r3964_receive_buf, |
164 | .receive_room = r3964_receive_room, | ||
165 | }; | 163 | }; |
166 | 164 | ||
167 | 165 | ||
@@ -1119,6 +1117,7 @@ static int r3964_open(struct tty_struct *tty) | |||
1119 | pInfo->nRetry = 0; | 1117 | pInfo->nRetry = 0; |
1120 | 1118 | ||
1121 | tty->disc_data = pInfo; | 1119 | tty->disc_data = pInfo; |
1120 | tty->receive_room = 65536; | ||
1122 | 1121 | ||
1123 | init_timer(&pInfo->tmr); | 1122 | init_timer(&pInfo->tmr); |
1124 | pInfo->tmr.data = (unsigned long)pInfo; | 1123 | pInfo->tmr.data = (unsigned long)pInfo; |
@@ -1405,12 +1404,5 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1405 | } | 1404 | } |
1406 | } | 1405 | } |
1407 | 1406 | ||
1408 | static int r3964_receive_room(struct tty_struct *tty) | ||
1409 | { | ||
1410 | TRACE_L("receive_room"); | ||
1411 | return -1; | ||
1412 | } | ||
1413 | |||
1414 | |||
1415 | MODULE_LICENSE("GPL"); | 1407 | MODULE_LICENSE("GPL"); |
1416 | MODULE_ALIAS_LDISC(N_R3964); | 1408 | MODULE_ALIAS_LDISC(N_R3964); |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index c556f4d3ccd7..ccad7ae94541 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -78,7 +78,32 @@ static inline void free_buf(unsigned char *buf) | |||
78 | free_page((unsigned long) buf); | 78 | free_page((unsigned long) buf); |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 81 | /** |
82 | * n_tty_set__room - receive space | ||
83 | * @tty: terminal | ||
84 | * | ||
85 | * Called by the driver to find out how much data it is | ||
86 | * permitted to feed to the line discipline without any being lost | ||
87 | * and thus to manage flow control. Not serialized. Answers for the | ||
88 | * "instant". | ||
89 | */ | ||
90 | |||
91 | static void n_tty_set_room(struct tty_struct *tty) | ||
92 | { | ||
93 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
94 | |||
95 | /* | ||
96 | * If we are doing input canonicalization, and there are no | ||
97 | * pending newlines, let characters through without limit, so | ||
98 | * that erase characters will be handled. Other excess | ||
99 | * characters will be beeped. | ||
100 | */ | ||
101 | if (left <= 0) | ||
102 | left = tty->icanon && !tty->canon_data; | ||
103 | tty->receive_room = left; | ||
104 | } | ||
105 | |||
106 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | ||
82 | { | 107 | { |
83 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 108 | if (tty->read_cnt < N_TTY_BUF_SIZE) { |
84 | tty->read_buf[tty->read_head] = c; | 109 | tty->read_buf[tty->read_head] = c; |
@@ -87,7 +112,7 @@ static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | |||
87 | } | 112 | } |
88 | } | 113 | } |
89 | 114 | ||
90 | static inline void put_tty_queue(unsigned char c, struct tty_struct *tty) | 115 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) |
91 | { | 116 | { |
92 | unsigned long flags; | 117 | unsigned long flags; |
93 | /* | 118 | /* |
@@ -136,6 +161,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
136 | spin_unlock_irqrestore(&tty->read_lock, flags); | 161 | spin_unlock_irqrestore(&tty->read_lock, flags); |
137 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 162 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
138 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 163 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
164 | n_tty_set_room(tty); | ||
139 | check_unthrottle(tty); | 165 | check_unthrottle(tty); |
140 | } | 166 | } |
141 | 167 | ||
@@ -838,30 +864,6 @@ send_signal: | |||
838 | put_tty_queue(c, tty); | 864 | put_tty_queue(c, tty); |
839 | } | 865 | } |
840 | 866 | ||
841 | /** | ||
842 | * n_tty_receive_room - receive space | ||
843 | * @tty: terminal | ||
844 | * | ||
845 | * Called by the driver to find out how much data it is | ||
846 | * permitted to feed to the line discipline without any being lost | ||
847 | * and thus to manage flow control. Not serialized. Answers for the | ||
848 | * "instant". | ||
849 | */ | ||
850 | |||
851 | static int n_tty_receive_room(struct tty_struct *tty) | ||
852 | { | ||
853 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
854 | |||
855 | /* | ||
856 | * If we are doing input canonicalization, and there are no | ||
857 | * pending newlines, let characters through without limit, so | ||
858 | * that erase characters will be handled. Other excess | ||
859 | * characters will be beeped. | ||
860 | */ | ||
861 | if (left <= 0) | ||
862 | left = tty->icanon && !tty->canon_data; | ||
863 | return left; | ||
864 | } | ||
865 | 867 | ||
866 | /** | 868 | /** |
867 | * n_tty_write_wakeup - asynchronous I/O notifier | 869 | * n_tty_write_wakeup - asynchronous I/O notifier |
@@ -953,6 +955,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
953 | tty->driver->flush_chars(tty); | 955 | tty->driver->flush_chars(tty); |
954 | } | 956 | } |
955 | 957 | ||
958 | n_tty_set_room(tty); | ||
959 | |||
956 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { | 960 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { |
957 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 961 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
958 | if (waitqueue_active(&tty->read_wait)) | 962 | if (waitqueue_active(&tty->read_wait)) |
@@ -964,7 +968,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
964 | * mode. We don't want to throttle the driver if we're in | 968 | * mode. We don't want to throttle the driver if we're in |
965 | * canonical mode and don't have a newline yet! | 969 | * canonical mode and don't have a newline yet! |
966 | */ | 970 | */ |
967 | if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) { | 971 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) { |
968 | /* check TTY_THROTTLED first so it indicates our state */ | 972 | /* check TTY_THROTTLED first so it indicates our state */ |
969 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | 973 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && |
970 | tty->driver->throttle) | 974 | tty->driver->throttle) |
@@ -999,6 +1003,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | |||
999 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1003 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1000 | tty->raw = 1; | 1004 | tty->raw = 1; |
1001 | tty->real_raw = 1; | 1005 | tty->real_raw = 1; |
1006 | n_tty_set_room(tty); | ||
1002 | return; | 1007 | return; |
1003 | } | 1008 | } |
1004 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || | 1009 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || |
@@ -1051,6 +1056,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | |||
1051 | else | 1056 | else |
1052 | tty->real_raw = 0; | 1057 | tty->real_raw = 0; |
1053 | } | 1058 | } |
1059 | n_tty_set_room(tty); | ||
1054 | } | 1060 | } |
1055 | 1061 | ||
1056 | /** | 1062 | /** |
@@ -1130,7 +1136,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1130 | * | 1136 | * |
1131 | */ | 1137 | */ |
1132 | 1138 | ||
1133 | static inline int copy_from_read_buf(struct tty_struct *tty, | 1139 | static int copy_from_read_buf(struct tty_struct *tty, |
1134 | unsigned char __user **b, | 1140 | unsigned char __user **b, |
1135 | size_t *nr) | 1141 | size_t *nr) |
1136 | 1142 | ||
@@ -1308,6 +1314,7 @@ do_it_again: | |||
1308 | retval = -ERESTARTSYS; | 1314 | retval = -ERESTARTSYS; |
1309 | break; | 1315 | break; |
1310 | } | 1316 | } |
1317 | n_tty_set_room(tty); | ||
1311 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 1318 | clear_bit(TTY_DONT_FLIP, &tty->flags); |
1312 | timeout = schedule_timeout(timeout); | 1319 | timeout = schedule_timeout(timeout); |
1313 | set_bit(TTY_DONT_FLIP, &tty->flags); | 1320 | set_bit(TTY_DONT_FLIP, &tty->flags); |
@@ -1401,6 +1408,8 @@ do_it_again: | |||
1401 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1408 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1402 | goto do_it_again; | 1409 | goto do_it_again; |
1403 | 1410 | ||
1411 | n_tty_set_room(tty); | ||
1412 | |||
1404 | return retval; | 1413 | return retval; |
1405 | } | 1414 | } |
1406 | 1415 | ||
@@ -1553,7 +1562,6 @@ struct tty_ldisc tty_ldisc_N_TTY = { | |||
1553 | normal_poll, /* poll */ | 1562 | normal_poll, /* poll */ |
1554 | NULL, /* hangup */ | 1563 | NULL, /* hangup */ |
1555 | n_tty_receive_buf, /* receive_buf */ | 1564 | n_tty_receive_buf, /* receive_buf */ |
1556 | n_tty_receive_room, /* receive_room */ | ||
1557 | n_tty_write_wakeup /* write_wakeup */ | 1565 | n_tty_write_wakeup /* write_wakeup */ |
1558 | }; | 1566 | }; |
1559 | 1567 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 9fb10c9fec88..8a8ca32822ba 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -1007,8 +1007,9 @@ static void rx_ready_hdlc(MGSLPC_INFO *info, int eom) | |||
1007 | 1007 | ||
1008 | static void rx_ready_async(MGSLPC_INFO *info, int tcd) | 1008 | static void rx_ready_async(MGSLPC_INFO *info, int tcd) |
1009 | { | 1009 | { |
1010 | unsigned char data, status; | 1010 | unsigned char data, status, flag; |
1011 | int fifo_count; | 1011 | int fifo_count; |
1012 | int work = 0; | ||
1012 | struct tty_struct *tty = info->tty; | 1013 | struct tty_struct *tty = info->tty; |
1013 | struct mgsl_icount *icount = &info->icount; | 1014 | struct mgsl_icount *icount = &info->icount; |
1014 | 1015 | ||
@@ -1023,20 +1024,16 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd) | |||
1023 | fifo_count = 32; | 1024 | fifo_count = 32; |
1024 | } else | 1025 | } else |
1025 | fifo_count = 32; | 1026 | fifo_count = 32; |
1026 | 1027 | ||
1028 | tty_buffer_request_room(tty, fifo_count); | ||
1027 | /* Flush received async data to receive data buffer. */ | 1029 | /* Flush received async data to receive data buffer. */ |
1028 | while (fifo_count) { | 1030 | while (fifo_count) { |
1029 | data = read_reg(info, CHA + RXFIFO); | 1031 | data = read_reg(info, CHA + RXFIFO); |
1030 | status = read_reg(info, CHA + RXFIFO); | 1032 | status = read_reg(info, CHA + RXFIFO); |
1031 | fifo_count -= 2; | 1033 | fifo_count -= 2; |
1032 | 1034 | ||
1033 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1034 | break; | ||
1035 | |||
1036 | *tty->flip.char_buf_ptr = data; | ||
1037 | icount->rx++; | 1035 | icount->rx++; |
1038 | 1036 | flag = TTY_NORMAL; | |
1039 | *tty->flip.flag_buf_ptr = 0; | ||
1040 | 1037 | ||
1041 | // if no frameing/crc error then save data | 1038 | // if no frameing/crc error then save data |
1042 | // BIT7:parity error | 1039 | // BIT7:parity error |
@@ -1055,26 +1052,23 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd) | |||
1055 | status &= info->read_status_mask; | 1052 | status &= info->read_status_mask; |
1056 | 1053 | ||
1057 | if (status & BIT7) | 1054 | if (status & BIT7) |
1058 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 1055 | flag = TTY_PARITY; |
1059 | else if (status & BIT6) | 1056 | else if (status & BIT6) |
1060 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 1057 | flag = TTY_FRAME; |
1061 | } | 1058 | } |
1062 | 1059 | work += tty_insert_flip_char(tty, data, flag); | |
1063 | tty->flip.flag_buf_ptr++; | ||
1064 | tty->flip.char_buf_ptr++; | ||
1065 | tty->flip.count++; | ||
1066 | } | 1060 | } |
1067 | issue_command(info, CHA, CMD_RXFIFO); | 1061 | issue_command(info, CHA, CMD_RXFIFO); |
1068 | 1062 | ||
1069 | if (debug_level >= DEBUG_LEVEL_ISR) { | 1063 | if (debug_level >= DEBUG_LEVEL_ISR) { |
1070 | printk("%s(%d):rx_ready_async count=%d\n", | 1064 | printk("%s(%d):rx_ready_async", |
1071 | __FILE__,__LINE__,tty->flip.count); | 1065 | __FILE__,__LINE__); |
1072 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", | 1066 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", |
1073 | __FILE__,__LINE__,icount->rx,icount->brk, | 1067 | __FILE__,__LINE__,icount->rx,icount->brk, |
1074 | icount->parity,icount->frame,icount->overrun); | 1068 | icount->parity,icount->frame,icount->overrun); |
1075 | } | 1069 | } |
1076 | 1070 | ||
1077 | if (tty->flip.count) | 1071 | if (work) |
1078 | tty_flip_buffer_push(tty); | 1072 | tty_flip_buffer_push(tty); |
1079 | } | 1073 | } |
1080 | 1074 | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 49f3997fd251..9b5a2c0e7008 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun | |||
111 | if (!to || tty->stopped) | 111 | if (!to || tty->stopped) |
112 | return 0; | 112 | return 0; |
113 | 113 | ||
114 | c = to->ldisc.receive_room(to); | 114 | c = to->receive_room; |
115 | if (c > count) | 115 | if (c > count) |
116 | c = count; | 116 | c = count; |
117 | to->ldisc.receive_buf(to, buf, NULL, c); | 117 | to->ldisc.receive_buf(to, buf, NULL, c); |
@@ -126,7 +126,7 @@ static int pty_write_room(struct tty_struct *tty) | |||
126 | if (!to || tty->stopped) | 126 | if (!to || tty->stopped) |
127 | return 0; | 127 | return 0; |
128 | 128 | ||
129 | return to->ldisc.receive_room(to); | 129 | return to->receive_room; |
130 | } | 130 | } |
131 | 131 | ||
132 | /* | 132 | /* |
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index e42e7b50bf6b..ddda9c14e059 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c | |||
@@ -38,6 +38,7 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2"; | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
40 | #include <linux/tty.h> | 40 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | ||
41 | #include <asm/io.h> | 42 | #include <asm/io.h> |
42 | #include <asm/system.h> | 43 | #include <asm/system.h> |
43 | #include <asm/string.h> | 44 | #include <asm/string.h> |
@@ -560,6 +561,7 @@ struct Port * PortP; | |||
560 | struct PKT *PacketP; | 561 | struct PKT *PacketP; |
561 | register uint DataCnt; | 562 | register uint DataCnt; |
562 | uchar * ptr; | 563 | uchar * ptr; |
564 | unsigned char *buf; | ||
563 | int copied =0; | 565 | int copied =0; |
564 | 566 | ||
565 | static int intCount, RxIntCnt; | 567 | static int intCount, RxIntCnt; |
@@ -657,8 +659,7 @@ struct Port * PortP; | |||
657 | ** and available space. | 659 | ** and available space. |
658 | */ | 660 | */ |
659 | 661 | ||
660 | transCount = min_t(unsigned int, PacketP->len & PKT_LEN_MASK, | 662 | transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK); |
661 | TTY_FLIPBUF_SIZE - TtyP->flip.count); | ||
662 | rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n", | 663 | rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n", |
663 | PortP->PortNum, transCount); | 664 | PortP->PortNum, transCount); |
664 | /* | 665 | /* |
@@ -678,9 +679,8 @@ struct Port * PortP; | |||
678 | #endif | 679 | #endif |
679 | ptr = (uchar *) PacketP->data + PortP->RxDataStart; | 680 | ptr = (uchar *) PacketP->data + PortP->RxDataStart; |
680 | 681 | ||
681 | rio_memcpy_fromio (TtyP->flip.char_buf_ptr, ptr, transCount); | 682 | tty_prepare_flip_string(TtyP, &buf, transCount); |
682 | memset(TtyP->flip.flag_buf_ptr, TTY_NORMAL, transCount); | 683 | rio_memcpy_fromio (buf, ptr, transCount); |
683 | |||
684 | #ifdef STATS | 684 | #ifdef STATS |
685 | /* | 685 | /* |
686 | ** keep a count for statistical purposes | 686 | ** keep a count for statistical purposes |
@@ -690,9 +690,6 @@ struct Port * PortP; | |||
690 | PortP->RxDataStart += transCount; | 690 | PortP->RxDataStart += transCount; |
691 | PacketP->len -= transCount; | 691 | PacketP->len -= transCount; |
692 | copied += transCount; | 692 | copied += transCount; |
693 | TtyP->flip.count += transCount; | ||
694 | TtyP->flip.char_buf_ptr += transCount; | ||
695 | TtyP->flip.flag_buf_ptr += transCount; | ||
696 | 693 | ||
697 | 694 | ||
698 | #ifdef ___DEBUG_IT___ | 695 | #ifdef ___DEBUG_IT___ |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 5dae32521620..050e70ee5920 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/major.h> | 46 | #include <linux/major.h> |
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/tty_flip.h> | ||
49 | 50 | ||
50 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
51 | 52 | ||
@@ -354,28 +355,17 @@ static inline void rc_receive_exc(struct riscom_board const * bp) | |||
354 | struct riscom_port *port; | 355 | struct riscom_port *port; |
355 | struct tty_struct *tty; | 356 | struct tty_struct *tty; |
356 | unsigned char status; | 357 | unsigned char status; |
357 | unsigned char ch; | 358 | unsigned char ch, flag; |
358 | 359 | ||
359 | if (!(port = rc_get_port(bp, "Receive"))) | 360 | if (!(port = rc_get_port(bp, "Receive"))) |
360 | return; | 361 | return; |
361 | 362 | ||
362 | tty = port->tty; | 363 | tty = port->tty; |
363 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
364 | printk(KERN_WARNING "rc%d: port %d: Working around flip " | ||
365 | "buffer overflow.\n", | ||
366 | board_No(bp), port_No(port)); | ||
367 | return; | ||
368 | } | ||
369 | 364 | ||
370 | #ifdef RC_REPORT_OVERRUN | 365 | #ifdef RC_REPORT_OVERRUN |
371 | status = rc_in(bp, CD180_RCSR); | 366 | status = rc_in(bp, CD180_RCSR); |
372 | if (status & RCSR_OE) { | 367 | if (status & RCSR_OE) |
373 | port->overrun++; | 368 | port->overrun++; |
374 | #if 0 | ||
375 | printk(KERN_ERR "rc%d: port %d: Overrun. Total %ld overruns\n", | ||
376 | board_No(bp), port_No(port), port->overrun); | ||
377 | #endif | ||
378 | } | ||
379 | status &= port->mark_mask; | 369 | status &= port->mark_mask; |
380 | #else | 370 | #else |
381 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; | 371 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; |
@@ -393,25 +383,24 @@ static inline void rc_receive_exc(struct riscom_board const * bp) | |||
393 | } else if (status & RCSR_BREAK) { | 383 | } else if (status & RCSR_BREAK) { |
394 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", | 384 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", |
395 | board_No(bp), port_No(port)); | 385 | board_No(bp), port_No(port)); |
396 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 386 | flag = TTY_BREAK; |
397 | if (port->flags & ASYNC_SAK) | 387 | if (port->flags & ASYNC_SAK) |
398 | do_SAK(tty); | 388 | do_SAK(tty); |
399 | 389 | ||
400 | } else if (status & RCSR_PE) | 390 | } else if (status & RCSR_PE) |
401 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 391 | flag = TTY_PARITY; |
402 | 392 | ||
403 | else if (status & RCSR_FE) | 393 | else if (status & RCSR_FE) |
404 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 394 | flag = TTY_FRAME; |
405 | 395 | ||
406 | else if (status & RCSR_OE) | 396 | else if (status & RCSR_OE) |
407 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 397 | flag = TTY_OVERRUN; |
408 | 398 | ||
409 | else | 399 | else |
410 | *tty->flip.flag_buf_ptr++ = 0; | 400 | flag = TTY_NORMAL; |
411 | 401 | ||
412 | *tty->flip.char_buf_ptr++ = ch; | 402 | tty_insert_flip_char(tty, ch, flag); |
413 | tty->flip.count++; | 403 | tty_flip_buffer_push(tty); |
414 | schedule_delayed_work(&tty->flip.work, 1); | ||
415 | } | 404 | } |
416 | 405 | ||
417 | static inline void rc_receive(struct riscom_board const * bp) | 406 | static inline void rc_receive(struct riscom_board const * bp) |
@@ -432,17 +421,15 @@ static inline void rc_receive(struct riscom_board const * bp) | |||
432 | #endif | 421 | #endif |
433 | 422 | ||
434 | while (count--) { | 423 | while (count--) { |
435 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 424 | if (tty_buffer_request_room(tty, 1) == 0) { |
436 | printk(KERN_WARNING "rc%d: port %d: Working around " | 425 | printk(KERN_WARNING "rc%d: port %d: Working around " |
437 | "flip buffer overflow.\n", | 426 | "flip buffer overflow.\n", |
438 | board_No(bp), port_No(port)); | 427 | board_No(bp), port_No(port)); |
439 | break; | 428 | break; |
440 | } | 429 | } |
441 | *tty->flip.char_buf_ptr++ = rc_in(bp, CD180_RDR); | 430 | tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL); |
442 | *tty->flip.flag_buf_ptr++ = 0; | ||
443 | tty->flip.count++; | ||
444 | } | 431 | } |
445 | schedule_delayed_work(&tty->flip.work, 1); | 432 | tty_flip_buffer_push(tty); |
446 | } | 433 | } |
447 | 434 | ||
448 | static inline void rc_transmit(struct riscom_board const * bp) | 435 | static inline void rc_transmit(struct riscom_board const * bp) |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index d3bc731fbb27..0949dcef0697 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -325,19 +325,16 @@ static void rp_do_receive(struct r_port *info, | |||
325 | { | 325 | { |
326 | unsigned int CharNStat; | 326 | unsigned int CharNStat; |
327 | int ToRecv, wRecv, space = 0, count; | 327 | int ToRecv, wRecv, space = 0, count; |
328 | unsigned char *cbuf; | 328 | unsigned char *cbuf, *chead; |
329 | char *fbuf; | 329 | char *fbuf, *fhead; |
330 | struct tty_ldisc *ld; | 330 | struct tty_ldisc *ld; |
331 | 331 | ||
332 | ld = tty_ldisc_ref(tty); | 332 | ld = tty_ldisc_ref(tty); |
333 | 333 | ||
334 | ToRecv = sGetRxCnt(cp); | 334 | ToRecv = sGetRxCnt(cp); |
335 | if (ld) | 335 | space = tty->receive_room; |
336 | space = ld->receive_room(tty); | ||
337 | if (space > 2 * TTY_FLIPBUF_SIZE) | 336 | if (space > 2 * TTY_FLIPBUF_SIZE) |
338 | space = 2 * TTY_FLIPBUF_SIZE; | 337 | space = 2 * TTY_FLIPBUF_SIZE; |
339 | cbuf = tty->flip.char_buf; | ||
340 | fbuf = tty->flip.flag_buf; | ||
341 | count = 0; | 338 | count = 0; |
342 | #ifdef ROCKET_DEBUG_INTR | 339 | #ifdef ROCKET_DEBUG_INTR |
343 | printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space); | 340 | printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space); |
@@ -350,9 +347,13 @@ static void rp_do_receive(struct r_port *info, | |||
350 | if (ToRecv > space) | 347 | if (ToRecv > space) |
351 | ToRecv = space; | 348 | ToRecv = space; |
352 | 349 | ||
350 | ToRecv = tty_prepare_flip_string_flags(tty, &chead, &fhead, ToRecv); | ||
353 | if (ToRecv <= 0) | 351 | if (ToRecv <= 0) |
354 | goto done; | 352 | goto done; |
355 | 353 | ||
354 | cbuf = chead; | ||
355 | fbuf = fhead; | ||
356 | |||
356 | /* | 357 | /* |
357 | * if status indicates there are errored characters in the | 358 | * if status indicates there are errored characters in the |
358 | * FIFO, then enter status mode (a word in FIFO holds | 359 | * FIFO, then enter status mode (a word in FIFO holds |
@@ -399,7 +400,7 @@ static void rp_do_receive(struct r_port *info, | |||
399 | else if (CharNStat & STMRCVROVRH) | 400 | else if (CharNStat & STMRCVROVRH) |
400 | *fbuf++ = TTY_OVERRUN; | 401 | *fbuf++ = TTY_OVERRUN; |
401 | else | 402 | else |
402 | *fbuf++ = 0; | 403 | *fbuf++ = TTY_NORMAL; |
403 | *cbuf++ = CharNStat & 0xff; | 404 | *cbuf++ = CharNStat & 0xff; |
404 | count++; | 405 | count++; |
405 | ToRecv--; | 406 | ToRecv--; |
@@ -426,13 +427,13 @@ static void rp_do_receive(struct r_port *info, | |||
426 | sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); | 427 | sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); |
427 | if (ToRecv & 1) | 428 | if (ToRecv & 1) |
428 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); | 429 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); |
429 | memset(fbuf, 0, ToRecv); | 430 | memset(fbuf, TTY_NORMAL, ToRecv); |
430 | cbuf += ToRecv; | 431 | cbuf += ToRecv; |
431 | fbuf += ToRecv; | 432 | fbuf += ToRecv; |
432 | count += ToRecv; | 433 | count += ToRecv; |
433 | } | 434 | } |
434 | /* Push the data up to the tty layer */ | 435 | /* Push the data up to the tty layer */ |
435 | ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); | 436 | ld->receive_buf(tty, cbuf, fbuf, count); |
436 | done: | 437 | done: |
437 | tty_ldisc_deref(ld); | 438 | tty_ldisc_deref(ld); |
438 | } | 439 | } |
diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 5b187c895c18..71093a9fc462 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c | |||
@@ -275,7 +275,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t | |||
275 | int paste_selection(struct tty_struct *tty) | 275 | int paste_selection(struct tty_struct *tty) |
276 | { | 276 | { |
277 | struct vc_data *vc = (struct vc_data *)tty->driver_data; | 277 | struct vc_data *vc = (struct vc_data *)tty->driver_data; |
278 | int pasted = 0, count; | 278 | int pasted = 0; |
279 | unsigned int count; | ||
279 | struct tty_ldisc *ld; | 280 | struct tty_ldisc *ld; |
280 | DECLARE_WAITQUEUE(wait, current); | 281 | DECLARE_WAITQUEUE(wait, current); |
281 | 282 | ||
@@ -293,7 +294,7 @@ int paste_selection(struct tty_struct *tty) | |||
293 | continue; | 294 | continue; |
294 | } | 295 | } |
295 | count = sel_buffer_lth - pasted; | 296 | count = sel_buffer_lth - pasted; |
296 | count = min(count, tty->ldisc.receive_room(tty)); | 297 | count = min(count, tty->receive_room); |
297 | tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count); | 298 | tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count); |
298 | pasted += count; | 299 | pasted += count; |
299 | } | 300 | } |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index dda30e42ec79..80a5b840e22f 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -194,11 +194,6 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) | |||
194 | */ | 194 | */ |
195 | struct tty_struct *tty = port->gs.tty; | 195 | struct tty_struct *tty = port->gs.tty; |
196 | 196 | ||
197 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
198 | return; | ||
199 | |||
200 | tty->flip.count++; | ||
201 | |||
202 | #if 0 | 197 | #if 0 |
203 | switch(err) { | 198 | switch(err) { |
204 | case TTY_BREAK: | 199 | case TTY_BREAK: |
@@ -212,8 +207,7 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) | |||
212 | } | 207 | } |
213 | #endif | 208 | #endif |
214 | 209 | ||
215 | *tty->flip.flag_buf_ptr++ = err; | 210 | tty_insert_flip_char(tty, ch, err); |
216 | *tty->flip.char_buf_ptr++ = ch; | ||
217 | tty_flip_buffer_push(tty); | 211 | tty_flip_buffer_push(tty); |
218 | } | 212 | } |
219 | 213 | ||
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index a580748b92a1..f36342ae8e7e 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -422,45 +422,35 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp) | |||
422 | base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; | 422 | base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; |
423 | return IRQ_HANDLED; | 423 | return IRQ_HANDLED; |
424 | } | 424 | } |
425 | if (tty->flip.count < TTY_FLIPBUF_SIZE){ | 425 | if (tty_buffer_request_room(tty, 1) != 0){ |
426 | tty->flip.count++; | ||
427 | if (err & info->read_status_mask){ | 426 | if (err & info->read_status_mask){ |
428 | if(err & CyBREAK){ | 427 | if(err & CyBREAK){ |
429 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 428 | tty_insert_flip_char(tty, data, TTY_BREAK); |
430 | *tty->flip.char_buf_ptr++ = data; | ||
431 | if (info->flags & ASYNC_SAK){ | 429 | if (info->flags & ASYNC_SAK){ |
432 | do_SAK(tty); | 430 | do_SAK(tty); |
433 | } | 431 | } |
434 | }else if(err & CyFRAME){ | 432 | }else if(err & CyFRAME){ |
435 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 433 | tty_insert_flip_char(tty, data, TTY_FRAME); |
436 | *tty->flip.char_buf_ptr++ = data; | ||
437 | }else if(err & CyPARITY){ | 434 | }else if(err & CyPARITY){ |
438 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 435 | tty_insert_flip_char(tty, data, TTY_PARITY); |
439 | *tty->flip.char_buf_ptr++ = data; | ||
440 | }else if(err & CyOVERRUN){ | 436 | }else if(err & CyOVERRUN){ |
441 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 437 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
442 | *tty->flip.char_buf_ptr++ = 0; | ||
443 | /* | 438 | /* |
444 | If the flip buffer itself is | 439 | If the flip buffer itself is |
445 | overflowing, we still loose | 440 | overflowing, we still loose |
446 | the next incoming character. | 441 | the next incoming character. |
447 | */ | 442 | */ |
448 | if(tty->flip.count < TTY_FLIPBUF_SIZE){ | 443 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
449 | tty->flip.count++; | 444 | } |
450 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
451 | *tty->flip.char_buf_ptr++ = data; | ||
452 | } | ||
453 | /* These two conditions may imply */ | 445 | /* These two conditions may imply */ |
454 | /* a normal read should be done. */ | 446 | /* a normal read should be done. */ |
455 | /* else if(data & CyTIMEOUT) */ | 447 | /* else if(data & CyTIMEOUT) */ |
456 | /* else if(data & CySPECHAR) */ | 448 | /* else if(data & CySPECHAR) */ |
457 | }else{ | 449 | }else{ |
458 | *tty->flip.flag_buf_ptr++ = 0; | 450 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
459 | *tty->flip.char_buf_ptr++ = 0; | ||
460 | } | 451 | } |
461 | }else{ | 452 | }else{ |
462 | *tty->flip.flag_buf_ptr++ = 0; | 453 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
463 | *tty->flip.char_buf_ptr++ = 0; | ||
464 | } | 454 | } |
465 | }else{ | 455 | }else{ |
466 | /* there was a software buffer overrun | 456 | /* there was a software buffer overrun |
@@ -692,12 +682,7 @@ cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp) | |||
692 | #endif | 682 | #endif |
693 | while(char_count--){ | 683 | while(char_count--){ |
694 | data = base_addr[CyRDR]; | 684 | data = base_addr[CyRDR]; |
695 | if (tty->flip.count >= TTY_FLIPBUF_SIZE){ | 685 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
696 | continue; | ||
697 | } | ||
698 | tty->flip.count++; | ||
699 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
700 | *tty->flip.char_buf_ptr++ = data; | ||
701 | #ifdef CYCLOM_16Y_HACK | 686 | #ifdef CYCLOM_16Y_HACK |
702 | udelay(10L); | 687 | udelay(10L); |
703 | #endif | 688 | #endif |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 0bbfce43031c..0a574bdbce36 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/interrupt.h> | 85 | #include <linux/interrupt.h> |
86 | #include <linux/errno.h> | 86 | #include <linux/errno.h> |
87 | #include <linux/tty.h> | 87 | #include <linux/tty.h> |
88 | #include <linux/tty_flip.h> | ||
88 | #include <linux/mm.h> | 89 | #include <linux/mm.h> |
89 | #include <linux/serial.h> | 90 | #include <linux/serial.h> |
90 | #include <linux/fcntl.h> | 91 | #include <linux/fcntl.h> |
@@ -665,7 +666,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
665 | struct specialix_port *port; | 666 | struct specialix_port *port; |
666 | struct tty_struct *tty; | 667 | struct tty_struct *tty; |
667 | unsigned char status; | 668 | unsigned char status; |
668 | unsigned char ch; | 669 | unsigned char ch, flag; |
669 | 670 | ||
670 | func_enter(); | 671 | func_enter(); |
671 | 672 | ||
@@ -676,8 +677,6 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
676 | return; | 677 | return; |
677 | } | 678 | } |
678 | tty = port->tty; | 679 | tty = port->tty; |
679 | dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n", | ||
680 | port, tty->flip.count, TTY_FLIPBUF_SIZE); | ||
681 | 680 | ||
682 | status = sx_in(bp, CD186x_RCSR); | 681 | status = sx_in(bp, CD186x_RCSR); |
683 | 682 | ||
@@ -691,7 +690,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
691 | 690 | ||
692 | /* This flip buffer check needs to be below the reading of the | 691 | /* This flip buffer check needs to be below the reading of the |
693 | status register to reset the chip's IRQ.... */ | 692 | status register to reset the chip's IRQ.... */ |
694 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 693 | if (tty_buffer_request_room(tty, 1) == 0) { |
695 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", | 694 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", |
696 | board_No(bp), port_No(port)); | 695 | board_No(bp), port_No(port)); |
697 | func_exit(); | 696 | func_exit(); |
@@ -712,26 +711,24 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
712 | } else if (status & RCSR_BREAK) { | 711 | } else if (status & RCSR_BREAK) { |
713 | dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", | 712 | dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", |
714 | board_No(bp), port_No(port)); | 713 | board_No(bp), port_No(port)); |
715 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 714 | flag = TTY_BREAK; |
716 | if (port->flags & ASYNC_SAK) | 715 | if (port->flags & ASYNC_SAK) |
717 | do_SAK(tty); | 716 | do_SAK(tty); |
718 | 717 | ||
719 | } else if (status & RCSR_PE) | 718 | } else if (status & RCSR_PE) |
720 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 719 | flag = TTY_PARITY; |
721 | 720 | ||
722 | else if (status & RCSR_FE) | 721 | else if (status & RCSR_FE) |
723 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 722 | flag = TTY_FRAME; |
724 | 723 | ||
725 | else if (status & RCSR_OE) | 724 | else if (status & RCSR_OE) |
726 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 725 | flag = TTY_OVERRUN; |
727 | 726 | ||
728 | else | 727 | else |
729 | *tty->flip.flag_buf_ptr++ = 0; | 728 | flag = TTY_NORMAL; |
730 | |||
731 | *tty->flip.char_buf_ptr++ = ch; | ||
732 | tty->flip.count++; | ||
733 | schedule_delayed_work(&tty->flip.work, 1); | ||
734 | 729 | ||
730 | if(tty_insert_flip_char(tty, ch, flag)) | ||
731 | tty_flip_buffer_push(tty); | ||
735 | func_exit(); | 732 | func_exit(); |
736 | } | 733 | } |
737 | 734 | ||
@@ -755,18 +752,11 @@ static inline void sx_receive(struct specialix_board * bp) | |||
755 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); | 752 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); |
756 | port->hits[count > 8 ? 9 : count]++; | 753 | port->hits[count > 8 ? 9 : count]++; |
757 | 754 | ||
758 | while (count--) { | 755 | tty_buffer_request_room(tty, count); |
759 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
760 | printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n", | ||
761 | board_No(bp), port_No(port)); | ||
762 | break; | ||
763 | } | ||
764 | *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR); | ||
765 | *tty->flip.flag_buf_ptr++ = 0; | ||
766 | tty->flip.count++; | ||
767 | } | ||
768 | schedule_delayed_work(&tty->flip.work, 1); | ||
769 | 756 | ||
757 | while (count--) | ||
758 | tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); | ||
759 | tty_flip_buffer_push(tty); | ||
770 | func_exit(); | 760 | func_exit(); |
771 | } | 761 | } |
772 | 762 | ||
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index acef2abf3f0d..0e20780d4a29 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -2901,7 +2901,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2901 | if (portp->tty != (struct tty_struct *) NULL) { | 2901 | if (portp->tty != (struct tty_struct *) NULL) { |
2902 | if (portp->tty->driver_data == portp) { | 2902 | if (portp->tty->driver_data == portp) { |
2903 | portp->stats.ttystate = portp->tty->flags; | 2903 | portp->stats.ttystate = portp->tty->flags; |
2904 | portp->stats.rxbuffered = portp->tty->flip.count; | 2904 | /* No longer available as a statistic */ |
2905 | portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */ | ||
2905 | if (portp->tty->termios != (struct termios *) NULL) { | 2906 | if (portp->tty->termios != (struct termios *) NULL) { |
2906 | portp->stats.cflags = portp->tty->termios->c_cflag; | 2907 | portp->stats.cflags = portp->tty->termios->c_cflag; |
2907 | portp->stats.iflags = portp->tty->termios->c_iflag; | 2908 | portp->stats.iflags = portp->tty->termios->c_iflag; |
@@ -4045,9 +4046,7 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4045 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { | 4046 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { |
4046 | outb((RDCR + portp->uartaddr), ioaddr); | 4047 | outb((RDCR + portp->uartaddr), ioaddr); |
4047 | len = inb(ioaddr + EREG_DATA); | 4048 | len = inb(ioaddr + EREG_DATA); |
4048 | if ((tty == (struct tty_struct *) NULL) || | 4049 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { |
4049 | (tty->flip.char_buf_ptr == (char *) NULL) || | ||
4050 | ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) { | ||
4051 | len = MIN(len, sizeof(stl_unwanted)); | 4050 | len = MIN(len, sizeof(stl_unwanted)); |
4052 | outb((RDSR + portp->uartaddr), ioaddr); | 4051 | outb((RDSR + portp->uartaddr), ioaddr); |
4053 | insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); | 4052 | insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); |
@@ -4056,12 +4055,10 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4056 | } else { | 4055 | } else { |
4057 | len = MIN(len, buflen); | 4056 | len = MIN(len, buflen); |
4058 | if (len > 0) { | 4057 | if (len > 0) { |
4058 | unsigned char *ptr; | ||
4059 | outb((RDSR + portp->uartaddr), ioaddr); | 4059 | outb((RDSR + portp->uartaddr), ioaddr); |
4060 | insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len); | 4060 | tty_prepare_flip_string(tty, &ptr, len); |
4061 | memset(tty->flip.flag_buf_ptr, 0, len); | 4061 | insb((ioaddr + EREG_DATA), ptr, len); |
4062 | tty->flip.flag_buf_ptr += len; | ||
4063 | tty->flip.char_buf_ptr += len; | ||
4064 | tty->flip.count += len; | ||
4065 | tty_schedule_flip(tty); | 4062 | tty_schedule_flip(tty); |
4066 | portp->stats.rxtotal += len; | 4063 | portp->stats.rxtotal += len; |
4067 | } | 4064 | } |
@@ -4085,8 +4082,7 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4085 | portp->stats.txxoff++; | 4082 | portp->stats.txxoff++; |
4086 | goto stl_rxalldone; | 4083 | goto stl_rxalldone; |
4087 | } | 4084 | } |
4088 | if ((tty != (struct tty_struct *) NULL) && | 4085 | if (tty != NULL && (portp->rxignoremsk & status) == 0) { |
4089 | ((portp->rxignoremsk & status) == 0)) { | ||
4090 | if (portp->rxmarkmsk & status) { | 4086 | if (portp->rxmarkmsk & status) { |
4091 | if (status & ST_BREAK) { | 4087 | if (status & ST_BREAK) { |
4092 | status = TTY_BREAK; | 4088 | status = TTY_BREAK; |
@@ -4106,14 +4102,8 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4106 | } else { | 4102 | } else { |
4107 | status = 0; | 4103 | status = 0; |
4108 | } | 4104 | } |
4109 | if (tty->flip.char_buf_ptr != (char *) NULL) { | 4105 | tty_insert_flip_char(tty, ch, status); |
4110 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 4106 | tty_schedule_flip(tty); |
4111 | *tty->flip.flag_buf_ptr++ = status; | ||
4112 | *tty->flip.char_buf_ptr++ = ch; | ||
4113 | tty->flip.count++; | ||
4114 | } | ||
4115 | tty_schedule_flip(tty); | ||
4116 | } | ||
4117 | } | 4107 | } |
4118 | } else { | 4108 | } else { |
4119 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); | 4109 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); |
@@ -5012,9 +5002,7 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
5012 | len = inb(ioaddr + XP_DATA) + 1; | 5002 | len = inb(ioaddr + XP_DATA) + 1; |
5013 | 5003 | ||
5014 | if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { | 5004 | if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { |
5015 | if ((tty == (struct tty_struct *) NULL) || | 5005 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { |
5016 | (tty->flip.char_buf_ptr == (char *) NULL) || | ||
5017 | ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) { | ||
5018 | len = MIN(len, sizeof(stl_unwanted)); | 5006 | len = MIN(len, sizeof(stl_unwanted)); |
5019 | outb(GRXFIFO, (ioaddr + XP_ADDR)); | 5007 | outb(GRXFIFO, (ioaddr + XP_ADDR)); |
5020 | insb((ioaddr + XP_DATA), &stl_unwanted[0], len); | 5008 | insb((ioaddr + XP_DATA), &stl_unwanted[0], len); |
@@ -5023,12 +5011,10 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
5023 | } else { | 5011 | } else { |
5024 | len = MIN(len, buflen); | 5012 | len = MIN(len, buflen); |
5025 | if (len > 0) { | 5013 | if (len > 0) { |
5014 | unsigned char *ptr; | ||
5026 | outb(GRXFIFO, (ioaddr + XP_ADDR)); | 5015 | outb(GRXFIFO, (ioaddr + XP_ADDR)); |
5027 | insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len); | 5016 | tty_prepare_flip_string(tty, &ptr, len); |
5028 | memset(tty->flip.flag_buf_ptr, 0, len); | 5017 | insb((ioaddr + XP_DATA), ptr, len); |
5029 | tty->flip.flag_buf_ptr += len; | ||
5030 | tty->flip.char_buf_ptr += len; | ||
5031 | tty->flip.count += len; | ||
5032 | tty_schedule_flip(tty); | 5018 | tty_schedule_flip(tty); |
5033 | portp->stats.rxtotal += len; | 5019 | portp->stats.rxtotal += len; |
5034 | } | 5020 | } |
@@ -5096,14 +5082,8 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch | |||
5096 | status = 0; | 5082 | status = 0; |
5097 | } | 5083 | } |
5098 | 5084 | ||
5099 | if (tty->flip.char_buf_ptr != (char *) NULL) { | 5085 | tty_insert_flip_char(tty, ch, status); |
5100 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 5086 | tty_schedule_flip(tty); |
5101 | *tty->flip.flag_buf_ptr++ = status; | ||
5102 | *tty->flip.char_buf_ptr++ = ch; | ||
5103 | tty->flip.count++; | ||
5104 | } | ||
5105 | tty_schedule_flip(tty); | ||
5106 | } | ||
5107 | 5087 | ||
5108 | if (status == 0) | 5088 | if (status == 0) |
5109 | portp->stats.rxtotal++; | 5089 | portp->stats.rxtotal++; |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 564f31778eb3..64bf89cb574f 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -1085,6 +1085,7 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1085 | int rx_op; | 1085 | int rx_op; |
1086 | struct tty_struct *tty; | 1086 | struct tty_struct *tty; |
1087 | int copied=0; | 1087 | int copied=0; |
1088 | unsigned char *rp; | ||
1088 | 1089 | ||
1089 | func_enter2 (); | 1090 | func_enter2 (); |
1090 | tty = port->gs.tty; | 1091 | tty = port->gs.tty; |
@@ -1095,8 +1096,8 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1095 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); | 1096 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); |
1096 | 1097 | ||
1097 | /* Don't copy more bytes than there is room for in the buffer */ | 1098 | /* Don't copy more bytes than there is room for in the buffer */ |
1098 | if (tty->flip.count + c > TTY_FLIPBUF_SIZE) | 1099 | |
1099 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | 1100 | c = tty_prepare_flip_string(tty, &rp, c); |
1100 | 1101 | ||
1101 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | 1102 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); |
1102 | 1103 | ||
@@ -1111,14 +1112,8 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1111 | sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, | 1112 | sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, |
1112 | read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op), | 1113 | read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op), |
1113 | CHAN_OFFSET(port, hi_rxbuf)); | 1114 | CHAN_OFFSET(port, hi_rxbuf)); |
1114 | memcpy_fromio (tty->flip.char_buf_ptr, | 1115 | memcpy_fromio (rp, |
1115 | port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c); | 1116 | port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c); |
1116 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, c); | ||
1117 | |||
1118 | /* Update the kernel buffer end */ | ||
1119 | tty->flip.count += c; | ||
1120 | tty->flip.char_buf_ptr += c; | ||
1121 | tty->flip.flag_buf_ptr += c; | ||
1122 | 1117 | ||
1123 | /* This one last. ( Not essential.) | 1118 | /* This one last. ( Not essential.) |
1124 | It allows the card to start putting more data into the buffer! | 1119 | It allows the card to start putting more data into the buffer! |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 789572fc002b..9f1b466c4f84 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -1467,6 +1467,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1467 | { | 1467 | { |
1468 | int Fifocount; | 1468 | int Fifocount; |
1469 | u16 status; | 1469 | u16 status; |
1470 | int work = 0; | ||
1470 | unsigned char DataByte; | 1471 | unsigned char DataByte; |
1471 | struct tty_struct *tty = info->tty; | 1472 | struct tty_struct *tty = info->tty; |
1472 | struct mgsl_icount *icount = &info->icount; | 1473 | struct mgsl_icount *icount = &info->icount; |
@@ -1487,6 +1488,8 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1487 | /* flush the receive FIFO */ | 1488 | /* flush the receive FIFO */ |
1488 | 1489 | ||
1489 | while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { | 1490 | while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { |
1491 | int flag; | ||
1492 | |||
1490 | /* read one byte from RxFIFO */ | 1493 | /* read one byte from RxFIFO */ |
1491 | outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), | 1494 | outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), |
1492 | info->io_base + CCAR ); | 1495 | info->io_base + CCAR ); |
@@ -1498,13 +1501,9 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1498 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) | 1501 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) |
1499 | usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); | 1502 | usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); |
1500 | 1503 | ||
1501 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1502 | continue; | ||
1503 | |||
1504 | *tty->flip.char_buf_ptr = DataByte; | ||
1505 | icount->rx++; | 1504 | icount->rx++; |
1506 | 1505 | ||
1507 | *tty->flip.flag_buf_ptr = 0; | 1506 | flag = 0; |
1508 | if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + | 1507 | if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + |
1509 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { | 1508 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { |
1510 | printk("rxerr=%04X\n",status); | 1509 | printk("rxerr=%04X\n",status); |
@@ -1530,41 +1529,31 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1530 | status &= info->read_status_mask; | 1529 | status &= info->read_status_mask; |
1531 | 1530 | ||
1532 | if (status & RXSTATUS_BREAK_RECEIVED) { | 1531 | if (status & RXSTATUS_BREAK_RECEIVED) { |
1533 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 1532 | flag = TTY_BREAK; |
1534 | if (info->flags & ASYNC_SAK) | 1533 | if (info->flags & ASYNC_SAK) |
1535 | do_SAK(tty); | 1534 | do_SAK(tty); |
1536 | } else if (status & RXSTATUS_PARITY_ERROR) | 1535 | } else if (status & RXSTATUS_PARITY_ERROR) |
1537 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 1536 | flag = TTY_PARITY; |
1538 | else if (status & RXSTATUS_FRAMING_ERROR) | 1537 | else if (status & RXSTATUS_FRAMING_ERROR) |
1539 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 1538 | flag = TTY_FRAME; |
1540 | if (status & RXSTATUS_OVERRUN) { | ||
1541 | /* Overrun is special, since it's | ||
1542 | * reported immediately, and doesn't | ||
1543 | * affect the current character | ||
1544 | */ | ||
1545 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
1546 | tty->flip.count++; | ||
1547 | tty->flip.flag_buf_ptr++; | ||
1548 | tty->flip.char_buf_ptr++; | ||
1549 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
1550 | } | ||
1551 | } | ||
1552 | } /* end of if (error) */ | 1539 | } /* end of if (error) */ |
1553 | 1540 | tty_insert_flip_char(tty, DataByte, flag); | |
1554 | tty->flip.flag_buf_ptr++; | 1541 | if (status & RXSTATUS_OVERRUN) { |
1555 | tty->flip.char_buf_ptr++; | 1542 | /* Overrun is special, since it's |
1556 | tty->flip.count++; | 1543 | * reported immediately, and doesn't |
1544 | * affect the current character | ||
1545 | */ | ||
1546 | work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1547 | } | ||
1557 | } | 1548 | } |
1558 | 1549 | ||
1559 | if ( debug_level >= DEBUG_LEVEL_ISR ) { | 1550 | if ( debug_level >= DEBUG_LEVEL_ISR ) { |
1560 | printk("%s(%d):mgsl_isr_receive_data flip count=%d\n", | ||
1561 | __FILE__,__LINE__,tty->flip.count); | ||
1562 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", | 1551 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", |
1563 | __FILE__,__LINE__,icount->rx,icount->brk, | 1552 | __FILE__,__LINE__,icount->rx,icount->brk, |
1564 | icount->parity,icount->frame,icount->overrun); | 1553 | icount->parity,icount->frame,icount->overrun); |
1565 | } | 1554 | } |
1566 | 1555 | ||
1567 | if ( tty->flip.count ) | 1556 | if(work) |
1568 | tty_flip_buffer_push(tty); | 1557 | tty_flip_buffer_push(tty); |
1569 | } | 1558 | } |
1570 | 1559 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 41759cd70a4f..79c81def4104 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -1749,6 +1749,9 @@ static void rx_async(struct slgt_info *info) | |||
1749 | unsigned char status; | 1749 | unsigned char status; |
1750 | struct slgt_desc *bufs = info->rbufs; | 1750 | struct slgt_desc *bufs = info->rbufs; |
1751 | int i, count; | 1751 | int i, count; |
1752 | int chars = 0; | ||
1753 | int stat; | ||
1754 | unsigned char ch; | ||
1752 | 1755 | ||
1753 | start = end = info->rbuf_current; | 1756 | start = end = info->rbuf_current; |
1754 | 1757 | ||
@@ -1760,16 +1763,15 @@ static void rx_async(struct slgt_info *info) | |||
1760 | DBGDATA(info, p, count, "rx"); | 1763 | DBGDATA(info, p, count, "rx"); |
1761 | 1764 | ||
1762 | for(i=0 ; i < count; i+=2, p+=2) { | 1765 | for(i=0 ; i < count; i+=2, p+=2) { |
1763 | if (tty) { | 1766 | if (tty && chars) { |
1764 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 1767 | tty_flip_buffer_push(tty); |
1765 | tty_flip_buffer_push(tty); | 1768 | chars = 0; |
1766 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1767 | break; | ||
1768 | *tty->flip.char_buf_ptr = *p; | ||
1769 | *tty->flip.flag_buf_ptr = 0; | ||
1770 | } | 1769 | } |
1770 | ch = *p; | ||
1771 | icount->rx++; | 1771 | icount->rx++; |
1772 | 1772 | ||
1773 | stat = 0; | ||
1774 | |||
1773 | if ((status = *(p+1) & (BIT9 + BIT8))) { | 1775 | if ((status = *(p+1) & (BIT9 + BIT8))) { |
1774 | if (status & BIT9) | 1776 | if (status & BIT9) |
1775 | icount->parity++; | 1777 | icount->parity++; |
@@ -1778,17 +1780,14 @@ static void rx_async(struct slgt_info *info) | |||
1778 | /* discard char if tty control flags say so */ | 1780 | /* discard char if tty control flags say so */ |
1779 | if (status & info->ignore_status_mask) | 1781 | if (status & info->ignore_status_mask) |
1780 | continue; | 1782 | continue; |
1781 | if (tty) { | 1783 | if (status & BIT9) |
1782 | if (status & BIT9) | 1784 | stat = TTY_PARITY; |
1783 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 1785 | else if (status & BIT8) |
1784 | else if (status & BIT8) | 1786 | stat = TTY_FRAME; |
1785 | *tty->flip.flag_buf_ptr = TTY_FRAME; | ||
1786 | } | ||
1787 | } | 1787 | } |
1788 | if (tty) { | 1788 | if (tty) { |
1789 | tty->flip.flag_buf_ptr++; | 1789 | tty_insert_flip_char(tty, ch, stat); |
1790 | tty->flip.char_buf_ptr++; | 1790 | chars++; |
1791 | tty->flip.count++; | ||
1792 | } | 1791 | } |
1793 | } | 1792 | } |
1794 | 1793 | ||
@@ -1811,7 +1810,7 @@ static void rx_async(struct slgt_info *info) | |||
1811 | break; | 1810 | break; |
1812 | } | 1811 | } |
1813 | 1812 | ||
1814 | if (tty && tty->flip.count) | 1813 | if (tty && chars) |
1815 | tty_flip_buffer_push(tty); | 1814 | tty_flip_buffer_push(tty); |
1816 | } | 1815 | } |
1817 | 1816 | ||
@@ -2029,7 +2028,7 @@ static void isr_serial(struct slgt_info *info) | |||
2029 | if (info->tty) { | 2028 | if (info->tty) { |
2030 | if (!(status & info->ignore_status_mask)) { | 2029 | if (!(status & info->ignore_status_mask)) { |
2031 | if (info->read_status_mask & MASK_BREAK) { | 2030 | if (info->read_status_mask & MASK_BREAK) { |
2032 | *info->tty->flip.flag_buf_ptr = TTY_BREAK; | 2031 | tty_insert_flip_char(info->tty, 0, TTY_BREAK); |
2033 | if (info->flags & ASYNC_SAK) | 2032 | if (info->flags & ASYNC_SAK) |
2034 | do_SAK(info->tty); | 2033 | do_SAK(info->tty); |
2035 | } | 2034 | } |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index a9467e7d3747..960adb256fbb 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -2196,7 +2196,7 @@ void isr_rxint(SLMP_INFO * info) | |||
2196 | if ( tty ) { | 2196 | if ( tty ) { |
2197 | if (!(status & info->ignore_status_mask1)) { | 2197 | if (!(status & info->ignore_status_mask1)) { |
2198 | if (info->read_status_mask1 & BRKD) { | 2198 | if (info->read_status_mask1 & BRKD) { |
2199 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 2199 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
2200 | if (info->flags & ASYNC_SAK) | 2200 | if (info->flags & ASYNC_SAK) |
2201 | do_SAK(tty); | 2201 | do_SAK(tty); |
2202 | } | 2202 | } |
@@ -2240,16 +2240,10 @@ void isr_rxrdy(SLMP_INFO * info) | |||
2240 | 2240 | ||
2241 | while((status = read_reg(info,CST0)) & BIT0) | 2241 | while((status = read_reg(info,CST0)) & BIT0) |
2242 | { | 2242 | { |
2243 | int flag = 0; | ||
2244 | int over = 0; | ||
2243 | DataByte = read_reg(info,TRB); | 2245 | DataByte = read_reg(info,TRB); |
2244 | 2246 | ||
2245 | if ( tty ) { | ||
2246 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
2247 | continue; | ||
2248 | |||
2249 | *tty->flip.char_buf_ptr = DataByte; | ||
2250 | *tty->flip.flag_buf_ptr = 0; | ||
2251 | } | ||
2252 | |||
2253 | icount->rx++; | 2247 | icount->rx++; |
2254 | 2248 | ||
2255 | if ( status & (PE + FRME + OVRN) ) { | 2249 | if ( status & (PE + FRME + OVRN) ) { |
@@ -2272,42 +2266,34 @@ void isr_rxrdy(SLMP_INFO * info) | |||
2272 | 2266 | ||
2273 | if ( tty ) { | 2267 | if ( tty ) { |
2274 | if (status & PE) | 2268 | if (status & PE) |
2275 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 2269 | flag = TTY_PARITY; |
2276 | else if (status & FRME) | 2270 | else if (status & FRME) |
2277 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 2271 | flag = TTY_FRAME; |
2278 | if (status & OVRN) { | 2272 | if (status & OVRN) { |
2279 | /* Overrun is special, since it's | 2273 | /* Overrun is special, since it's |
2280 | * reported immediately, and doesn't | 2274 | * reported immediately, and doesn't |
2281 | * affect the current character | 2275 | * affect the current character |
2282 | */ | 2276 | */ |
2283 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 2277 | over = 1; |
2284 | tty->flip.count++; | ||
2285 | tty->flip.flag_buf_ptr++; | ||
2286 | tty->flip.char_buf_ptr++; | ||
2287 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
2288 | } | ||
2289 | } | 2278 | } |
2290 | } | 2279 | } |
2291 | } /* end of if (error) */ | 2280 | } /* end of if (error) */ |
2292 | 2281 | ||
2293 | if ( tty ) { | 2282 | if ( tty ) { |
2294 | tty->flip.flag_buf_ptr++; | 2283 | tty_insert_flip_char(tty, DataByte, flag); |
2295 | tty->flip.char_buf_ptr++; | 2284 | if (over) |
2296 | tty->flip.count++; | 2285 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
2297 | } | 2286 | } |
2298 | } | 2287 | } |
2299 | 2288 | ||
2300 | if ( debug_level >= DEBUG_LEVEL_ISR ) { | 2289 | if ( debug_level >= DEBUG_LEVEL_ISR ) { |
2301 | printk("%s(%d):%s isr_rxrdy() flip count=%d\n", | ||
2302 | __FILE__,__LINE__,info->device_name, | ||
2303 | tty ? tty->flip.count : 0); | ||
2304 | printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", | 2290 | printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", |
2305 | __FILE__,__LINE__,info->device_name, | 2291 | __FILE__,__LINE__,info->device_name, |
2306 | icount->rx,icount->brk,icount->parity, | 2292 | icount->rx,icount->brk,icount->parity, |
2307 | icount->frame,icount->overrun); | 2293 | icount->frame,icount->overrun); |
2308 | } | 2294 | } |
2309 | 2295 | ||
2310 | if ( tty && tty->flip.count ) | 2296 | if ( tty ) |
2311 | tty_flip_buffer_push(tty); | 2297 | tty_flip_buffer_push(tty); |
2312 | } | 2298 | } |
2313 | 2299 | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 4b1eef51ec59..1eda82b31a61 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -166,9 +166,12 @@ static struct tty_struct *alloc_tty_struct(void) | |||
166 | return tty; | 166 | return tty; |
167 | } | 167 | } |
168 | 168 | ||
169 | static void tty_buffer_free_all(struct tty_struct *); | ||
170 | |||
169 | static inline void free_tty_struct(struct tty_struct *tty) | 171 | static inline void free_tty_struct(struct tty_struct *tty) |
170 | { | 172 | { |
171 | kfree(tty->write_buf); | 173 | kfree(tty->write_buf); |
174 | tty_buffer_free_all(tty); | ||
172 | kfree(tty); | 175 | kfree(tty); |
173 | } | 176 | } |
174 | 177 | ||
@@ -231,6 +234,201 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
231 | } | 234 | } |
232 | 235 | ||
233 | /* | 236 | /* |
237 | * Tty buffer allocation management | ||
238 | */ | ||
239 | |||
240 | static void tty_buffer_free_all(struct tty_struct *tty) | ||
241 | { | ||
242 | struct tty_buffer *thead; | ||
243 | while((thead = tty->buf.head) != NULL) { | ||
244 | tty->buf.head = thead->next; | ||
245 | kfree(thead); | ||
246 | } | ||
247 | while((thead = tty->buf.free) != NULL) { | ||
248 | tty->buf.free = thead->next; | ||
249 | kfree(thead); | ||
250 | } | ||
251 | tty->buf.tail = NULL; | ||
252 | } | ||
253 | |||
254 | static void tty_buffer_init(struct tty_struct *tty) | ||
255 | { | ||
256 | tty->buf.head = NULL; | ||
257 | tty->buf.tail = NULL; | ||
258 | tty->buf.free = NULL; | ||
259 | } | ||
260 | |||
261 | static struct tty_buffer *tty_buffer_alloc(size_t size) | ||
262 | { | ||
263 | struct tty_buffer *p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
264 | if(p == NULL) | ||
265 | return NULL; | ||
266 | p->used = 0; | ||
267 | p->size = size; | ||
268 | p->next = NULL; | ||
269 | p->char_buf_ptr = (char *)(p->data); | ||
270 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | ||
271 | /* printk("Flip create %p\n", p); */ | ||
272 | return p; | ||
273 | } | ||
274 | |||
275 | /* Must be called with the tty_read lock held. This needs to acquire strategy | ||
276 | code to decide if we should kfree or relink a given expired buffer */ | ||
277 | |||
278 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | ||
279 | { | ||
280 | /* Dumb strategy for now - should keep some stats */ | ||
281 | /* printk("Flip dispose %p\n", b); */ | ||
282 | if(b->size >= 512) | ||
283 | kfree(b); | ||
284 | else { | ||
285 | b->next = tty->buf.free; | ||
286 | tty->buf.free = b; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | ||
291 | { | ||
292 | struct tty_buffer **tbh = &tty->buf.free; | ||
293 | while((*tbh) != NULL) { | ||
294 | struct tty_buffer *t = *tbh; | ||
295 | if(t->size >= size) { | ||
296 | *tbh = t->next; | ||
297 | t->next = NULL; | ||
298 | t->used = 0; | ||
299 | /* DEBUG ONLY */ | ||
300 | memset(t->data, '*', size); | ||
301 | /* printk("Flip recycle %p\n", t); */ | ||
302 | return t; | ||
303 | } | ||
304 | tbh = &((*tbh)->next); | ||
305 | } | ||
306 | /* Round the buffer size out */ | ||
307 | size = (size + 0xFF) & ~ 0xFF; | ||
308 | return tty_buffer_alloc(size); | ||
309 | /* Should possibly check if this fails for the largest buffer we | ||
310 | have queued and recycle that ? */ | ||
311 | } | ||
312 | |||
313 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
314 | { | ||
315 | struct tty_buffer *b = tty->buf.head, *n; | ||
316 | int left = 0; | ||
317 | |||
318 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | ||
319 | remove this conditional if its worth it. This would be invisible | ||
320 | to the callers */ | ||
321 | if(b != NULL) | ||
322 | left = b->size - b->used; | ||
323 | if(left >= size) | ||
324 | return size; | ||
325 | /* This is the slow path - looking for new buffers to use */ | ||
326 | n = tty_buffer_find(tty, size); | ||
327 | if(n == NULL) | ||
328 | return left; | ||
329 | n->next = b; | ||
330 | if(b != NULL) | ||
331 | b->next = n; | ||
332 | else | ||
333 | tty->buf.head = n; | ||
334 | tty->buf.tail = n; | ||
335 | return size; | ||
336 | } | ||
337 | |||
338 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | ||
339 | |||
340 | int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size) | ||
341 | { | ||
342 | int copied = 0; | ||
343 | do { | ||
344 | int space = tty_buffer_request_room(tty, size - copied); | ||
345 | struct tty_buffer *tb = tty->buf.tail; | ||
346 | /* If there is no space then tb may be NULL */ | ||
347 | if(unlikely(space == 0)) | ||
348 | break; | ||
349 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
350 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
351 | tb->used += space; | ||
352 | copied += space; | ||
353 | chars += space; | ||
354 | /* printk("Flip insert %d.\n", space); */ | ||
355 | } | ||
356 | /* There is a small chance that we need to split the data over | ||
357 | several buffers. If this is the case we must loop */ | ||
358 | while (unlikely(size > copied)); | ||
359 | return copied; | ||
360 | } | ||
361 | |||
362 | EXPORT_SYMBOL_GPL(tty_insert_flip_string); | ||
363 | |||
364 | int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size) | ||
365 | { | ||
366 | int copied = 0; | ||
367 | do { | ||
368 | int space = tty_buffer_request_room(tty, size - copied); | ||
369 | struct tty_buffer *tb = tty->buf.tail; | ||
370 | /* If there is no space then tb may be NULL */ | ||
371 | if(unlikely(space == 0)) | ||
372 | break; | ||
373 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
374 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | ||
375 | tb->used += space; | ||
376 | copied += space; | ||
377 | chars += space; | ||
378 | flags += space; | ||
379 | } | ||
380 | /* There is a small chance that we need to split the data over | ||
381 | several buffers. If this is the case we must loop */ | ||
382 | while (unlikely(size > copied)); | ||
383 | return copied; | ||
384 | } | ||
385 | |||
386 | EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); | ||
387 | |||
388 | |||
389 | /* | ||
390 | * Prepare a block of space in the buffer for data. Returns the length | ||
391 | * available and buffer pointer to the space which is now allocated and | ||
392 | * accounted for as ready for normal characters. This is used for drivers | ||
393 | * that need their own block copy routines into the buffer. There is no | ||
394 | * guarantee the buffer is a DMA target! | ||
395 | */ | ||
396 | |||
397 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) | ||
398 | { | ||
399 | int space = tty_buffer_request_room(tty, size); | ||
400 | struct tty_buffer *tb = tty->buf.tail; | ||
401 | *chars = tb->char_buf_ptr + tb->used; | ||
402 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
403 | tb->used += space; | ||
404 | return space; | ||
405 | } | ||
406 | |||
407 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | ||
408 | |||
409 | /* | ||
410 | * Prepare a block of space in the buffer for data. Returns the length | ||
411 | * available and buffer pointer to the space which is now allocated and | ||
412 | * accounted for as ready for characters. This is used for drivers | ||
413 | * that need their own block copy routines into the buffer. There is no | ||
414 | * guarantee the buffer is a DMA target! | ||
415 | */ | ||
416 | |||
417 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) | ||
418 | { | ||
419 | int space = tty_buffer_request_room(tty, size); | ||
420 | struct tty_buffer *tb = tty->buf.tail; | ||
421 | *chars = tb->char_buf_ptr + tb->used; | ||
422 | *flags = tb->flag_buf_ptr + tb->used; | ||
423 | tb->used += space; | ||
424 | return space; | ||
425 | } | ||
426 | |||
427 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | ||
428 | |||
429 | |||
430 | |||
431 | /* | ||
234 | * This is probably overkill for real world processors but | 432 | * This is probably overkill for real world processors but |
235 | * they are not on hot paths so a little discipline won't do | 433 | * they are not on hot paths so a little discipline won't do |
236 | * any harm. | 434 | * any harm. |
@@ -492,6 +690,17 @@ restart: | |||
492 | if (ld == NULL) | 690 | if (ld == NULL) |
493 | return -EINVAL; | 691 | return -EINVAL; |
494 | 692 | ||
693 | /* | ||
694 | * No more input please, we are switching. The new ldisc | ||
695 | * will update this value in the ldisc open function | ||
696 | */ | ||
697 | |||
698 | tty->receive_room = 0; | ||
699 | |||
700 | /* | ||
701 | * Problem: What do we do if this blocks ? | ||
702 | */ | ||
703 | |||
495 | tty_wait_until_sent(tty, 0); | 704 | tty_wait_until_sent(tty, 0); |
496 | 705 | ||
497 | if (tty->ldisc.num == ldisc) { | 706 | if (tty->ldisc.num == ldisc) { |
@@ -560,9 +769,9 @@ restart: | |||
560 | * we say so later on. | 769 | * we say so later on. |
561 | */ | 770 | */ |
562 | 771 | ||
563 | work = cancel_delayed_work(&tty->flip.work); | 772 | work = cancel_delayed_work(&tty->buf.work); |
564 | /* | 773 | /* |
565 | * Wait for ->hangup_work and ->flip.work handlers to terminate | 774 | * Wait for ->hangup_work and ->buf.work handlers to terminate |
566 | */ | 775 | */ |
567 | 776 | ||
568 | flush_scheduled_work(); | 777 | flush_scheduled_work(); |
@@ -616,7 +825,7 @@ restart: | |||
616 | /* Restart it in case no characters kick it off. Safe if | 825 | /* Restart it in case no characters kick it off. Safe if |
617 | already running */ | 826 | already running */ |
618 | if (work) | 827 | if (work) |
619 | schedule_delayed_work(&tty->flip.work, 1); | 828 | schedule_delayed_work(&tty->buf.work, 1); |
620 | return retval; | 829 | return retval; |
621 | } | 830 | } |
622 | 831 | ||
@@ -1721,10 +1930,10 @@ static void release_dev(struct file * filp) | |||
1721 | */ | 1930 | */ |
1722 | clear_bit(TTY_LDISC, &tty->flags); | 1931 | clear_bit(TTY_LDISC, &tty->flags); |
1723 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 1932 | clear_bit(TTY_DONT_FLIP, &tty->flags); |
1724 | cancel_delayed_work(&tty->flip.work); | 1933 | cancel_delayed_work(&tty->buf.work); |
1725 | 1934 | ||
1726 | /* | 1935 | /* |
1727 | * Wait for ->hangup_work and ->flip.work handlers to terminate | 1936 | * Wait for ->hangup_work and ->buf.work handlers to terminate |
1728 | */ | 1937 | */ |
1729 | 1938 | ||
1730 | flush_scheduled_work(); | 1939 | flush_scheduled_work(); |
@@ -2518,17 +2727,15 @@ EXPORT_SYMBOL(do_SAK); | |||
2518 | 2727 | ||
2519 | /* | 2728 | /* |
2520 | * This routine is called out of the software interrupt to flush data | 2729 | * This routine is called out of the software interrupt to flush data |
2521 | * from the flip buffer to the line discipline. | 2730 | * from the buffer chain to the line discipline. |
2522 | */ | 2731 | */ |
2523 | 2732 | ||
2524 | static void flush_to_ldisc(void *private_) | 2733 | static void flush_to_ldisc(void *private_) |
2525 | { | 2734 | { |
2526 | struct tty_struct *tty = (struct tty_struct *) private_; | 2735 | struct tty_struct *tty = (struct tty_struct *) private_; |
2527 | unsigned char *cp; | ||
2528 | char *fp; | ||
2529 | int count; | ||
2530 | unsigned long flags; | 2736 | unsigned long flags; |
2531 | struct tty_ldisc *disc; | 2737 | struct tty_ldisc *disc; |
2738 | struct tty_buffer *tbuf; | ||
2532 | 2739 | ||
2533 | disc = tty_ldisc_ref(tty); | 2740 | disc = tty_ldisc_ref(tty); |
2534 | if (disc == NULL) /* !TTY_LDISC */ | 2741 | if (disc == NULL) /* !TTY_LDISC */ |
@@ -2538,28 +2745,22 @@ static void flush_to_ldisc(void *private_) | |||
2538 | /* | 2745 | /* |
2539 | * Do it after the next timer tick: | 2746 | * Do it after the next timer tick: |
2540 | */ | 2747 | */ |
2541 | schedule_delayed_work(&tty->flip.work, 1); | 2748 | schedule_delayed_work(&tty->buf.work, 1); |
2542 | goto out; | 2749 | goto out; |
2543 | } | 2750 | } |
2544 | spin_lock_irqsave(&tty->read_lock, flags); | 2751 | spin_lock_irqsave(&tty->read_lock, flags); |
2545 | if (tty->flip.buf_num) { | 2752 | while((tbuf = tty->buf.head) != NULL) { |
2546 | cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; | 2753 | tty->buf.head = tbuf->next; |
2547 | fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; | 2754 | spin_unlock_irqrestore(&tty->read_lock, flags); |
2548 | tty->flip.buf_num = 0; | 2755 | /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ |
2549 | tty->flip.char_buf_ptr = tty->flip.char_buf; | 2756 | disc->receive_buf(tty, tbuf->char_buf_ptr, |
2550 | tty->flip.flag_buf_ptr = tty->flip.flag_buf; | 2757 | tbuf->flag_buf_ptr, |
2551 | } else { | 2758 | tbuf->used); |
2552 | cp = tty->flip.char_buf; | 2759 | spin_lock_irqsave(&tty->read_lock, flags); |
2553 | fp = tty->flip.flag_buf; | 2760 | tty_buffer_free(tty, tbuf); |
2554 | tty->flip.buf_num = 1; | 2761 | } |
2555 | tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE; | 2762 | tty->buf.tail = NULL; |
2556 | tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; | ||
2557 | } | ||
2558 | count = tty->flip.count; | ||
2559 | tty->flip.count = 0; | ||
2560 | spin_unlock_irqrestore(&tty->read_lock, flags); | 2763 | spin_unlock_irqrestore(&tty->read_lock, flags); |
2561 | |||
2562 | disc->receive_buf(tty, cp, fp, count); | ||
2563 | out: | 2764 | out: |
2564 | tty_ldisc_deref(disc); | 2765 | tty_ldisc_deref(disc); |
2565 | } | 2766 | } |
@@ -2654,11 +2855,12 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2654 | if (tty->low_latency) | 2855 | if (tty->low_latency) |
2655 | flush_to_ldisc((void *) tty); | 2856 | flush_to_ldisc((void *) tty); |
2656 | else | 2857 | else |
2657 | schedule_delayed_work(&tty->flip.work, 1); | 2858 | schedule_delayed_work(&tty->buf.work, 1); |
2658 | } | 2859 | } |
2659 | 2860 | ||
2660 | EXPORT_SYMBOL(tty_flip_buffer_push); | 2861 | EXPORT_SYMBOL(tty_flip_buffer_push); |
2661 | 2862 | ||
2863 | |||
2662 | /* | 2864 | /* |
2663 | * This subroutine initializes a tty structure. | 2865 | * This subroutine initializes a tty structure. |
2664 | */ | 2866 | */ |
@@ -2669,10 +2871,10 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
2669 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); | 2871 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); |
2670 | tty->pgrp = -1; | 2872 | tty->pgrp = -1; |
2671 | tty->overrun_time = jiffies; | 2873 | tty->overrun_time = jiffies; |
2672 | tty->flip.char_buf_ptr = tty->flip.char_buf; | 2874 | tty->buf.head = tty->buf.tail = NULL; |
2673 | tty->flip.flag_buf_ptr = tty->flip.flag_buf; | 2875 | tty_buffer_init(tty); |
2674 | INIT_WORK(&tty->flip.work, flush_to_ldisc, tty); | 2876 | INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); |
2675 | init_MUTEX(&tty->flip.pty_sem); | 2877 | init_MUTEX(&tty->buf.pty_sem); |
2676 | init_MUTEX(&tty->termios_sem); | 2878 | init_MUTEX(&tty->termios_sem); |
2677 | init_waitqueue_head(&tty->write_wait); | 2879 | init_waitqueue_head(&tty->write_wait); |
2678 | init_waitqueue_head(&tty->read_wait); | 2880 | init_waitqueue_head(&tty->read_wait); |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 4d75c261f98a..cb82ebf4cb07 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
@@ -993,11 +993,10 @@ static void vioHandleData(struct HvLpEvent *event) | |||
993 | * Don't attempt to copy more data into the buffer than we | 993 | * Don't attempt to copy more data into the buffer than we |
994 | * have room for because it would fail without indication. | 994 | * have room for because it would fail without indication. |
995 | */ | 995 | */ |
996 | if ((tty->flip.count + 1) > TTY_FLIPBUF_SIZE) { | 996 | if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) { |
997 | printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); | 997 | printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); |
998 | break; | 998 | break; |
999 | } | 999 | } |
1000 | tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL); | ||
1001 | } | 1000 | } |
1002 | 1001 | ||
1003 | /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */ | 1002 | /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */ |
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index 33e71e23b212..d9325281e482 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -434,13 +434,7 @@ static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp) | |||
434 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | 434 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); |
435 | return IRQ_HANDLED; | 435 | return IRQ_HANDLED; |
436 | } | 436 | } |
437 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 437 | tty_insert_flip_char(tty, ch, 0); |
438 | *tty->flip.char_buf_ptr = ch; | ||
439 | *tty->flip.flag_buf_ptr = 0; | ||
440 | tty->flip.flag_buf_ptr++; | ||
441 | tty->flip.char_buf_ptr++; | ||
442 | tty->flip.count++; | ||
443 | } | ||
444 | 438 | ||
445 | /* Check if another character is already ready; in that case, the | 439 | /* Check if another character is already ready; in that case, the |
446 | * spcond_int() function must be used, because this character may have an | 440 | * spcond_int() function must be used, because this character may have an |
@@ -487,13 +481,7 @@ static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp) | |||
487 | else | 481 | else |
488 | err = 0; | 482 | err = 0; |
489 | 483 | ||
490 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 484 | tty_insert_flip_char(tty, ch, err); |
491 | *tty->flip.char_buf_ptr = ch; | ||
492 | *tty->flip.flag_buf_ptr = err; | ||
493 | tty->flip.flag_buf_ptr++; | ||
494 | tty->flip.char_buf_ptr++; | ||
495 | tty->flip.count++; | ||
496 | } | ||
497 | 485 | ||
498 | /* ++TeSche: *All* errors have to be cleared manually, | 486 | /* ++TeSche: *All* errors have to be cleared manually, |
499 | * else the condition persists for the next chars | 487 | * else the condition persists for the next chars |
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 1bd88fca0542..54a680cc704d 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -96,6 +96,7 @@ static int serport_ldisc_open(struct tty_struct *tty) | |||
96 | init_waitqueue_head(&serport->wait); | 96 | init_waitqueue_head(&serport->wait); |
97 | 97 | ||
98 | tty->disc_data = serport; | 98 | tty->disc_data = serport; |
99 | tty->receive_room = 256; | ||
99 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 100 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
100 | 101 | ||
101 | return 0; | 102 | return 0; |
@@ -140,17 +141,6 @@ out: | |||
140 | } | 141 | } |
141 | 142 | ||
142 | /* | 143 | /* |
143 | * serport_ldisc_room() reports how much room we do have for receiving data. | ||
144 | * Although we in fact have infinite room, we need to specify some value | ||
145 | * here, and 256 seems to be reasonable. | ||
146 | */ | ||
147 | |||
148 | static int serport_ldisc_room(struct tty_struct *tty) | ||
149 | { | ||
150 | return 256; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * serport_ldisc_read() just waits indefinitely if everything goes well. | 144 | * serport_ldisc_read() just waits indefinitely if everything goes well. |
155 | * However, when the serio driver closes the serio port, it finishes, | 145 | * However, when the serio driver closes the serio port, it finishes, |
156 | * returning 0 characters. | 146 | * returning 0 characters. |
@@ -237,7 +227,6 @@ static struct tty_ldisc serport_ldisc = { | |||
237 | .read = serport_ldisc_read, | 227 | .read = serport_ldisc_read, |
238 | .ioctl = serport_ldisc_ioctl, | 228 | .ioctl = serport_ldisc_ioctl, |
239 | .receive_buf = serport_ldisc_receive, | 229 | .receive_buf = serport_ldisc_receive, |
240 | .receive_room = serport_ldisc_room, | ||
241 | .write_wakeup = serport_ldisc_write_wakeup | 230 | .write_wakeup = serport_ldisc_write_wakeup |
242 | }; | 231 | }; |
243 | 232 | ||
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 11ae0fddea04..623adbb0d13a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -463,8 +463,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) | |||
463 | #endif | 463 | #endif |
464 | goto bad; | 464 | goto bad; |
465 | } | 465 | } |
466 | if (ld->receive_room && | 466 | if (mp->tty->receive_room < datalen) { |
467 | ld->receive_room(mp->tty) < datalen) { | ||
468 | #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) | 467 | #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) |
469 | printk(KERN_DEBUG "capi: no room in tty\n"); | 468 | printk(KERN_DEBUG "capi: no room in tty\n"); |
470 | #endif | 469 | #endif |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 4643df097bfe..22759c01746a 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -857,6 +857,118 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que | |||
857 | return count; | 857 | return count; |
858 | } | 858 | } |
859 | 859 | ||
860 | /* | ||
861 | * isdn_readbchan_tty() tries to get data from the read-queue. | ||
862 | * It MUST be called with interrupts off. | ||
863 | * | ||
864 | * Be aware that this is not an atomic operation when sleep != 0, even though | ||
865 | * interrupts are turned off! Well, like that we are currently only called | ||
866 | * on behalf of a read system call on raw device files (which are documented | ||
867 | * to be dangerous and for for debugging purpose only). The inode semaphore | ||
868 | * takes care that this is not called for the same minor device number while | ||
869 | * we are sleeping, but access is not serialized against simultaneous read() | ||
870 | * from the corresponding ttyI device. Can other ugly events, like changes | ||
871 | * of the mapping (di,ch)<->minor, happen during the sleep? --he | ||
872 | */ | ||
873 | int | ||
874 | isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | ||
875 | { | ||
876 | int count; | ||
877 | int count_pull; | ||
878 | int count_put; | ||
879 | int dflag; | ||
880 | struct sk_buff *skb; | ||
881 | char last = 0; | ||
882 | int len; | ||
883 | |||
884 | if (!dev->drv[di]) | ||
885 | return 0; | ||
886 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | ||
887 | return 0; | ||
888 | |||
889 | len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]); | ||
890 | if(len == 0) | ||
891 | return len; | ||
892 | |||
893 | count = 0; | ||
894 | while (len) { | ||
895 | if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel]))) | ||
896 | break; | ||
897 | #ifdef CONFIG_ISDN_AUDIO | ||
898 | if (ISDN_AUDIO_SKB_LOCK(skb)) | ||
899 | break; | ||
900 | ISDN_AUDIO_SKB_LOCK(skb) = 1; | ||
901 | if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) { | ||
902 | char *p = skb->data; | ||
903 | unsigned long DLEmask = (1 << channel); | ||
904 | |||
905 | dflag = 0; | ||
906 | count_pull = count_put = 0; | ||
907 | while ((count_pull < skb->len) && (len > 0)) { | ||
908 | len--; | ||
909 | if (dev->drv[di]->DLEflag & DLEmask) { | ||
910 | last = DLE; | ||
911 | dev->drv[di]->DLEflag &= ~DLEmask; | ||
912 | } else { | ||
913 | last = *p; | ||
914 | if (last == DLE) { | ||
915 | dev->drv[di]->DLEflag |= DLEmask; | ||
916 | (ISDN_AUDIO_SKB_DLECOUNT(skb))--; | ||
917 | } | ||
918 | p++; | ||
919 | count_pull++; | ||
920 | } | ||
921 | count_put++; | ||
922 | } | ||
923 | if (count_pull >= skb->len) | ||
924 | dflag = 1; | ||
925 | } else { | ||
926 | #endif | ||
927 | /* No DLE's in buff, so simply copy it */ | ||
928 | dflag = 1; | ||
929 | if ((count_pull = skb->len) > len) { | ||
930 | count_pull = len; | ||
931 | dflag = 0; | ||
932 | } | ||
933 | count_put = count_pull; | ||
934 | if(count_put > 1) | ||
935 | tty_insert_flip_string(tty, skb->data, count_put - 1); | ||
936 | last = skb->data[count_put] - 1; | ||
937 | len -= count_put; | ||
938 | #ifdef CONFIG_ISDN_AUDIO | ||
939 | } | ||
940 | #endif | ||
941 | count += count_put; | ||
942 | if (dflag) { | ||
943 | /* We got all the data in this buff. | ||
944 | * Now we can dequeue it. | ||
945 | */ | ||
946 | if(cisco_hack) | ||
947 | tty_insert_flip_char(tty, last, 0xFF); | ||
948 | else | ||
949 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
950 | #ifdef CONFIG_ISDN_AUDIO | ||
951 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | ||
952 | #endif | ||
953 | skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); | ||
954 | dev_kfree_skb(skb); | ||
955 | } else { | ||
956 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
957 | /* Not yet emptied this buff, so it | ||
958 | * must stay in the queue, for further calls | ||
959 | * but we pull off the data we got until now. | ||
960 | */ | ||
961 | skb_pull(skb, count_pull); | ||
962 | #ifdef CONFIG_ISDN_AUDIO | ||
963 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | ||
964 | #endif | ||
965 | } | ||
966 | dev->drv[di]->rcvcount[channel] -= count_put; | ||
967 | } | ||
968 | return count; | ||
969 | } | ||
970 | |||
971 | |||
860 | static __inline int | 972 | static __inline int |
861 | isdn_minor2drv(int minor) | 973 | isdn_minor2drv(int minor) |
862 | { | 974 | { |
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index e27e9c3a81ed..082735dbb412 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h | |||
@@ -37,6 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); | |||
37 | extern void isdn_unexclusive_channel(int di, int ch); | 37 | extern void isdn_unexclusive_channel(int di, int ch); |
38 | extern int isdn_getnum(char **); | 38 | extern int isdn_getnum(char **); |
39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); | 39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); |
40 | extern int isdn_readbchan_tty(int, int, struct tty_struct *, int); | ||
40 | extern int isdn_get_free_channel(int, int, int, int, int, char *); | 41 | extern int isdn_get_free_channel(int, int, int, int, int, char *); |
41 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); | 42 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); |
42 | extern int register_isdn(isdn_if * i); | 43 | extern int register_isdn(isdn_if * i); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 8c404b4e2482..f190a99604f0 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -64,37 +64,42 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) | |||
64 | int c; | 64 | int c; |
65 | int len; | 65 | int len; |
66 | struct tty_struct *tty; | 66 | struct tty_struct *tty; |
67 | char last; | ||
67 | 68 | ||
68 | if (info->online) { | 69 | if (info->online) { |
69 | if ((tty = info->tty)) { | 70 | if ((tty = info->tty)) { |
70 | if (info->mcr & UART_MCR_RTS) { | 71 | if (info->mcr & UART_MCR_RTS) { |
71 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
72 | len = skb->len | 72 | len = skb->len |
73 | #ifdef CONFIG_ISDN_AUDIO | 73 | #ifdef CONFIG_ISDN_AUDIO |
74 | + ISDN_AUDIO_SKB_DLECOUNT(skb) | 74 | + ISDN_AUDIO_SKB_DLECOUNT(skb) |
75 | #endif | 75 | #endif |
76 | ; | 76 | ; |
77 | |||
78 | c = tty_buffer_request_room(tty, len); | ||
77 | if (c >= len) { | 79 | if (c >= len) { |
78 | #ifdef CONFIG_ISDN_AUDIO | 80 | #ifdef CONFIG_ISDN_AUDIO |
79 | if (ISDN_AUDIO_SKB_DLECOUNT(skb)) | 81 | if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { |
80 | while (skb->len--) { | 82 | int l = skb->len; |
83 | unsigned char *dp = skb->data; | ||
84 | while (--l) { | ||
81 | if (*skb->data == DLE) | 85 | if (*skb->data == DLE) |
82 | tty_insert_flip_char(tty, DLE, 0); | 86 | tty_insert_flip_char(tty, DLE, 0); |
83 | tty_insert_flip_char(tty, *skb->data++, 0); | 87 | tty_insert_flip_char(tty, *dp++, 0); |
88 | } | ||
89 | last = *dp; | ||
84 | } else { | 90 | } else { |
85 | #endif | 91 | #endif |
86 | memcpy(tty->flip.char_buf_ptr, | 92 | if(len > 1) |
87 | skb->data, len); | 93 | tty_insert_flip_string(tty, skb->data, len - 1); |
88 | tty->flip.count += len; | 94 | last = skb->data[len - 1]; |
89 | tty->flip.char_buf_ptr += len; | ||
90 | memset(tty->flip.flag_buf_ptr, 0, len); | ||
91 | tty->flip.flag_buf_ptr += len; | ||
92 | #ifdef CONFIG_ISDN_AUDIO | 95 | #ifdef CONFIG_ISDN_AUDIO |
93 | } | 96 | } |
94 | #endif | 97 | #endif |
95 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) | 98 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) |
96 | tty->flip.flag_buf_ptr[len - 1] = 0xff; | 99 | tty_insert_flip_char(tty, last, 0xFF); |
97 | schedule_delayed_work(&tty->flip.work, 1); | 100 | else |
101 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
102 | tty_flip_buffer_push(tty); | ||
98 | kfree_skb(skb); | 103 | kfree_skb(skb); |
99 | return 1; | 104 | return 1; |
100 | } | 105 | } |
@@ -114,7 +119,6 @@ isdn_tty_readmodem(void) | |||
114 | int resched = 0; | 119 | int resched = 0; |
115 | int midx; | 120 | int midx; |
116 | int i; | 121 | int i; |
117 | int c; | ||
118 | int r; | 122 | int r; |
119 | struct tty_struct *tty; | 123 | struct tty_struct *tty; |
120 | modem_info *info; | 124 | modem_info *info; |
@@ -131,20 +135,13 @@ isdn_tty_readmodem(void) | |||
131 | #endif | 135 | #endif |
132 | if ((tty = info->tty)) { | 136 | if ((tty = info->tty)) { |
133 | if (info->mcr & UART_MCR_RTS) { | 137 | if (info->mcr & UART_MCR_RTS) { |
134 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | 138 | /* CISCO AsyncPPP Hack */ |
135 | if (c > 0) { | 139 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) |
136 | r = isdn_readbchan(info->isdn_driver, info->isdn_channel, | 140 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); |
137 | tty->flip.char_buf_ptr, | 141 | else |
138 | tty->flip.flag_buf_ptr, c, NULL); | 142 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); |
139 | /* CISCO AsyncPPP Hack */ | 143 | if (r) |
140 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) | 144 | tty_flip_buffer_push(tty); |
141 | memset(tty->flip.flag_buf_ptr, 0, r); | ||
142 | tty->flip.count += r; | ||
143 | tty->flip.flag_buf_ptr += r; | ||
144 | tty->flip.char_buf_ptr += r; | ||
145 | if (r) | ||
146 | schedule_delayed_work(&tty->flip.work, 1); | ||
147 | } | ||
148 | } else | 145 | } else |
149 | r = 1; | 146 | r = 1; |
150 | } else | 147 | } else |
@@ -249,7 +246,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) | |||
249 | } | 246 | } |
250 | #endif | 247 | #endif |
251 | #endif | 248 | #endif |
252 | /* Try to deliver directly via tty-flip-buf if queue is empty */ | 249 | /* Try to deliver directly via tty-buf if queue is empty */ |
253 | spin_lock_irqsave(&info->readlock, flags); | 250 | spin_lock_irqsave(&info->readlock, flags); |
254 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | 251 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) |
255 | if (isdn_tty_try_read(info, skb)) { | 252 | if (isdn_tty_try_read(info, skb)) { |
@@ -534,7 +531,7 @@ isdn_tty_senddown(modem_info * info) | |||
534 | /* The next routine is called once from within timer-interrupt | 531 | /* The next routine is called once from within timer-interrupt |
535 | * triggered within isdn_tty_modem_ncarrier(). It calls | 532 | * triggered within isdn_tty_modem_ncarrier(). It calls |
536 | * isdn_tty_modem_result() to stuff a "NO CARRIER" Message | 533 | * isdn_tty_modem_result() to stuff a "NO CARRIER" Message |
537 | * into the tty's flip-buffer. | 534 | * into the tty's buffer. |
538 | */ | 535 | */ |
539 | static void | 536 | static void |
540 | isdn_tty_modem_do_ncarrier(unsigned long data) | 537 | isdn_tty_modem_do_ncarrier(unsigned long data) |
@@ -2347,6 +2344,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2347 | u_long flags; | 2344 | u_long flags; |
2348 | struct sk_buff *skb = NULL; | 2345 | struct sk_buff *skb = NULL; |
2349 | char *sp = NULL; | 2346 | char *sp = NULL; |
2347 | int l = strlen(msg); | ||
2350 | 2348 | ||
2351 | if (!msg) { | 2349 | if (!msg) { |
2352 | printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); | 2350 | printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); |
@@ -2359,16 +2357,16 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2359 | return; | 2357 | return; |
2360 | } | 2358 | } |
2361 | 2359 | ||
2362 | /* use queue instead of direct flip, if online and */ | 2360 | /* use queue instead of direct, if online and */ |
2363 | /* data is in queue or flip buffer is full */ | 2361 | /* data is in queue or buffer is full */ |
2364 | if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || | 2362 | if ((info->online && tty_buffer_request_room(tty, l) < l) || |
2365 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { | 2363 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { |
2366 | skb = alloc_skb(strlen(msg), GFP_ATOMIC); | 2364 | skb = alloc_skb(l, GFP_ATOMIC); |
2367 | if (!skb) { | 2365 | if (!skb) { |
2368 | spin_unlock_irqrestore(&info->readlock, flags); | 2366 | spin_unlock_irqrestore(&info->readlock, flags); |
2369 | return; | 2367 | return; |
2370 | } | 2368 | } |
2371 | sp = skb_put(skb, strlen(msg)); | 2369 | sp = skb_put(skb, l); |
2372 | #ifdef CONFIG_ISDN_AUDIO | 2370 | #ifdef CONFIG_ISDN_AUDIO |
2373 | ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; | 2371 | ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; |
2374 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | 2372 | ISDN_AUDIO_SKB_LOCK(skb) = 0; |
@@ -2392,9 +2390,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2392 | if (skb) { | 2390 | if (skb) { |
2393 | *sp++ = c; | 2391 | *sp++ = c; |
2394 | } else { | 2392 | } else { |
2395 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 2393 | if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) |
2396 | break; | 2394 | break; |
2397 | tty_insert_flip_char(tty, c, 0); | ||
2398 | } | 2395 | } |
2399 | } | 2396 | } |
2400 | if (skb) { | 2397 | if (skb) { |
@@ -2402,12 +2399,12 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2402 | dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; | 2399 | dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; |
2403 | spin_unlock_irqrestore(&info->readlock, flags); | 2400 | spin_unlock_irqrestore(&info->readlock, flags); |
2404 | /* Schedule dequeuing */ | 2401 | /* Schedule dequeuing */ |
2405 | if ((dev->modempoll) && (info->rcvsched)) | 2402 | if (dev->modempoll && info->rcvsched) |
2406 | isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); | 2403 | isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); |
2407 | 2404 | ||
2408 | } else { | 2405 | } else { |
2409 | spin_unlock_irqrestore(&info->readlock, flags); | 2406 | spin_unlock_irqrestore(&info->readlock, flags); |
2410 | schedule_delayed_work(&tty->flip.work, 1); | 2407 | tty_flip_buffer_push(tty); |
2411 | } | 2408 | } |
2412 | } | 2409 | } |
2413 | 2410 | ||
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 90999867a32c..102c1f0b90da 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -456,11 +456,6 @@ out: | |||
456 | 456 | ||
457 | /* ----------------------------------------------------------------------- */ | 457 | /* ----------------------------------------------------------------------- */ |
458 | 458 | ||
459 | static int sixpack_receive_room(struct tty_struct *tty) | ||
460 | { | ||
461 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
462 | } | ||
463 | |||
464 | /* | 459 | /* |
465 | * Handle the 'receiver data ready' interrupt. | 460 | * Handle the 'receiver data ready' interrupt. |
466 | * This function is called by the 'tty_io' module in the kernel when | 461 | * This function is called by the 'tty_io' module in the kernel when |
@@ -671,6 +666,7 @@ static int sixpack_open(struct tty_struct *tty) | |||
671 | 666 | ||
672 | /* Done. We have linked the TTY line to a channel. */ | 667 | /* Done. We have linked the TTY line to a channel. */ |
673 | tty->disc_data = sp; | 668 | tty->disc_data = sp; |
669 | tty->receive_room = 65536; | ||
674 | 670 | ||
675 | /* Now we're ready to register. */ | 671 | /* Now we're ready to register. */ |
676 | if (register_netdev(dev)) | 672 | if (register_netdev(dev)) |
@@ -802,7 +798,6 @@ static struct tty_ldisc sp_ldisc = { | |||
802 | .close = sixpack_close, | 798 | .close = sixpack_close, |
803 | .ioctl = sixpack_ioctl, | 799 | .ioctl = sixpack_ioctl, |
804 | .receive_buf = sixpack_receive_buf, | 800 | .receive_buf = sixpack_receive_buf, |
805 | .receive_room = sixpack_receive_room, | ||
806 | .write_wakeup = sixpack_write_wakeup, | 801 | .write_wakeup = sixpack_write_wakeup, |
807 | }; | 802 | }; |
808 | 803 | ||
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index f4424cf886c5..dc5e9d59deed 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -753,6 +753,7 @@ static int mkiss_open(struct tty_struct *tty) | |||
753 | 753 | ||
754 | ax->tty = tty; | 754 | ax->tty = tty; |
755 | tty->disc_data = ax; | 755 | tty->disc_data = ax; |
756 | tty->receive_room = 65535; | ||
756 | 757 | ||
757 | if (tty->driver->flush_buffer) | 758 | if (tty->driver->flush_buffer) |
758 | tty->driver->flush_buffer(tty); | 759 | tty->driver->flush_buffer(tty); |
@@ -940,11 +941,6 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
940 | tty->driver->unthrottle(tty); | 941 | tty->driver->unthrottle(tty); |
941 | } | 942 | } |
942 | 943 | ||
943 | static int mkiss_receive_room(struct tty_struct *tty) | ||
944 | { | ||
945 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
946 | } | ||
947 | |||
948 | /* | 944 | /* |
949 | * Called by the driver when there's room for more data. If we have | 945 | * Called by the driver when there's room for more data. If we have |
950 | * more packets to send, we send them here. | 946 | * more packets to send, we send them here. |
@@ -983,7 +979,6 @@ static struct tty_ldisc ax_ldisc = { | |||
983 | .close = mkiss_close, | 979 | .close = mkiss_close, |
984 | .ioctl = mkiss_ioctl, | 980 | .ioctl = mkiss_ioctl, |
985 | .receive_buf = mkiss_receive_buf, | 981 | .receive_buf = mkiss_receive_buf, |
986 | .receive_room = mkiss_receive_room, | ||
987 | .write_wakeup = mkiss_write_wakeup | 982 | .write_wakeup = mkiss_write_wakeup |
988 | }; | 983 | }; |
989 | 984 | ||
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index b8d112348ba4..101750bf210f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -289,22 +289,6 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
289 | } | 289 | } |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * Function irtty_receive_room (tty) | ||
293 | * | ||
294 | * Used by the TTY to find out how much data we can receive at a time | ||
295 | * | ||
296 | */ | ||
297 | static int irtty_receive_room(struct tty_struct *tty) | ||
298 | { | ||
299 | struct sirtty_cb *priv = tty->disc_data; | ||
300 | |||
301 | IRDA_ASSERT(priv != NULL, return 0;); | ||
302 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return 0;); | ||
303 | |||
304 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Function irtty_write_wakeup (tty) | 292 | * Function irtty_write_wakeup (tty) |
309 | * | 293 | * |
310 | * Called by the driver when there's room for more data. If we have | 294 | * Called by the driver when there's room for more data. If we have |
@@ -534,6 +518,7 @@ static int irtty_open(struct tty_struct *tty) | |||
534 | 518 | ||
535 | dev->priv = priv; | 519 | dev->priv = priv; |
536 | tty->disc_data = priv; | 520 | tty->disc_data = priv; |
521 | tty->receive_room = 65536; | ||
537 | 522 | ||
538 | up(&irtty_sem); | 523 | up(&irtty_sem); |
539 | 524 | ||
@@ -605,7 +590,6 @@ static struct tty_ldisc irda_ldisc = { | |||
605 | .ioctl = irtty_ioctl, | 590 | .ioctl = irtty_ioctl, |
606 | .poll = NULL, | 591 | .poll = NULL, |
607 | .receive_buf = irtty_receive_buf, | 592 | .receive_buf = irtty_receive_buf, |
608 | .receive_room = irtty_receive_room, | ||
609 | .write_wakeup = irtty_write_wakeup, | 593 | .write_wakeup = irtty_write_wakeup, |
610 | .owner = THIS_MODULE, | 594 | .owner = THIS_MODULE, |
611 | }; | 595 | }; |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 400f652282d7..aa6540b39466 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -189,7 +189,7 @@ ppp_asynctty_open(struct tty_struct *tty) | |||
189 | goto out_free; | 189 | goto out_free; |
190 | 190 | ||
191 | tty->disc_data = ap; | 191 | tty->disc_data = ap; |
192 | 192 | tty->receive_room = 65536; | |
193 | return 0; | 193 | return 0; |
194 | 194 | ||
195 | out_free: | 195 | out_free: |
@@ -343,12 +343,6 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
343 | return 0; | 343 | return 0; |
344 | } | 344 | } |
345 | 345 | ||
346 | static int | ||
347 | ppp_asynctty_room(struct tty_struct *tty) | ||
348 | { | ||
349 | return 65535; | ||
350 | } | ||
351 | |||
352 | /* | 346 | /* |
353 | * This can now be called from hard interrupt level as well | 347 | * This can now be called from hard interrupt level as well |
354 | * as soft interrupt level or mainline. | 348 | * as soft interrupt level or mainline. |
@@ -398,7 +392,6 @@ static struct tty_ldisc ppp_ldisc = { | |||
398 | .write = ppp_asynctty_write, | 392 | .write = ppp_asynctty_write, |
399 | .ioctl = ppp_asynctty_ioctl, | 393 | .ioctl = ppp_asynctty_ioctl, |
400 | .poll = ppp_asynctty_poll, | 394 | .poll = ppp_asynctty_poll, |
401 | .receive_room = ppp_asynctty_room, | ||
402 | .receive_buf = ppp_asynctty_receive, | 395 | .receive_buf = ppp_asynctty_receive, |
403 | .write_wakeup = ppp_asynctty_wakeup, | 396 | .write_wakeup = ppp_asynctty_wakeup, |
404 | }; | 397 | }; |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 4d51c0c8023d..33cb8254e79d 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -237,7 +237,7 @@ ppp_sync_open(struct tty_struct *tty) | |||
237 | goto out_free; | 237 | goto out_free; |
238 | 238 | ||
239 | tty->disc_data = ap; | 239 | tty->disc_data = ap; |
240 | 240 | tty->receive_room = 65536; | |
241 | return 0; | 241 | return 0; |
242 | 242 | ||
243 | out_free: | 243 | out_free: |
@@ -384,12 +384,6 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
387 | static int | ||
388 | ppp_sync_room(struct tty_struct *tty) | ||
389 | { | ||
390 | return 65535; | ||
391 | } | ||
392 | |||
393 | /* | 387 | /* |
394 | * This can now be called from hard interrupt level as well | 388 | * This can now be called from hard interrupt level as well |
395 | * as soft interrupt level or mainline. | 389 | * as soft interrupt level or mainline. |
@@ -439,7 +433,6 @@ static struct tty_ldisc ppp_sync_ldisc = { | |||
439 | .write = ppp_sync_write, | 433 | .write = ppp_sync_write, |
440 | .ioctl = ppp_synctty_ioctl, | 434 | .ioctl = ppp_synctty_ioctl, |
441 | .poll = ppp_sync_poll, | 435 | .poll = ppp_sync_poll, |
442 | .receive_room = ppp_sync_room, | ||
443 | .receive_buf = ppp_sync_receive, | 436 | .receive_buf = ppp_sync_receive, |
444 | .write_wakeup = ppp_sync_wakeup, | 437 | .write_wakeup = ppp_sync_wakeup, |
445 | }; | 438 | }; |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 404ea4297e32..b2e18d28850d 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -651,11 +651,6 @@ static void sl_setup(struct net_device *dev) | |||
651 | ******************************************/ | 651 | ******************************************/ |
652 | 652 | ||
653 | 653 | ||
654 | static int slip_receive_room(struct tty_struct *tty) | ||
655 | { | ||
656 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
657 | } | ||
658 | |||
659 | /* | 654 | /* |
660 | * Handle the 'receiver data ready' interrupt. | 655 | * Handle the 'receiver data ready' interrupt. |
661 | * This function is called by the 'tty_io' module in the kernel when | 656 | * This function is called by the 'tty_io' module in the kernel when |
@@ -869,10 +864,6 @@ static int slip_open(struct tty_struct *tty) | |||
869 | sl->line = tty_devnum(tty); | 864 | sl->line = tty_devnum(tty); |
870 | sl->pid = current->pid; | 865 | sl->pid = current->pid; |
871 | 866 | ||
872 | /* FIXME: already done before we were called - seems this can go */ | ||
873 | if (tty->driver->flush_buffer) | ||
874 | tty->driver->flush_buffer(tty); | ||
875 | |||
876 | if (!test_bit(SLF_INUSE, &sl->flags)) { | 867 | if (!test_bit(SLF_INUSE, &sl->flags)) { |
877 | /* Perform the low-level SLIP initialization. */ | 868 | /* Perform the low-level SLIP initialization. */ |
878 | if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) | 869 | if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) |
@@ -897,6 +888,7 @@ static int slip_open(struct tty_struct *tty) | |||
897 | 888 | ||
898 | /* Done. We have linked the TTY line to a channel. */ | 889 | /* Done. We have linked the TTY line to a channel. */ |
899 | rtnl_unlock(); | 890 | rtnl_unlock(); |
891 | tty->receive_room = 65536; /* We don't flow control */ | ||
900 | return sl->dev->base_addr; | 892 | return sl->dev->base_addr; |
901 | 893 | ||
902 | err_free_bufs: | 894 | err_free_bufs: |
@@ -1329,7 +1321,6 @@ static struct tty_ldisc sl_ldisc = { | |||
1329 | .close = slip_close, | 1321 | .close = slip_close, |
1330 | .ioctl = slip_ioctl, | 1322 | .ioctl = slip_ioctl, |
1331 | .receive_buf = slip_receive_buf, | 1323 | .receive_buf = slip_receive_buf, |
1332 | .receive_room = slip_receive_room, | ||
1333 | .write_wakeup = slip_write_wakeup, | 1324 | .write_wakeup = slip_write_wakeup, |
1334 | }; | 1325 | }; |
1335 | 1326 | ||
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 52f26b9c69d2..931cbdf6d791 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c | |||
@@ -689,7 +689,7 @@ static void cpc_tty_rx_work(void * data) | |||
689 | } | 689 | } |
690 | } | 690 | } |
691 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; | 691 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; |
692 | kfree(buf); | 692 | kfree((void *)buf); |
693 | buf = cpc_tty->buf_rx.first; | 693 | buf = cpc_tty->buf_rx.first; |
694 | flg_rx = 1; | 694 | flg_rx = 1; |
695 | } | 695 | } |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index bdf672c48182..9c3ccc669143 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -515,11 +515,6 @@ static int x25_asy_close(struct net_device *dev) | |||
515 | return 0; | 515 | return 0; |
516 | } | 516 | } |
517 | 517 | ||
518 | static int x25_asy_receive_room(struct tty_struct *tty) | ||
519 | { | ||
520 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
521 | } | ||
522 | |||
523 | /* | 518 | /* |
524 | * Handle the 'receiver data ready' interrupt. | 519 | * Handle the 'receiver data ready' interrupt. |
525 | * This function is called by the 'tty_io' module in the kernel when | 520 | * This function is called by the 'tty_io' module in the kernel when |
@@ -573,6 +568,7 @@ static int x25_asy_open_tty(struct tty_struct *tty) | |||
573 | 568 | ||
574 | sl->tty = tty; | 569 | sl->tty = tty; |
575 | tty->disc_data = sl; | 570 | tty->disc_data = sl; |
571 | tty->receive_room = 65536; | ||
576 | if (tty->driver->flush_buffer) { | 572 | if (tty->driver->flush_buffer) { |
577 | tty->driver->flush_buffer(tty); | 573 | tty->driver->flush_buffer(tty); |
578 | } | 574 | } |
@@ -779,7 +775,6 @@ static struct tty_ldisc x25_ldisc = { | |||
779 | .close = x25_asy_close_tty, | 775 | .close = x25_asy_close_tty, |
780 | .ioctl = x25_asy_ioctl, | 776 | .ioctl = x25_asy_ioctl, |
781 | .receive_buf = x25_asy_receive_buf, | 777 | .receive_buf = x25_asy_receive_buf, |
782 | .receive_room = x25_asy_receive_room, | ||
783 | .write_wakeup = x25_asy_write_wakeup, | 778 | .write_wakeup = x25_asy_write_wakeup, |
784 | }; | 779 | }; |
785 | 780 | ||
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index d25264ba0c0e..18baacfc5a2c 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -1675,11 +1675,6 @@ static int strip_rebuild_header(struct sk_buff *skb) | |||
1675 | /************************************************************************/ | 1675 | /************************************************************************/ |
1676 | /* Receiving routines */ | 1676 | /* Receiving routines */ |
1677 | 1677 | ||
1678 | static int strip_receive_room(struct tty_struct *tty) | ||
1679 | { | ||
1680 | return 0x10000; /* We can handle an infinite amount of data. :-) */ | ||
1681 | } | ||
1682 | |||
1683 | /* | 1678 | /* |
1684 | * This function parses the response to the ATS300? command, | 1679 | * This function parses the response to the ATS300? command, |
1685 | * extracting the radio version and serial number. | 1680 | * extracting the radio version and serial number. |
@@ -2424,7 +2419,7 @@ static struct net_device_stats *strip_get_stats(struct net_device *dev) | |||
2424 | /* | 2419 | /* |
2425 | * Here's the order things happen: | 2420 | * Here's the order things happen: |
2426 | * When the user runs "slattach -p strip ..." | 2421 | * When the user runs "slattach -p strip ..." |
2427 | * 1. The TTY module calls strip_open | 2422 | * 1. The TTY module calls strip_open;; |
2428 | * 2. strip_open calls strip_alloc | 2423 | * 2. strip_open calls strip_alloc |
2429 | * 3. strip_alloc calls register_netdev | 2424 | * 3. strip_alloc calls register_netdev |
2430 | * 4. register_netdev calls strip_dev_init | 2425 | * 4. register_netdev calls strip_dev_init |
@@ -2652,6 +2647,8 @@ static int strip_open(struct tty_struct *tty) | |||
2652 | 2647 | ||
2653 | strip_info->tty = tty; | 2648 | strip_info->tty = tty; |
2654 | tty->disc_data = strip_info; | 2649 | tty->disc_data = strip_info; |
2650 | tty->receive_room = 65536; | ||
2651 | |||
2655 | if (tty->driver->flush_buffer) | 2652 | if (tty->driver->flush_buffer) |
2656 | tty->driver->flush_buffer(tty); | 2653 | tty->driver->flush_buffer(tty); |
2657 | 2654 | ||
@@ -2762,7 +2759,6 @@ static struct tty_ldisc strip_ldisc = { | |||
2762 | .close = strip_close, | 2759 | .close = strip_close, |
2763 | .ioctl = strip_ioctl, | 2760 | .ioctl = strip_ioctl, |
2764 | .receive_buf = strip_receive_buf, | 2761 | .receive_buf = strip_receive_buf, |
2765 | .receive_room = strip_receive_room, | ||
2766 | .write_wakeup = strip_write_some_more, | 2762 | .write_wakeup = strip_write_some_more, |
2767 | }; | 2763 | }; |
2768 | 2764 | ||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 75419cf9d353..1f060914cfa4 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/kdev_t.h> | 17 | #include <linux/kdev_t.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/tty_flip.h> | ||
19 | #include <linux/vt_kern.h> | 20 | #include <linux/vt_kern.h> |
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/console.h> | 22 | #include <linux/console.h> |
@@ -432,8 +433,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
432 | if (count > slen) | 433 | if (count > slen) |
433 | count = slen; | 434 | count = slen; |
434 | } else | 435 | } else |
435 | if (count >= TTY_FLIPBUF_SIZE - tty->flip.count) | ||
436 | count = TTY_FLIPBUF_SIZE - tty->flip.count - 1; | ||
437 | EBCASC(raw->inbuf, count); | 436 | EBCASC(raw->inbuf, count); |
438 | cchar = ctrlchar_handle(raw->inbuf, count, tty); | 437 | cchar = ctrlchar_handle(raw->inbuf, count, tty); |
439 | switch (cchar & CTRLCHAR_MASK) { | 438 | switch (cchar & CTRLCHAR_MASK) { |
@@ -441,28 +440,20 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
441 | break; | 440 | break; |
442 | 441 | ||
443 | case CTRLCHAR_CTRL: | 442 | case CTRLCHAR_CTRL: |
444 | tty->flip.count++; | 443 | tty_insert_flip_char(tty, cchar, TTY_NORMAL); |
445 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
446 | *tty->flip.char_buf_ptr++ = cchar; | ||
447 | tty_flip_buffer_push(raw->tty); | 444 | tty_flip_buffer_push(raw->tty); |
448 | break; | 445 | break; |
449 | 446 | ||
450 | case CTRLCHAR_NONE: | 447 | case CTRLCHAR_NONE: |
451 | memcpy(tty->flip.char_buf_ptr, | ||
452 | raw->inbuf, count); | ||
453 | if (count < 2 || | 448 | if (count < 2 || |
454 | (strncmp(raw->inbuf+count-2, "^n", 2) && | 449 | (strncmp(raw->inbuf+count-2, "\252n", 2) && |
455 | strncmp(raw->inbuf+count-2, "\252n", 2)) ) { | 450 | strncmp(raw->inbuf+count-2, "^n", 2)) ) { |
456 | /* don't add the auto \n */ | 451 | /* add the auto \n */ |
457 | tty->flip.char_buf_ptr[count] = '\n'; | 452 | raw->inbuf[count] = '\n'; |
458 | memset(tty->flip.flag_buf_ptr, | ||
459 | TTY_NORMAL, count + 1); | ||
460 | count++; | 453 | count++; |
461 | } else | 454 | } else |
462 | count-=2; | 455 | count -= 2; |
463 | tty->flip.char_buf_ptr += count; | 456 | tty_insert_flip_string(tty, raw->inbuf, count); |
464 | tty->flip.flag_buf_ptr += count; | ||
465 | tty->flip.count += count; | ||
466 | tty_flip_buffer_push(raw->tty); | 457 | tty_flip_buffer_push(raw->tty); |
467 | break; | 458 | break; |
468 | } | 459 | } |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index a20d7c89341d..6cbf067f1a8f 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kmod.h> | 13 | #include <linux/kmod.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/tty_driver.h> | 15 | #include <linux/tty_driver.h> |
16 | #include <linux/tty_flip.h> | ||
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
17 | #include <linux/wait.h> | 18 | #include <linux/wait.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -496,25 +497,19 @@ sclp_tty_input(unsigned char* buf, unsigned int count) | |||
496 | case CTRLCHAR_SYSRQ: | 497 | case CTRLCHAR_SYSRQ: |
497 | break; | 498 | break; |
498 | case CTRLCHAR_CTRL: | 499 | case CTRLCHAR_CTRL: |
499 | sclp_tty->flip.count++; | 500 | tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL); |
500 | *sclp_tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
501 | *sclp_tty->flip.char_buf_ptr++ = cchar; | ||
502 | tty_flip_buffer_push(sclp_tty); | 501 | tty_flip_buffer_push(sclp_tty); |
503 | break; | 502 | break; |
504 | case CTRLCHAR_NONE: | 503 | case CTRLCHAR_NONE: |
505 | /* send (normal) input to line discipline */ | 504 | /* send (normal) input to line discipline */ |
506 | memcpy(sclp_tty->flip.char_buf_ptr, buf, count); | ||
507 | if (count < 2 || | 505 | if (count < 2 || |
508 | (strncmp ((const char *) buf + count - 2, "^n", 2) && | 506 | (strncmp((const char *) buf + count - 2, "^n", 2) && |
509 | strncmp ((const char *) buf + count - 2, "\0252n", 2))) { | 507 | strncmp((const char *) buf + count - 2, "\252n", 2))) { |
510 | sclp_tty->flip.char_buf_ptr[count] = '\n'; | 508 | /* add the auto \n */ |
511 | count++; | 509 | tty_insert_flip_string(sclp_tty, buf, count); |
510 | tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL); | ||
512 | } else | 511 | } else |
513 | count -= 2; | 512 | tty_insert_flip_string(sclp_tty, buf, count - 2); |
514 | memset(sclp_tty->flip.flag_buf_ptr, TTY_NORMAL, count); | ||
515 | sclp_tty->flip.char_buf_ptr += count; | ||
516 | sclp_tty->flip.flag_buf_ptr += count; | ||
517 | sclp_tty->flip.count += count; | ||
518 | tty_flip_buffer_push(sclp_tty); | 513 | tty_flip_buffer_push(sclp_tty); |
519 | break; | 514 | break; |
520 | } | 515 | } |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 06bd85824d7b..9e02625c82cf 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
18 | #include <linux/tty_driver.h> | 18 | #include <linux/tty_driver.h> |
19 | #include <linux/tty_flip.h> | ||
19 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
21 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
@@ -482,16 +483,7 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | |||
482 | /* Send input to line discipline */ | 483 | /* Send input to line discipline */ |
483 | buffer++; | 484 | buffer++; |
484 | count--; | 485 | count--; |
485 | /* Prevent buffer overrun by discarding input. Note that | 486 | tty_insert_flip_string(sclp_vt220_tty, buffer, count); |
486 | * because buffer_push works asynchronously, we cannot wait | ||
487 | * for the buffer to be emptied. */ | ||
488 | if (count + sclp_vt220_tty->flip.count > TTY_FLIPBUF_SIZE) | ||
489 | count = TTY_FLIPBUF_SIZE - sclp_vt220_tty->flip.count; | ||
490 | memcpy(sclp_vt220_tty->flip.char_buf_ptr, buffer, count); | ||
491 | memset(sclp_vt220_tty->flip.flag_buf_ptr, TTY_NORMAL, count); | ||
492 | sclp_vt220_tty->flip.char_buf_ptr += count; | ||
493 | sclp_vt220_tty->flip.flag_buf_ptr += count; | ||
494 | sclp_vt220_tty->flip.count += count; | ||
495 | tty_flip_buffer_push(sclp_vt220_tty); | 487 | tty_flip_buffer_push(sclp_vt220_tty); |
496 | break; | 488 | break; |
497 | } | 489 | } |
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c index 968f2c113efe..93d1725eb79b 100644 --- a/drivers/s390/net/ctctty.c +++ b/drivers/s390/net/ctctty.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
28 | #include <linux/tty_flip.h> | ||
28 | #include <linux/serial_reg.h> | 29 | #include <linux/serial_reg.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
@@ -101,25 +102,17 @@ static spinlock_t ctc_tty_lock; | |||
101 | static int | 102 | static int |
102 | ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) | 103 | ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) |
103 | { | 104 | { |
104 | int c; | ||
105 | int len; | 105 | int len; |
106 | struct tty_struct *tty; | 106 | struct tty_struct *tty; |
107 | 107 | ||
108 | DBF_TEXT(trace, 5, __FUNCTION__); | 108 | DBF_TEXT(trace, 5, __FUNCTION__); |
109 | if ((tty = info->tty)) { | 109 | if ((tty = info->tty)) { |
110 | if (info->mcr & UART_MCR_RTS) { | 110 | if (info->mcr & UART_MCR_RTS) { |
111 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
112 | len = skb->len; | 111 | len = skb->len; |
113 | if (c >= len) { | 112 | tty_insert_flip_string(tty, skb->data, len); |
114 | memcpy(tty->flip.char_buf_ptr, skb->data, len); | 113 | tty_flip_buffer_push(tty); |
115 | memset(tty->flip.flag_buf_ptr, 0, len); | 114 | kfree_skb(skb); |
116 | tty->flip.count += len; | 115 | return 1; |
117 | tty->flip.char_buf_ptr += len; | ||
118 | tty->flip.flag_buf_ptr += len; | ||
119 | tty_flip_buffer_push(tty); | ||
120 | kfree_skb(skb); | ||
121 | return 1; | ||
122 | } | ||
123 | } | 116 | } |
124 | } | 117 | } |
125 | return 0; | 118 | return 0; |
@@ -138,19 +131,12 @@ ctc_tty_readmodem(ctc_tty_info *info) | |||
138 | DBF_TEXT(trace, 5, __FUNCTION__); | 131 | DBF_TEXT(trace, 5, __FUNCTION__); |
139 | if ((tty = info->tty)) { | 132 | if ((tty = info->tty)) { |
140 | if (info->mcr & UART_MCR_RTS) { | 133 | if (info->mcr & UART_MCR_RTS) { |
141 | int c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
142 | struct sk_buff *skb; | 134 | struct sk_buff *skb; |
143 | 135 | ||
144 | if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) { | 136 | if ((skb = skb_dequeue(&info->rx_queue))) { |
145 | int len = skb->len; | 137 | int len = skb->len; |
146 | if (len > c) | 138 | tty_insert_flip_string(tty, skb->data, len); |
147 | len = c; | ||
148 | memcpy(tty->flip.char_buf_ptr, skb->data, len); | ||
149 | skb_pull(skb, len); | 139 | skb_pull(skb, len); |
150 | memset(tty->flip.flag_buf_ptr, 0, len); | ||
151 | tty->flip.count += len; | ||
152 | tty->flip.char_buf_ptr += len; | ||
153 | tty->flip.flag_buf_ptr += len; | ||
154 | tty_flip_buffer_push(tty); | 140 | tty_flip_buffer_push(tty); |
155 | if (skb->len > 0) | 141 | if (skb->len > 0) |
156 | skb_queue_head(&info->rx_queue, skb); | 142 | skb_queue_head(&info->rx_queue, skb); |
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; |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 248279e44c99..b9fd39fd1b5b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -335,14 +335,9 @@ next_buffer: | |||
335 | 335 | ||
336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); | 336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); |
337 | 337 | ||
338 | for (i = 0; i < buf->size && !acm->throttle; i++) { | 338 | tty_buffer_request_room(tty, buf->size); |
339 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 339 | if (!acm->throttle) |
340 | we drop them. */ | 340 | tty_insert_flip_string(tty, buf->base, buf->size); |
341 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
342 | tty_flip_buffer_push(tty); | ||
343 | } | ||
344 | tty_insert_flip_char(tty, buf->base[i], 0); | ||
345 | } | ||
346 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(tty); |
347 | 342 | ||
348 | spin_lock(&acm->throttle_lock); | 343 | spin_lock(&acm->throttle_lock); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 65e084a2c87e..2e6926b33455 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -1271,6 +1271,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1271 | unsigned int len; | 1271 | unsigned int len; |
1272 | struct gs_port *port; | 1272 | struct gs_port *port; |
1273 | int ret; | 1273 | int ret; |
1274 | struct tty_struct *tty; | ||
1274 | 1275 | ||
1275 | /* TEMPORARY -- only port 0 is supported right now */ | 1276 | /* TEMPORARY -- only port 0 is supported right now */ |
1276 | port = dev->dev_port[0]; | 1277 | port = dev->dev_port[0]; |
@@ -1290,7 +1291,10 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1290 | goto exit; | 1291 | goto exit; |
1291 | } | 1292 | } |
1292 | 1293 | ||
1293 | if (port->port_tty == NULL) { | 1294 | |
1295 | tty = port->port_tty; | ||
1296 | |||
1297 | if (tty == NULL) { | ||
1294 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", | 1298 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", |
1295 | port->port_num); | 1299 | port->port_num); |
1296 | ret = -EIO; | 1300 | ret = -EIO; |
@@ -1304,20 +1308,13 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1304 | goto exit; | 1308 | goto exit; |
1305 | } | 1309 | } |
1306 | 1310 | ||
1307 | len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count); | 1311 | len = tty_buffer_request_room(tty, size); |
1308 | if (len < size) | 1312 | if (len > 0) { |
1309 | size = len; | 1313 | tty_insert_flip_string(tty, packet, len); |
1310 | |||
1311 | if (size > 0) { | ||
1312 | memcpy(port->port_tty->flip.char_buf_ptr, packet, size); | ||
1313 | port->port_tty->flip.char_buf_ptr += size; | ||
1314 | port->port_tty->flip.count += size; | ||
1315 | tty_flip_buffer_push(port->port_tty); | 1314 | tty_flip_buffer_push(port->port_tty); |
1316 | wake_up_interruptible(&port->port_tty->read_wait); | 1315 | wake_up_interruptible(&port->port_tty->read_wait); |
1317 | } | 1316 | } |
1318 | |||
1319 | ret = 0; | 1317 | ret = 0; |
1320 | |||
1321 | exit: | 1318 | exit: |
1322 | spin_unlock(&port->port_lock); | 1319 | spin_unlock(&port->port_lock); |
1323 | return ret; | 1320 | return ret; |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 14f55fd26a64..be5dc80836c3 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -84,7 +84,7 @@ config USB_SERIAL_BELKIN | |||
84 | 84 | ||
85 | config USB_SERIAL_WHITEHEAT | 85 | config USB_SERIAL_WHITEHEAT |
86 | tristate "USB ConnectTech WhiteHEAT Serial Driver" | 86 | tristate "USB ConnectTech WhiteHEAT Serial Driver" |
87 | depends on USB_SERIAL && BROKEN_ON_SMP | 87 | depends on USB_SERIAL |
88 | help | 88 | help |
89 | Say Y here if you want to use a ConnectTech WhiteHEAT 4 port | 89 | Say Y here if you want to use a ConnectTech WhiteHEAT 4 port |
90 | USB to serial converter device. | 90 | USB to serial converter device. |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 6d18d4eaba35..2357b1d102d7 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -364,7 +364,6 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
364 | struct tty_struct *tty; | 364 | struct tty_struct *tty; |
365 | unsigned char *data = urb->transfer_buffer; | 365 | unsigned char *data = urb->transfer_buffer; |
366 | short todo; | 366 | short todo; |
367 | int i; | ||
368 | int result; | 367 | int result; |
369 | 368 | ||
370 | dbg("%s - port %d", __FUNCTION__, port->number); | 369 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -381,14 +380,8 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
381 | return; | 380 | return; |
382 | } | 381 | } |
383 | if (urb->actual_length) { | 382 | if (urb->actual_length) { |
384 | for (i = 0; i < urb->actual_length ; ++i) { | 383 | tty_buffer_request_room(tty, urb->actual_length); |
385 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 384 | tty_insert_flip_string(tty, data, urb->actual_length); |
386 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
387 | tty_flip_buffer_push(tty); | ||
388 | } | ||
389 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
390 | tty_insert_flip_char(tty, data[i], 0); | ||
391 | } | ||
392 | tty_flip_buffer_push(tty); | 385 | tty_flip_buffer_push(tty); |
393 | } | 386 | } |
394 | 387 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 4e9637eb6137..68067fe117a4 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1263,12 +1263,10 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
1263 | 1263 | ||
1264 | /* process read if there is data other than line status */ | 1264 | /* process read if there is data other than line status */ |
1265 | if (tty && (bytes > i)) { | 1265 | if (tty && (bytes > i)) { |
1266 | bytes = tty_buffer_request_room(tty, bytes); | ||
1266 | for (; i < bytes ; ++i) { | 1267 | for (; i < bytes ; ++i) { |
1267 | dbg("pushing byte number %d - %d - %c", i, data[i], | 1268 | dbg("pushing byte number %d - %d - %c", i, data[i], |
1268 | data[i]); | 1269 | data[i]); |
1269 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
1270 | tty_flip_buffer_push(tty); | ||
1271 | } | ||
1272 | tty_insert_flip_char(tty, data[i], tty_flag); | 1270 | tty_insert_flip_char(tty, data[i], tty_flag); |
1273 | } | 1271 | } |
1274 | tty_flip_buffer_push(port->tty); | 1272 | tty_flip_buffer_push(port->tty); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 8fc414bd5b24..b3f776a90c93 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -946,13 +946,10 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); | |||
946 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 946 | spin_lock_irqsave( &priv->dp_port_lock, flags ); |
947 | 947 | ||
948 | /* send any buffered chars from throttle time on to tty subsystem */ | 948 | /* send any buffered chars from throttle time on to tty subsystem */ |
949 | len = min(priv->dp_in_buf_len, TTY_FLIPBUF_SIZE - tty->flip.count ); | 949 | |
950 | len = tty_buffer_request_room(tty, priv->dp_in_buf_len); | ||
950 | if( len > 0 ) { | 951 | if( len > 0 ) { |
951 | memcpy( tty->flip.char_buf_ptr, priv->dp_in_buf, len ); | 952 | tty_insert_flip_string_flags(tty, priv->dp_in_buf, priv->dp_in_flag_buf, len); |
952 | memcpy( tty->flip.flag_buf_ptr, priv->dp_in_flag_buf, len ); | ||
953 | tty->flip.char_buf_ptr += len; | ||
954 | tty->flip.flag_buf_ptr += len; | ||
955 | tty->flip.count += len; | ||
956 | tty_flip_buffer_push( tty ); | 953 | tty_flip_buffer_push( tty ); |
957 | } | 954 | } |
958 | 955 | ||
@@ -1827,6 +1824,7 @@ static int digi_read_inb_callback( struct urb *urb ) | |||
1827 | int status = ((unsigned char *)urb->transfer_buffer)[2]; | 1824 | int status = ((unsigned char *)urb->transfer_buffer)[2]; |
1828 | unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3; | 1825 | unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3; |
1829 | int flag,throttled; | 1826 | int flag,throttled; |
1827 | int i; | ||
1830 | 1828 | ||
1831 | /* do not process callbacks on closed ports */ | 1829 | /* do not process callbacks on closed ports */ |
1832 | /* but do continue the read chain */ | 1830 | /* but do continue the read chain */ |
@@ -1885,20 +1883,18 @@ static int digi_read_inb_callback( struct urb *urb ) | |||
1885 | } | 1883 | } |
1886 | 1884 | ||
1887 | } else { | 1885 | } else { |
1888 | 1886 | len = tty_buffer_request_room(tty, len); | |
1889 | len = min( len, TTY_FLIPBUF_SIZE - tty->flip.count ); | ||
1890 | |||
1891 | if( len > 0 ) { | 1887 | if( len > 0 ) { |
1892 | memcpy( tty->flip.char_buf_ptr, data, len ); | 1888 | /* Hot path */ |
1893 | memset( tty->flip.flag_buf_ptr, flag, len ); | 1889 | if(flag == TTY_NORMAL) |
1894 | tty->flip.char_buf_ptr += len; | 1890 | tty_insert_flip_string(tty, data, len); |
1895 | tty->flip.flag_buf_ptr += len; | 1891 | else { |
1896 | tty->flip.count += len; | 1892 | for(i = 0; i < len; i++) |
1893 | tty_insert_flip_char(tty, data[i], flag); | ||
1894 | } | ||
1897 | tty_flip_buffer_push( tty ); | 1895 | tty_flip_buffer_push( tty ); |
1898 | } | 1896 | } |
1899 | |||
1900 | } | 1897 | } |
1901 | |||
1902 | } | 1898 | } |
1903 | 1899 | ||
1904 | spin_unlock( &priv->dp_port_lock ); | 1900 | spin_unlock( &priv->dp_port_lock ); |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 79a766e9ca23..63f7c78a1152 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -344,7 +344,6 @@ static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
344 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 344 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
345 | struct tty_struct *tty; | 345 | struct tty_struct *tty; |
346 | unsigned char *data = urb->transfer_buffer; | 346 | unsigned char *data = urb->transfer_buffer; |
347 | int i; | ||
348 | int result; | 347 | int result; |
349 | 348 | ||
350 | dbg("%s - port %d", __FUNCTION__, port->number); | 349 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -359,19 +358,8 @@ static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
359 | tty = port->tty; | 358 | tty = port->tty; |
360 | 359 | ||
361 | if (urb->actual_length) { | 360 | if (urb->actual_length) { |
362 | for (i = 0; i < urb->actual_length ; ++i) { | 361 | tty_buffer_request_room(tty, urb->actual_length); |
363 | /* gb - 2000/11/13 | 362 | tty_insert_flip_string(tty, data, urb->actual_length); |
364 | * If we insert too many characters we'll overflow the buffer. | ||
365 | * This means we'll lose bytes - Decidedly bad. | ||
366 | */ | ||
367 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
368 | tty_flip_buffer_push(tty); | ||
369 | } | ||
370 | tty_insert_flip_char(tty, data[i], 0); | ||
371 | } | ||
372 | /* gb - 2000/11/13 | ||
373 | * Goes straight through instead of scheduling - if tty->low_latency is set. | ||
374 | */ | ||
375 | tty_flip_buffer_push(tty); | 363 | tty_flip_buffer_push(tty); |
376 | bytes_in += urb->actual_length; | 364 | bytes_in += urb->actual_length; |
377 | } | 365 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index eb863b3f2d79..10bc1bf23b35 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1610,24 +1610,11 @@ static void ftdi_process_read (void *param) | |||
1610 | length = 0; | 1610 | length = 0; |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | /* have to make sure we don't overflow the buffer | ||
1614 | with tty_insert_flip_char's */ | ||
1615 | if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { | ||
1616 | tty_flip_buffer_push(tty); | ||
1617 | need_flip = 0; | ||
1618 | |||
1619 | if (tty->flip.count != 0) { | ||
1620 | /* flip didn't work, this happens when ftdi_process_read() is | ||
1621 | * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ | ||
1622 | dbg("%s - flip buffer push failed", __FUNCTION__); | ||
1623 | break; | ||
1624 | } | ||
1625 | } | ||
1626 | if (priv->rx_flags & THROTTLED) { | 1613 | if (priv->rx_flags & THROTTLED) { |
1627 | dbg("%s - throttled", __FUNCTION__); | 1614 | dbg("%s - throttled", __FUNCTION__); |
1628 | break; | 1615 | break; |
1629 | } | 1616 | } |
1630 | if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { | 1617 | if (tty_buffer_request_room(tty, length) < length) { |
1631 | /* break out & wait for throttling/unthrottling to happen */ | 1618 | /* break out & wait for throttling/unthrottling to happen */ |
1632 | dbg("%s - receive room low", __FUNCTION__); | 1619 | dbg("%s - receive room low", __FUNCTION__); |
1633 | break; | 1620 | break; |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 452efce72714..d6f55e9dccae 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -275,23 +275,14 @@ static void send_to_tty(struct usb_serial_port *port, | |||
275 | char *data, unsigned int actual_length) | 275 | char *data, unsigned int actual_length) |
276 | { | 276 | { |
277 | struct tty_struct *tty = port->tty; | 277 | struct tty_struct *tty = port->tty; |
278 | int i; | ||
279 | 278 | ||
280 | if (tty && actual_length) { | 279 | if (tty && actual_length) { |
281 | 280 | ||
282 | usb_serial_debug_data(debug, &port->dev, | 281 | usb_serial_debug_data(debug, &port->dev, |
283 | __FUNCTION__, actual_length, data); | 282 | __FUNCTION__, actual_length, data); |
284 | 283 | ||
285 | for (i = 0; i < actual_length ; ++i) { | 284 | tty_buffer_request_room(tty, actual_length); |
286 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 285 | tty_insert_flip_string(tty, data, actual_length); |
287 | we drop them. */ | ||
288 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
289 | tty_flip_buffer_push(tty); | ||
290 | } | ||
291 | /* this doesn't actually push the data through unless | ||
292 | tty->low_latency is set */ | ||
293 | tty_insert_flip_char(tty, data[i], 0); | ||
294 | } | ||
295 | tty_flip_buffer_push(tty); | 286 | tty_flip_buffer_push(tty); |
296 | } | 287 | } |
297 | } | 288 | } |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 4ddac620fc0c..476cda107f4f 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -254,7 +254,6 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg | |||
254 | struct usb_serial *serial = port->serial; | 254 | struct usb_serial *serial = port->serial; |
255 | struct tty_struct *tty; | 255 | struct tty_struct *tty; |
256 | unsigned char *data = urb->transfer_buffer; | 256 | unsigned char *data = urb->transfer_buffer; |
257 | int i; | ||
258 | int result; | 257 | int result; |
259 | 258 | ||
260 | dbg("%s - port %d", __FUNCTION__, port->number); | 259 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -268,14 +267,8 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg | |||
268 | 267 | ||
269 | tty = port->tty; | 268 | tty = port->tty; |
270 | if (tty && urb->actual_length) { | 269 | if (tty && urb->actual_length) { |
271 | for (i = 0; i < urb->actual_length ; ++i) { | 270 | tty_buffer_request_room(tty, urb->actual_length); |
272 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 271 | tty_insert_flip_string(tty, data, urb->actual_length); |
273 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
274 | tty_flip_buffer_push(tty); | ||
275 | } | ||
276 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
277 | tty_insert_flip_char(tty, data[i], 0); | ||
278 | } | ||
279 | tty_flip_buffer_push(tty); | 272 | tty_flip_buffer_push(tty); |
280 | } | 273 | } |
281 | 274 | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index faedbeb6ba49..3f29e6b0fd19 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -1965,20 +1965,14 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c | |||
1965 | int cnt; | 1965 | int cnt; |
1966 | 1966 | ||
1967 | do { | 1967 | do { |
1968 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1968 | cnt = tty_buffer_request_room(tty, length); |
1969 | tty_flip_buffer_push(tty); | 1969 | if (cnt < length) { |
1970 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1970 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
1971 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1971 | __FUNCTION__, length - cnt); |
1972 | __FUNCTION__, length); | 1972 | if(cnt == 0) |
1973 | return; | 1973 | break; |
1974 | } | ||
1975 | } | 1974 | } |
1976 | cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); | 1975 | tty_insert_flip_string(tty, data, cnt); |
1977 | memcpy(tty->flip.char_buf_ptr, data, cnt); | ||
1978 | memset(tty->flip.flag_buf_ptr, 0, cnt); | ||
1979 | tty->flip.char_buf_ptr += cnt; | ||
1980 | tty->flip.flag_buf_ptr += cnt; | ||
1981 | tty->flip.count += cnt; | ||
1982 | data += cnt; | 1976 | data += cnt; |
1983 | length -= cnt; | 1977 | length -= cnt; |
1984 | } while (length > 0); | 1978 | } while (length > 0); |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 2edf9cabad20..afc0f34b3a46 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1865,20 +1865,14 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c | |||
1865 | int cnt; | 1865 | int cnt; |
1866 | 1866 | ||
1867 | do { | 1867 | do { |
1868 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1868 | cnt = tty_buffer_request_room(tty, length); |
1869 | tty_flip_buffer_push(tty); | 1869 | if (cnt < length) { |
1870 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1870 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
1871 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1871 | __FUNCTION__, length - cnt); |
1872 | __FUNCTION__, length); | 1872 | if(cnt == 0) |
1873 | return; | 1873 | break; |
1874 | } | ||
1875 | } | 1874 | } |
1876 | cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); | 1875 | tty_insert_flip_string(tty, data, cnt); |
1877 | memcpy(tty->flip.char_buf_ptr, data, cnt); | ||
1878 | memset(tty->flip.flag_buf_ptr, 0, cnt); | ||
1879 | tty->flip.char_buf_ptr += cnt; | ||
1880 | tty->flip.flag_buf_ptr += cnt; | ||
1881 | tty->flip.count += cnt; | ||
1882 | data += cnt; | 1876 | data += cnt; |
1883 | length -= cnt; | 1877 | length -= cnt; |
1884 | } while (length > 0); | 1878 | } while (length > 0); |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 06d07cea0b70..9a5c97989562 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -711,7 +711,7 @@ static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
711 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 711 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
712 | struct tty_struct *tty; | 712 | struct tty_struct *tty; |
713 | unsigned char *data = urb->transfer_buffer; | 713 | unsigned char *data = urb->transfer_buffer; |
714 | int i, result; | 714 | int result; |
715 | 715 | ||
716 | dbg("%s - port %d", __FUNCTION__, port->number); | 716 | dbg("%s - port %d", __FUNCTION__, port->number); |
717 | 717 | ||
@@ -724,14 +724,8 @@ static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
724 | 724 | ||
725 | tty = port->tty; | 725 | tty = port->tty; |
726 | if (tty && urb->actual_length) { | 726 | if (tty && urb->actual_length) { |
727 | for (i = 0; i < urb->actual_length ; ++i) { | 727 | tty_buffer_request_room(tty, urb->actual_length); |
728 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 728 | tty_insert_flip_string(tty, data, urb->actual_length); |
729 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
730 | tty_flip_buffer_push(tty); | ||
731 | } | ||
732 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
733 | tty_insert_flip_char(tty, data[i], 0); | ||
734 | } | ||
735 | tty_flip_buffer_push(tty); | 729 | tty_flip_buffer_push(tty); |
736 | bytes_in += urb->actual_length; | 730 | bytes_in += urb->actual_length; |
737 | } | 731 | } |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 2dd191f5fe76..e760a70242c1 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -166,7 +166,6 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
166 | struct usb_serial_port *port = urb->context; | 166 | struct usb_serial_port *port = urb->context; |
167 | unsigned char *data = urb->transfer_buffer; | 167 | unsigned char *data = urb->transfer_buffer; |
168 | struct tty_struct *tty; | 168 | struct tty_struct *tty; |
169 | int i; | ||
170 | int result; | 169 | int result; |
171 | 170 | ||
172 | dbg("%s - port %d", __FUNCTION__, port->number); | 171 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -180,14 +179,8 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
180 | 179 | ||
181 | tty = port->tty; | 180 | tty = port->tty; |
182 | if (tty && urb->actual_length) { | 181 | if (tty && urb->actual_length) { |
183 | for (i = 0; i < urb->actual_length ; ++i) { | 182 | tty_buffer_request_room(tty, urb->actual_length); |
184 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 183 | tty_insert_flip_string(tty, data, urb->actual_length); |
185 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
186 | tty_flip_buffer_push(tty); | ||
187 | } | ||
188 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
189 | tty_insert_flip_char(tty, data[i], 0); | ||
190 | } | ||
191 | tty_flip_buffer_push(tty); | 184 | tty_flip_buffer_push(tty); |
192 | } | 185 | } |
193 | 186 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 4e2f7dfb58b2..78335a5f7743 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -648,7 +648,6 @@ static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
648 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, | 648 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, |
649 | urb->actual_length, data); | 649 | urb->actual_length, data); |
650 | } else { | 650 | } else { |
651 | int i; | ||
652 | int bytes_sent = ((__u8 *) data)[0] + | 651 | int bytes_sent = ((__u8 *) data)[0] + |
653 | ((unsigned int) ((__u8 *) data)[1] << 8); | 652 | ((unsigned int) ((__u8 *) data)[1] << 8); |
654 | tty = port->tty; | 653 | tty = port->tty; |
@@ -669,16 +668,8 @@ static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
669 | bytes_sent = urb->actual_length - 2; | 668 | bytes_sent = urb->actual_length - 2; |
670 | } | 669 | } |
671 | 670 | ||
672 | for (i = 2; i < 2+bytes_sent; i++) { | 671 | tty_buffer_request_room(tty, bytes_sent); |
673 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 672 | tty_insert_flip_string(tty, data + 2, bytes_sent); |
674 | * we drop them. */ | ||
675 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
676 | tty_flip_buffer_push(tty); | ||
677 | } | ||
678 | /* this doesn't actually push the data through unless | ||
679 | * tty->low_latency is set */ | ||
680 | tty_insert_flip_char(tty, ((__u8*) data)[i], 0); | ||
681 | } | ||
682 | tty_flip_buffer_push(tty); | 673 | tty_flip_buffer_push(tty); |
683 | 674 | ||
684 | /* again lockless, but debug info only */ | 675 | /* again lockless, but debug info only */ |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index d9c21e275130..b8b213185d0f 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -365,7 +365,6 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp) | |||
365 | 365 | ||
366 | static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) | 366 | static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) |
367 | { | 367 | { |
368 | int i; | ||
369 | int result; | 368 | int result; |
370 | struct usb_serial_port *port = (struct usb_serial_port *) purb->context; | 369 | struct usb_serial_port *port = (struct usb_serial_port *) purb->context; |
371 | struct tty_struct *tty; | 370 | struct tty_struct *tty; |
@@ -397,14 +396,8 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) | |||
397 | */ | 396 | */ |
398 | // END DEBUG | 397 | // END DEBUG |
399 | 398 | ||
400 | for (i = 0; i < purb->actual_length; ++i) { | 399 | tty_buffer_request_room(tty, purb->actual_length); |
401 | // if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. | 400 | tty_insert_flip_string(tty, data, purb->actual_length); |
402 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
403 | tty_flip_buffer_push(tty); | ||
404 | } | ||
405 | // this doesn't actually push the data through unless tty->low_latency is set | ||
406 | tty_insert_flip_char(tty, data[i], 0); | ||
407 | } | ||
408 | tty_flip_buffer_push(tty); | 401 | tty_flip_buffer_push(tty); |
409 | } | 402 | } |
410 | 403 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3fd2405304fd..52bdf6fe46f2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -321,7 +321,7 @@ static int option_write(struct usb_serial_port *port, | |||
321 | 321 | ||
322 | static void option_indat_callback(struct urb *urb, struct pt_regs *regs) | 322 | static void option_indat_callback(struct urb *urb, struct pt_regs *regs) |
323 | { | 323 | { |
324 | int i, err; | 324 | int err; |
325 | int endpoint; | 325 | int endpoint; |
326 | struct usb_serial_port *port; | 326 | struct usb_serial_port *port; |
327 | struct tty_struct *tty; | 327 | struct tty_struct *tty; |
@@ -338,11 +338,8 @@ static void option_indat_callback(struct urb *urb, struct pt_regs *regs) | |||
338 | } else { | 338 | } else { |
339 | tty = port->tty; | 339 | tty = port->tty; |
340 | if (urb->actual_length) { | 340 | if (urb->actual_length) { |
341 | for (i = 0; i < urb->actual_length ; ++i) { | 341 | tty_buffer_request_room(tty, urb->actual_length); |
342 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 342 | tty_insert_flip_string(tty, data, urb->actual_length); |
343 | tty_flip_buffer_push(tty); | ||
344 | tty_insert_flip_char(tty, data[i], 0); | ||
345 | } | ||
346 | tty_flip_buffer_push(tty); | 343 | tty_flip_buffer_push(tty); |
347 | } else { | 344 | } else { |
348 | dbg("%s: empty read urb received", __FUNCTION__); | 345 | dbg("%s: empty read urb received", __FUNCTION__); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index f03721056190..9ffff1938239 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -924,16 +924,12 @@ static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
924 | 924 | ||
925 | tty = port->tty; | 925 | tty = port->tty; |
926 | if (tty && urb->actual_length) { | 926 | if (tty && urb->actual_length) { |
927 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
927 | /* overrun is special, not associated with a char */ | 928 | /* overrun is special, not associated with a char */ |
928 | if (status & UART_OVERRUN_ERROR) | 929 | if (status & UART_OVERRUN_ERROR) |
929 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 930 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
930 | 931 | for (i = 0; i < urb->actual_length; ++i) | |
931 | for (i = 0; i < urb->actual_length; ++i) { | ||
932 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
933 | tty_flip_buffer_push(tty); | ||
934 | } | ||
935 | tty_insert_flip_char (tty, data[i], tty_flag); | 932 | tty_insert_flip_char (tty, data[i], tty_flag); |
936 | } | ||
937 | tty_flip_buffer_push (tty); | 933 | tty_flip_buffer_push (tty); |
938 | } | 934 | } |
939 | 935 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index abb830cb77bd..c18db3257073 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -1280,24 +1280,18 @@ static void ti_recv(struct device *dev, struct tty_struct *tty, | |||
1280 | int cnt; | 1280 | int cnt; |
1281 | 1281 | ||
1282 | do { | 1282 | do { |
1283 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1283 | cnt = tty_buffer_request_room(tty, length); |
1284 | tty_flip_buffer_push(tty); | 1284 | if (cnt < length) { |
1285 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1285 | dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length - cnt); |
1286 | dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length); | 1286 | if(cnt == 0) |
1287 | return; | 1287 | break; |
1288 | } | ||
1289 | } | 1288 | } |
1290 | cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); | 1289 | tty_insert_flip_string(tty, data, cnt); |
1291 | memcpy(tty->flip.char_buf_ptr, data, cnt); | 1290 | tty_flip_buffer_push(tty); |
1292 | memset(tty->flip.flag_buf_ptr, 0, cnt); | ||
1293 | tty->flip.char_buf_ptr += cnt; | ||
1294 | tty->flip.flag_buf_ptr += cnt; | ||
1295 | tty->flip.count += cnt; | ||
1296 | data += cnt; | 1291 | data += cnt; |
1297 | length -= cnt; | 1292 | length -= cnt; |
1298 | } while (length > 0); | 1293 | } while (length > 0); |
1299 | 1294 | ||
1300 | tty_flip_buffer_push(tty); | ||
1301 | } | 1295 | } |
1302 | 1296 | ||
1303 | 1297 | ||
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 49b1fbe61f25..bce3d55affd8 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -488,7 +488,6 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
488 | unsigned char *data = urb->transfer_buffer; | 488 | unsigned char *data = urb->transfer_buffer; |
489 | struct tty_struct *tty; | 489 | struct tty_struct *tty; |
490 | unsigned long flags; | 490 | unsigned long flags; |
491 | int i; | ||
492 | int throttled; | 491 | int throttled; |
493 | int result; | 492 | int result; |
494 | 493 | ||
@@ -503,14 +502,8 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
503 | 502 | ||
504 | tty = port->tty; | 503 | tty = port->tty; |
505 | if (tty && urb->actual_length) { | 504 | if (tty && urb->actual_length) { |
506 | for (i = 0; i < urb->actual_length ; ++i) { | 505 | tty_buffer_request_room(tty, urb->actual_length); |
507 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 506 | tty_insert_flip_string(tty, data, urb->actual_length); |
508 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
509 | tty_flip_buffer_push(tty); | ||
510 | } | ||
511 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
512 | tty_insert_flip_char(tty, data[i], 0); | ||
513 | } | ||
514 | tty_flip_buffer_push(tty); | 507 | tty_flip_buffer_push(tty); |
515 | } | 508 | } |
516 | spin_lock_irqsave(&priv->lock, flags); | 509 | spin_lock_irqsave(&priv->lock, flags); |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index a7c3c4734d83..557411c6e7c7 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -1434,7 +1434,9 @@ static void rx_data_softint(void *private) | |||
1434 | urb = wrap->urb; | 1434 | urb = wrap->urb; |
1435 | 1435 | ||
1436 | if (tty && urb->actual_length) { | 1436 | if (tty && urb->actual_length) { |
1437 | if (urb->actual_length > TTY_FLIPBUF_SIZE - tty->flip.count) { | 1437 | int len = tty_buffer_request_room(tty, urb->actual_length); |
1438 | /* This stuff can go away now I suspect */ | ||
1439 | if (unlikely(len < urb->actual_length)) { | ||
1438 | spin_lock_irqsave(&info->lock, flags); | 1440 | spin_lock_irqsave(&info->lock, flags); |
1439 | list_add(tmp, &info->rx_urb_q); | 1441 | list_add(tmp, &info->rx_urb_q); |
1440 | spin_unlock_irqrestore(&info->lock, flags); | 1442 | spin_unlock_irqrestore(&info->lock, flags); |
@@ -1442,11 +1444,8 @@ static void rx_data_softint(void *private) | |||
1442 | schedule_work(&info->rx_work); | 1444 | schedule_work(&info->rx_work); |
1443 | return; | 1445 | return; |
1444 | } | 1446 | } |
1445 | 1447 | tty_insert_flip_string(tty, urb->transfer_buffer, len); | |
1446 | memcpy(tty->flip.char_buf_ptr, urb->transfer_buffer, urb->actual_length); | 1448 | sent += len; |
1447 | tty->flip.char_buf_ptr += urb->actual_length; | ||
1448 | tty->flip.count += urb->actual_length; | ||
1449 | sent += urb->actual_length; | ||
1450 | } | 1449 | } |
1451 | 1450 | ||
1452 | urb->dev = port->serial->dev; | 1451 | urb->dev = port->serial->dev; |
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 7428198111eb..45f625d7d0b2 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h | |||
@@ -151,7 +151,7 @@ extern unsigned int keymap_count; | |||
151 | 151 | ||
152 | static inline void con_schedule_flip(struct tty_struct *t) | 152 | static inline void con_schedule_flip(struct tty_struct *t) |
153 | { | 153 | { |
154 | schedule_work(&t->flip.work); | 154 | schedule_work(&t->buf.work); |
155 | } | 155 | } |
156 | 156 | ||
157 | #endif | 157 | #endif |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 57449704a47b..3787102e4b12 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -51,16 +51,22 @@ | |||
51 | */ | 51 | */ |
52 | #define TTY_FLIPBUF_SIZE 512 | 52 | #define TTY_FLIPBUF_SIZE 512 |
53 | 53 | ||
54 | struct tty_flip_buffer { | 54 | struct tty_buffer { |
55 | struct tty_buffer *next; | ||
56 | char *char_buf_ptr; | ||
57 | unsigned char *flag_buf_ptr; | ||
58 | int used; | ||
59 | int size; | ||
60 | /* Data points here */ | ||
61 | unsigned long data[0]; | ||
62 | }; | ||
63 | |||
64 | struct tty_bufhead { | ||
55 | struct work_struct work; | 65 | struct work_struct work; |
56 | struct semaphore pty_sem; | 66 | struct semaphore pty_sem; |
57 | char *char_buf_ptr; | 67 | struct tty_buffer *head; /* Queue head */ |
58 | unsigned char *flag_buf_ptr; | 68 | struct tty_buffer *tail; /* Active buffer */ |
59 | int count; | 69 | struct tty_buffer *free; /* Free queue head */ |
60 | int buf_num; | ||
61 | unsigned char char_buf[2*TTY_FLIPBUF_SIZE]; | ||
62 | char flag_buf[2*TTY_FLIPBUF_SIZE]; | ||
63 | unsigned char slop[4]; /* N.B. bug overwrites buffer by 1 */ | ||
64 | }; | 70 | }; |
65 | /* | 71 | /* |
66 | * The pty uses char_buf and flag_buf as a contiguous buffer | 72 | * The pty uses char_buf and flag_buf as a contiguous buffer |
@@ -186,10 +192,11 @@ struct tty_struct { | |||
186 | unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; | 192 | unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; |
187 | unsigned char low_latency:1, warned:1; | 193 | unsigned char low_latency:1, warned:1; |
188 | unsigned char ctrl_status; | 194 | unsigned char ctrl_status; |
195 | unsigned int receive_room; /* Bytes free for queue */ | ||
189 | 196 | ||
190 | struct tty_struct *link; | 197 | struct tty_struct *link; |
191 | struct fasync_struct *fasync; | 198 | struct fasync_struct *fasync; |
192 | struct tty_flip_buffer flip; | 199 | struct tty_bufhead buf; |
193 | int max_flip_cnt; | 200 | int max_flip_cnt; |
194 | int alt_speed; /* For magic substitution of 38400 bps */ | 201 | int alt_speed; /* For magic substitution of 38400 bps */ |
195 | wait_queue_head_t write_wait; | 202 | wait_queue_head_t write_wait; |
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index abe9bfcf226c..be1400e82482 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h | |||
@@ -1,25 +1,33 @@ | |||
1 | #ifndef _LINUX_TTY_FLIP_H | 1 | #ifndef _LINUX_TTY_FLIP_H |
2 | #define _LINUX_TTY_FLIP_H | 2 | #define _LINUX_TTY_FLIP_H |
3 | 3 | ||
4 | extern int tty_buffer_request_room(struct tty_struct *tty, size_t size); | ||
5 | extern int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size); | ||
6 | extern int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size); | ||
7 | extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); | ||
8 | extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); | ||
9 | |||
4 | #ifdef INCLUDE_INLINE_FUNCS | 10 | #ifdef INCLUDE_INLINE_FUNCS |
5 | #define _INLINE_ extern | 11 | #define _INLINE_ extern |
6 | #else | 12 | #else |
7 | #define _INLINE_ static __inline__ | 13 | #define _INLINE_ static __inline__ |
8 | #endif | 14 | #endif |
9 | 15 | ||
10 | _INLINE_ void tty_insert_flip_char(struct tty_struct *tty, | 16 | _INLINE_ int tty_insert_flip_char(struct tty_struct *tty, |
11 | unsigned char ch, char flag) | 17 | unsigned char ch, char flag) |
12 | { | 18 | { |
13 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 19 | struct tty_buffer *tb = tty->buf.tail; |
14 | tty->flip.count++; | 20 | if (tb && tb->used < tb->size) { |
15 | *tty->flip.flag_buf_ptr++ = flag; | 21 | tb->flag_buf_ptr[tb->used] = flag; |
16 | *tty->flip.char_buf_ptr++ = ch; | 22 | tb->char_buf_ptr[tb->used++] = ch; |
23 | return 1; | ||
17 | } | 24 | } |
25 | return tty_insert_flip_string_flags(tty, &ch, &flag, 1); | ||
18 | } | 26 | } |
19 | 27 | ||
20 | _INLINE_ void tty_schedule_flip(struct tty_struct *tty) | 28 | _INLINE_ void tty_schedule_flip(struct tty_struct *tty) |
21 | { | 29 | { |
22 | schedule_delayed_work(&tty->flip.work, 1); | 30 | schedule_delayed_work(&tty->buf.work, 1); |
23 | } | 31 | } |
24 | 32 | ||
25 | #undef _INLINE_ | 33 | #undef _INLINE_ |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 6066afde5ce4..83c6e6c10ebb 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -81,14 +81,6 @@ | |||
81 | * pointer of flag bytes which indicate whether a character was | 81 | * pointer of flag bytes which indicate whether a character was |
82 | * received with a parity error, etc. | 82 | * received with a parity error, etc. |
83 | * | 83 | * |
84 | * int (*receive_room)(struct tty_struct *); | ||
85 | * | ||
86 | * This function is called by the low-level tty driver to | ||
87 | * determine how many characters the line discpline can accept. | ||
88 | * The low-level driver must not send more characters than was | ||
89 | * indicated by receive_room, or the line discpline may drop | ||
90 | * those characters. | ||
91 | * | ||
92 | * void (*write_wakeup)(struct tty_struct *); | 84 | * void (*write_wakeup)(struct tty_struct *); |
93 | * | 85 | * |
94 | * This function is called by the low-level tty driver to signal | 86 | * This function is called by the low-level tty driver to signal |
@@ -136,7 +128,6 @@ struct tty_ldisc { | |||
136 | */ | 128 | */ |
137 | void (*receive_buf)(struct tty_struct *, const unsigned char *cp, | 129 | void (*receive_buf)(struct tty_struct *, const unsigned char *cp, |
138 | char *fp, int count); | 130 | char *fp, int count); |
139 | int (*receive_room)(struct tty_struct *); | ||
140 | void (*write_wakeup)(struct tty_struct *); | 131 | void (*write_wakeup)(struct tty_struct *); |
141 | 132 | ||
142 | struct module *owner; | 133 | struct module *owner; |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 158a9c46d863..f57cde78c3de 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -480,13 +480,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) | |||
480 | BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); | 480 | BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); |
481 | 481 | ||
482 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { | 482 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { |
483 | register int i; | 483 | tty_buffer_request_room(tty, skb->len); |
484 | for (i = 0; i < skb->len; i++) { | 484 | tty_insert_flip_string(tty, skb->data, skb->len); |
485 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
486 | tty_flip_buffer_push(tty); | ||
487 | |||
488 | tty_insert_flip_char(tty, skb->data[i], 0); | ||
489 | } | ||
490 | tty_flip_buffer_push(tty); | 485 | tty_flip_buffer_push(tty); |
491 | } else | 486 | } else |
492 | tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len); | 487 | tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len); |