diff options
Diffstat (limited to 'drivers/char')
31 files changed, 536 insertions, 560 deletions
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 |