Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] TTY layer buffering revamp

The API and code have been through various bits of initial review by
serial driver people but they definitely need to live somewhere for a
while so the unconverted drivers can get knocked into shape, existing
drivers that have been updated can be better tuned and bugs whacked out.

This replaces the tty flip buffers with kmalloc objects in rings. In the
normal situation for an IRQ driven serial port at typical speeds the
behaviour is pretty much the same, two buffers end up allocated and the
kernel cycles between them as before.

When there are delays or at high speed we now behave far better as the
buffer pool can grow a bit rather than lose characters. This also means
that we can operate at higher speeds reliably.

For drivers that receive characters in blocks (DMA based, USB and
especially virtualisation) the layer allows a lot of driver specific
code that works around the tty layer with private secondary queues to be
removed. The IBM folks need this sort of layer, the smart serial port
people do, the virtualisers do (because a virtualised tty typically
operates at infinite speed rather than emulating 9600 baud).

Finally many drivers had invalid and unsafe attempts to avoid buffer
overflows by directly invoking tty methods extracted out of the innards
of work queue structs. These are no longer needed and all go away. That
fixes various random hangs with serial ports on overflow.

The other change in here is to optimise the receive_room path that is
used by some callers. It turns out that only one ldisc uses receive room
except asa constant and it updates it far far less than the value is
read. We thus make it a variable not a function call.

I expect the code to contain bugs due to the size alone but I'll be
watching and squashing them and feeding out new patches as it goes.

Because the buffers now dynamically expand you should only run out of
buffering when the kernel runs out of memory for real. That means a lot of
the horrible hacks high performance drivers used to do just aren't needed any
more.

Description:

tty_insert_flip_char is an old API and continues to work as before, as does
tty_flip_buffer_push() [this is why many drivers dont need modification]. It
does now also return the number of chars inserted

There are also

tty_buffer_request_room(tty, len)

which asks for a buffer block of the length requested and returns the space
found. This improves efficiency with hardware that knows how much to
transfer.

and tty_insert_flip_string_flags(tty, str, flags, len)

to insert a string of characters and flags

For a smart interface the usual code is

len = tty_request_buffer_room(tty, amount_hardware_says);
tty_insert_flip_string(tty, buffer_from_card, len);

More description!

At the moment tty buffers are attached directly to the tty. This is causing a
lot of the problems related to tty layer locking, also problems at high speed
and also with bursty data (such as occurs in virtualised environments)

I'm working on ripping out the flip buffers and replacing them with a pool of
dynamically allocated buffers. This allows both for old style "byte I/O"
devices and also helps virtualisation and smart devices where large blocks of
data suddenely materialise and need storing.

So far so good. Lots of drivers reference tty->flip.*. Several of them also
call directly and unsafely into function pointers it provides. This will all
break. Most drivers can use tty_insert_flip_char which can be kept as an API
but others need more.

At the moment I've added the following interfaces, if people think more will
be needed now is a good time to say

int tty_buffer_request_room(tty, size)

Try and ensure at least size bytes are available, returns actual room (may be
zero). At the moment it just uses the flipbuf space but that will change.
Repeated calls without characters being added are not cumulative. (ie if you
call it with 1, 1, 1, and then 4 you'll have four characters of space. The
other functions will also try and grow buffers in future but this will be a
more efficient way when you know block sizes.

int tty_insert_flip_char(tty, ch, flag)

As before insert a character if there is room. Now returns 1 for success, 0
for failure.

int tty_insert_flip_string(tty, str, len)

Insert a block of non error characters. Returns the number inserted.

int tty_prepare_flip_string(tty, strptr, len)

Adjust the buffer to allow len characters to be added. Returns a buffer
pointer in strptr and the length available. This allows for hardware that
needs to use functions like insl or mencpy_fromio.

Signed-off-by: Alan Cox <alan@redhat.com>
Cc: Paul Fulghum <paulkf@microgate.com>
Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
Signed-off-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: John Hawkes <hawkes@sgi.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Alan Cox and committed by
Linus Torvalds
33f0f88f 6ed80991

+1004 -1464
+1 -5
arch/um/drivers/chan_kern.c
··· 186 186 } 187 187 } 188 188 189 - if((tty->flip.flag_buf_ptr == NULL) || 190 - (tty->flip.char_buf_ptr == NULL)) 191 - return; 192 189 tty_insert_flip_char(tty, ch, TTY_NORMAL); 193 190 } 194 191 ··· 650 653 chan = list_entry(ele, struct chan, list); 651 654 if(!chan->input || (chan->ops->read == NULL)) continue; 652 655 do { 653 - if((tty != NULL) && 654 - (tty->flip.count >= TTY_FLIPBUF_SIZE)){ 656 + if (tty && !tty_buffer_request_room(tty, 1)) { 655 657 schedule_delayed_work(task, 1); 656 658 goto out; 657 659 }
+1 -15
drivers/bluetooth/hci_ldisc.c
··· 279 279 280 280 tty->disc_data = hu; 281 281 hu->tty = tty; 282 + tty->receive_room = 65536; 282 283 283 284 spin_lock_init(&hu->rx_lock); 284 285 ··· 347 346 348 347 if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) 349 348 hci_uart_tx_wakeup(hu); 350 - } 351 - 352 - /* hci_uart_tty_room() 353 - * 354 - * Callback function from tty driver. Return the amount of 355 - * space left in the receiver's buffer to decide if remote 356 - * transmitter is to be throttled. 357 - * 358 - * Arguments: tty pointer to associated tty instance data 359 - * Return Value: number of bytes left in receive buffer 360 - */ 361 - static int hci_uart_tty_room (struct tty_struct *tty) 362 - { 363 - return 65536; 364 349 } 365 350 366 351 /* hci_uart_tty_receive() ··· 531 544 hci_uart_ldisc.write = hci_uart_tty_write; 532 545 hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; 533 546 hci_uart_ldisc.poll = hci_uart_tty_poll; 534 - hci_uart_ldisc.receive_room = hci_uart_tty_room; 535 547 hci_uart_ldisc.receive_buf = hci_uart_tty_receive; 536 548 hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; 537 549 hci_uart_ldisc.owner = THIS_MODULE;
+3 -3
drivers/char/Kconfig
··· 80 80 81 81 config COMPUTONE 82 82 tristate "Computone IntelliPort Plus serial support" 83 - depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP 83 + depends on SERIAL_NONSTANDARD 84 84 ---help--- 85 85 This driver supports the entire family of Intelliport II/Plus 86 86 controllers with the exception of the MicroChannel controllers and ··· 153 153 154 154 config ESPSERIAL 155 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 157 help 158 158 This is a driver which supports Hayes ESP serial ports. Both single 159 159 port cards and multiport cards are supported. Make sure to read ··· 166 166 167 167 config MOXA_INTELLIO 168 168 tristate "Moxa Intellio support" 169 - depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP 169 + depends on SERIAL_NONSTANDARD 170 170 help 171 171 Say Y here if you have a Moxa Intellio multiport serial card. 172 172
+13 -20
drivers/char/amiserial.c
··· 265 265 int status; 266 266 int serdatr; 267 267 struct tty_struct *tty = info->tty; 268 - unsigned char ch; 268 + unsigned char ch, flag; 269 269 struct async_icount *icount; 270 + int oe = 0; 270 271 271 272 icount = &info->state->icount; 272 273 ··· 283 282 status |= UART_LSR_OE; 284 283 285 284 ch = serdatr & 0xff; 286 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 287 - goto ignore_char; 288 - *tty->flip.char_buf_ptr = ch; 289 285 icount->rx++; 290 286 291 287 #ifdef SERIAL_DEBUG_INTR 292 288 printk("DR%02x:%02x...", ch, status); 293 289 #endif 294 - *tty->flip.flag_buf_ptr = 0; 290 + flag = TTY_NORMAL; 295 291 296 292 /* 297 293 * We don't handle parity or frame errors - but I have left ··· 317 319 * should be ignored. 318 320 */ 319 321 if (status & info->ignore_status_mask) 320 - goto ignore_char; 322 + goto out; 321 323 322 324 status &= info->read_status_mask; 323 325 ··· 325 327 #ifdef SERIAL_DEBUG_INTR 326 328 printk("handling break...."); 327 329 #endif 328 - *tty->flip.flag_buf_ptr = TTY_BREAK; 330 + flag = TTY_BREAK; 329 331 if (info->flags & ASYNC_SAK) 330 332 do_SAK(tty); 331 333 } else if (status & UART_LSR_PE) 332 - *tty->flip.flag_buf_ptr = TTY_PARITY; 334 + flag = TTY_PARITY; 333 335 else if (status & UART_LSR_FE) 334 - *tty->flip.flag_buf_ptr = TTY_FRAME; 336 + flag = TTY_FRAME; 335 337 if (status & UART_LSR_OE) { 336 338 /* 337 339 * Overrun is special, since it's 338 340 * reported immediately, and doesn't 339 341 * affect the current character 340 342 */ 341 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 342 - tty->flip.count++; 343 - tty->flip.flag_buf_ptr++; 344 - tty->flip.char_buf_ptr++; 345 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 346 - } 343 + oe = 1; 347 344 } 348 345 } 349 - tty->flip.flag_buf_ptr++; 350 - tty->flip.char_buf_ptr++; 351 - tty->flip.count++; 352 - ignore_char: 353 - 346 + tty_insert_flip_char(tty, ch, flag); 347 + if (oe == 1) 348 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 354 349 tty_flip_buffer_push(tty); 350 + out: 351 + return; 355 352 } 356 353 357 354 static _INLINE_ void transmit_chars(struct async_struct *info)
+27 -62
drivers/char/cyclades.c
··· 641 641 #include <linux/timer.h> 642 642 #include <linux/interrupt.h> 643 643 #include <linux/tty.h> 644 + #include <linux/tty_flip.h> 644 645 #include <linux/serial.h> 645 646 #include <linux/major.h> 646 647 #include <linux/string.h> ··· 1087 1086 int had_work; 1088 1087 int mdm_change; 1089 1088 int mdm_status; 1090 - 1089 + int len; 1091 1090 if((cinfo = (struct cyclades_card *)dev_id) == 0){ 1092 1091 #ifdef CY_DEBUG_INTERRUPTS 1093 1092 printk("cyy_interrupt: spurious interrupt %d\n\r", irq); ··· 1164 1163 info->icount.rx++; 1165 1164 continue; 1166 1165 } 1167 - if (tty->flip.count < TTY_FLIPBUF_SIZE){ 1168 - tty->flip.count++; 1166 + if (tty_buffer_request_room(tty, 1)) { 1169 1167 if (data & info->read_status_mask){ 1170 1168 if(data & CyBREAK){ 1171 - *tty->flip.flag_buf_ptr++ = 1172 - TTY_BREAK; 1173 - *tty->flip.char_buf_ptr++ = 1174 - cy_readb(base_addr+(CyRDSR<<index)); 1169 + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK); 1175 1170 info->icount.rx++; 1176 1171 if (info->flags & ASYNC_SAK){ 1177 1172 do_SAK(tty); 1178 1173 } 1179 1174 }else if(data & CyFRAME){ 1180 - *tty->flip.flag_buf_ptr++ = 1181 - TTY_FRAME; 1182 - *tty->flip.char_buf_ptr++ = 1183 - cy_readb(base_addr+(CyRDSR<<index)); 1175 + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); 1184 1176 info->icount.rx++; 1185 1177 info->idle_stats.frame_errs++; 1186 1178 }else if(data & CyPARITY){ 1187 - *tty->flip.flag_buf_ptr++ = 1188 - TTY_PARITY; 1189 - *tty->flip.char_buf_ptr++ = 1190 - cy_readb(base_addr+(CyRDSR<<index)); 1179 + /* Pieces of seven... */ 1180 + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY); 1191 1181 info->icount.rx++; 1192 1182 info->idle_stats.parity_errs++; 1193 1183 }else if(data & CyOVERRUN){ 1194 - *tty->flip.flag_buf_ptr++ = 1195 - TTY_OVERRUN; 1196 - *tty->flip.char_buf_ptr++ = 0; 1184 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 1197 1185 info->icount.rx++; 1198 1186 /* If the flip buffer itself is 1199 1187 overflowing, we still lose 1200 1188 the next incoming character. 1201 1189 */ 1202 - if(tty->flip.count 1203 - < TTY_FLIPBUF_SIZE){ 1204 - tty->flip.count++; 1205 - *tty->flip.flag_buf_ptr++ = 1206 - TTY_NORMAL; 1207 - *tty->flip.char_buf_ptr++ = 1208 - cy_readb(base_addr+(CyRDSR<<index)); 1209 - info->icount.rx++; 1210 - } 1190 + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); 1191 + info->icount.rx++; 1211 1192 info->idle_stats.overruns++; 1212 1193 /* These two conditions may imply */ 1213 1194 /* a normal read should be done. */ 1214 1195 /* }else if(data & CyTIMEOUT){ */ 1215 1196 /* }else if(data & CySPECHAR){ */ 1216 - }else{ 1217 - *tty->flip.flag_buf_ptr++ = 0; 1218 - *tty->flip.char_buf_ptr++ = 0; 1219 - info->icount.rx++; 1197 + }else { 1198 + tty_insert_flip_char(tty, 0, TTY_NORMAL); 1199 + info->icount.rx++; 1220 1200 } 1221 1201 }else{ 1222 - *tty->flip.flag_buf_ptr++ = 0; 1223 - *tty->flip.char_buf_ptr++ = 0; 1202 + tty_insert_flip_char(tty, 0, TTY_NORMAL); 1224 1203 info->icount.rx++; 1225 1204 } 1226 1205 }else{ ··· 1221 1240 info->mon.char_max = char_count; 1222 1241 info->mon.char_last = char_count; 1223 1242 #endif 1224 - while(char_count--){ 1225 - if (tty->flip.count >= TTY_FLIPBUF_SIZE){ 1226 - break; 1227 - } 1228 - tty->flip.count++; 1243 + len = tty_buffer_request_room(tty, char_count); 1244 + while(len--){ 1229 1245 data = cy_readb(base_addr+(CyRDSR<<index)); 1230 - *tty->flip.flag_buf_ptr++ = TTY_NORMAL; 1231 - *tty->flip.char_buf_ptr++ = data; 1246 + tty_insert_flip_char(tty, data, TTY_NORMAL); 1232 1247 info->idle_stats.recv_bytes++; 1233 1248 info->icount.rx++; 1234 1249 #ifdef CY_16Y_HACK ··· 1233 1256 } 1234 1257 info->idle_stats.recv_idle = jiffies; 1235 1258 } 1236 - schedule_delayed_work(&tty->flip.work, 1); 1259 + schedule_delayed_work(&tty->buf.work, 1); 1237 1260 } 1238 1261 /* end of service */ 1239 1262 cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); ··· 1528 1551 struct cyclades_card *cinfo = &cy_card[info->card]; 1529 1552 struct tty_struct *tty = info->tty; 1530 1553 volatile int char_count; 1554 + int len; 1531 1555 #ifdef BLOCKMOVE 1532 1556 int small_count; 1533 1557 #else ··· 1584 1606 tty->flip.count += small_count; 1585 1607 } 1586 1608 #else 1587 - while(char_count--){ 1588 - if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt) 1589 - break; 1590 - 1591 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 1592 - break; 1593 - 1609 + len = tty_buffer_request_room(tty, char_count); 1610 + while(len--){ 1594 1611 data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); 1595 1612 new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); 1596 - tty->flip.count++; 1597 - *tty->flip.flag_buf_ptr++ = TTY_NORMAL; 1598 - *tty->flip.char_buf_ptr++ = data; 1613 + tty_insert_flip_char(tty, data, TTY_NORMAL); 1599 1614 info->idle_stats.recv_bytes++; 1600 1615 info->icount.rx++; 1601 1616 } ··· 1606 1635 } 1607 1636 #endif 1608 1637 info->idle_stats.recv_idle = jiffies; 1609 - schedule_delayed_work(&tty->flip.work, 1); 1638 + schedule_delayed_work(&tty->buf.work, 1); 1610 1639 } 1611 1640 /* Update rx_get */ 1612 1641 cy_writel(&buf_ctrl->rx_get, new_rx_get); ··· 1734 1763 1735 1764 switch(cmd) { 1736 1765 case C_CM_PR_ERROR: 1737 - tty->flip.count++; 1738 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 1739 - *tty->flip.char_buf_ptr++ = 0; 1766 + tty_insert_flip_char(tty, 0, TTY_PARITY); 1740 1767 info->icount.rx++; 1741 1768 special_count++; 1742 1769 break; 1743 1770 case C_CM_FR_ERROR: 1744 - tty->flip.count++; 1745 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 1746 - *tty->flip.char_buf_ptr++ = 0; 1771 + tty_insert_flip_char(tty, 0, TTY_FRAME); 1747 1772 info->icount.rx++; 1748 1773 special_count++; 1749 1774 break; 1750 1775 case C_CM_RXBRK: 1751 - tty->flip.count++; 1752 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 1753 - *tty->flip.char_buf_ptr++ = 0; 1776 + tty_insert_flip_char(tty, 0, TTY_BREAK); 1754 1777 info->icount.rx++; 1755 1778 special_count++; 1756 1779 break; ··· 1809 1844 if(delta_count) 1810 1845 cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); 1811 1846 if(special_count) 1812 - schedule_delayed_work(&tty->flip.work, 1); 1847 + schedule_delayed_work(&tty->buf.work, 1); 1813 1848 } 1814 1849 } 1815 1850
+4 -13
drivers/char/epca.c
··· 1786 1786 if (tty) { /* Begin if valid tty */ 1787 1787 if (event & BREAK_IND) { /* Begin if BREAK_IND */ 1788 1788 /* A break has been indicated */ 1789 - tty->flip.count++; 1790 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 1791 - *tty->flip.char_buf_ptr++ = 0; 1789 + tty_insert_flip_char(tty, 0, TTY_BREAK); 1792 1790 tty_schedule_flip(tty); 1793 1791 } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */ 1794 1792 if (ch->statusflags & LOWWAIT) ··· 2122 2124 int dataToRead, wrapgap, bytesAvailable; 2123 2125 unsigned int tail, head; 2124 2126 unsigned int wrapmask; 2125 - int rc; 2126 2127 2127 2128 /* --------------------------------------------------------------- 2128 2129 This routine is called by doint when a receive data event ··· 2159 2162 return; 2160 2163 } 2161 2164 2162 - if (tty->flip.count == TTY_FLIPBUF_SIZE) 2165 + if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0) 2163 2166 return; 2164 2167 2165 2168 if (readb(&bc->orun)) { 2166 2169 writeb(0, &bc->orun); 2167 2170 printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name); 2171 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 2168 2172 } 2169 2173 rxwinon(ch); 2170 - rptr = tty->flip.char_buf_ptr; 2171 - rc = tty->flip.count; 2172 2174 while (bytesAvailable > 0) { /* Begin while there is data on the card */ 2173 2175 wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; 2174 2176 /* --------------------------------------------------------------- ··· 2179 2183 /* -------------------------------------------------------------- 2180 2184 Make sure we don't overflow the buffer 2181 2185 ----------------------------------------------------------------- */ 2182 - if ((rc + dataToRead) > TTY_FLIPBUF_SIZE) 2183 - dataToRead = TTY_FLIPBUF_SIZE - rc; 2186 + dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); 2184 2187 if (dataToRead == 0) 2185 2188 break; 2186 2189 /* --------------------------------------------------------------- ··· 2187 2192 for translation if necessary. 2188 2193 ------------------------------------------------------------------ */ 2189 2194 memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); 2190 - rc += dataToRead; 2191 - rptr += dataToRead; 2192 2195 tail = (tail + dataToRead) & wrapmask; 2193 2196 bytesAvailable -= dataToRead; 2194 2197 } /* End while there is data on the card */ 2195 - tty->flip.count = rc; 2196 - tty->flip.char_buf_ptr = rptr; 2197 2198 globalwinon(ch); 2198 2199 writew(tail, &bc->rout); 2199 2200 /* Must be called with global data */
+28 -41
drivers/char/esp.c
··· 345 345 346 346 for (i = 0; i < num_bytes; i++) { 347 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 350 if (err_buf->data[i] & 0x04) { 351 - *(tty->flip.flag_buf_ptr++) = TTY_BREAK; 352 - 351 + flag = TTY_BREAK; 353 352 if (info->flags & ASYNC_SAK) 354 353 do_SAK(tty); 355 354 } 356 355 else if (err_buf->data[i] & 0x02) 357 - *(tty->flip.flag_buf_ptr++) = TTY_FRAME; 356 + flag = TTY_FRAME; 358 357 else if (err_buf->data[i] & 0x01) 359 - *(tty->flip.flag_buf_ptr++) = TTY_PARITY; 360 - else 361 - *(tty->flip.flag_buf_ptr++) = 0; 362 - 363 - tty->flip.count++; 358 + flag = TTY_PARITY; 359 + tty_insert_flip_char(tty, pio_buf->data[i], flag); 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 365 info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; 370 366 release_pio_buffer(pio_buf); ··· 393 397 int num_bytes; 394 398 unsigned long flags; 395 399 396 - 397 400 flags=claim_dma_lock(); 398 401 disable_dma(dma); 399 402 clear_dma_ff(dma); ··· 403 408 404 409 info->icount.rx += num_bytes; 405 410 406 - memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes); 407 - tty->flip.char_buf_ptr += num_bytes; 408 - tty->flip.count += num_bytes; 409 - memset(tty->flip.flag_buf_ptr, 0, num_bytes); 410 - tty->flip.flag_buf_ptr += num_bytes; 411 - 412 411 if (num_bytes > 0) { 413 - tty->flip.flag_buf_ptr--; 412 + tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); 414 413 415 414 status &= (0x1c & info->read_status_mask); 416 - 417 - if (status & info->ignore_status_mask) { 418 - tty->flip.count--; 419 - tty->flip.char_buf_ptr--; 420 - tty->flip.flag_buf_ptr--; 421 - } else if (status & 0x10) { 422 - *tty->flip.flag_buf_ptr = TTY_BREAK; 423 - (info->icount.brk)++; 424 - if (info->flags & ASYNC_SAK) 425 - do_SAK(tty); 426 - } else if (status & 0x08) { 427 - *tty->flip.flag_buf_ptr = TTY_FRAME; 428 - (info->icount.frame)++; 429 - } 430 - else if (status & 0x04) { 431 - *tty->flip.flag_buf_ptr = TTY_PARITY; 432 - (info->icount.parity)++; 433 - } 434 - 435 - tty->flip.flag_buf_ptr++; 436 415 437 - schedule_delayed_work(&tty->flip.work, 1); 416 + /* Is the status significant or do we throw the last byte ? */ 417 + if (!(status & info->ignore_status_mask)) { 418 + int statflag = 0; 419 + 420 + if (status & 0x10) { 421 + statflag = TTY_BREAK; 422 + (info->icount.brk)++; 423 + if (info->flags & ASYNC_SAK) 424 + do_SAK(tty); 425 + } else if (status & 0x08) { 426 + statflag = TTY_FRAME; 427 + (info->icount.frame)++; 428 + } 429 + else if (status & 0x04) { 430 + statflag = TTY_PARITY; 431 + (info->icount.parity)++; 432 + } 433 + tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag); 434 + } 435 + schedule_delayed_work(&tty->buf.work, 1); 438 436 } 439 437 440 438 if (dma_bytes != num_bytes) { ··· 681 693 num_bytes = serial_in(info, UART_ESI_STAT1) << 8; 682 694 num_bytes |= serial_in(info, UART_ESI_STAT2); 683 695 684 - if (num_bytes > (TTY_FLIPBUF_SIZE - info->tty->flip.count)) 685 - num_bytes = TTY_FLIPBUF_SIZE - info->tty->flip.count; 696 + num_bytes = tty_buffer_request_room(info->tty, num_bytes); 686 697 687 698 if (num_bytes) { 688 699 if (dma_bytes ||
+2 -4
drivers/char/hvc_console.c
··· 597 597 598 598 /* Read data if any */ 599 599 for (;;) { 600 - int count = N_INBUF; 601 - if (count > (TTY_FLIPBUF_SIZE - tty->flip.count)) 602 - count = TTY_FLIPBUF_SIZE - tty->flip.count; 600 + int count = tty_buffer_request_room(tty, N_INBUF); 603 601 604 602 /* If flip is full, just reschedule a later read */ 605 603 if (count == 0) { ··· 633 635 tty_insert_flip_char(tty, buf[i], 0); 634 636 } 635 637 636 - if (tty->flip.count) 638 + if (count) 637 639 tty_schedule_flip(tty); 638 640 639 641 /*
+4 -6
drivers/char/hvcs.c
··· 456 456 /* remove the read masks */ 457 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 460 got = hvc_get_chars(unit_address, 461 461 &buf[0], 462 462 HVCS_BUFF_LEN); 463 - for (i=0;got && i<got;i++) 464 - tty_insert_flip_char(tty, buf[i], TTY_NORMAL); 463 + tty_insert_flip_string(tty, buf, got); 465 464 } 466 465 467 466 /* Give the TTY time to process the data we just sent. */ ··· 468 469 hvcsd->todo_mask |= HVCS_QUICK_READ; 469 470 470 471 spin_unlock_irqrestore(&hvcsd->lock, flags); 471 - if (tty->flip.count) { 472 - /* This is synch because tty->low_latency == 1 */ 472 + /* This is synch because tty->low_latency == 1 */ 473 + if(got) 473 474 tty_flip_buffer_push(tty); 474 - } 475 475 476 476 if (!got) { 477 477 /* Do this _after_ the flip_buffer_push */
+9 -15
drivers/char/isicom.c
··· 115 115 #include <linux/module.h> 116 116 #include <linux/kernel.h> 117 117 #include <linux/tty.h> 118 + #include <linux/tty_flip.h> 118 119 #include <linux/termios.h> 119 120 #include <linux/fs.h> 120 121 #include <linux/sched.h> ··· 774 773 unsigned short base, header, word_count, count; 775 774 unsigned char channel; 776 775 short byte_count; 776 + unsigned char *rp; 777 777 778 778 card = (struct isi_board *) dev_id; 779 779 ··· 905 903 break; 906 904 907 905 case 1: /* Received Break !!! */ 908 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 909 - break; 910 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 911 - *tty->flip.char_buf_ptr++ = 0; 912 - tty->flip.count++; 906 + tty_insert_flip_char(tty, 0, TTY_BREAK); 913 907 if (port->flags & ASYNC_SAK) 914 908 do_SAK(tty); 915 - schedule_delayed_work(&tty->flip.work, 1); 909 + tty_flip_buffer_push(tty); 916 910 break; 917 911 918 912 case 2: /* Statistics */ ··· 921 923 } 922 924 } 923 925 else { /* Data Packet */ 924 - count = min_t(unsigned short, byte_count, (TTY_FLIPBUF_SIZE - tty->flip.count)); 926 + 927 + count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); 925 928 #ifdef ISICOM_DEBUG 926 929 printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n", 927 930 count, byte_count); 928 931 #endif 929 932 word_count = count >> 1; 930 - insw(base, tty->flip.char_buf_ptr, word_count); 931 - tty->flip.char_buf_ptr += (word_count << 1); 933 + insw(base, rp, word_count); 932 934 byte_count -= (word_count << 1); 933 935 if (count & 0x0001) { 934 - *tty->flip.char_buf_ptr++ = (char)(inw(base) & 0xff); 936 + tty_insert_flip_char(tty, inw(base) & 0xff, TTY_NORMAL); 935 937 byte_count -= 2; 936 938 } 937 - memset(tty->flip.flag_buf_ptr, 0, count); 938 - tty->flip.flag_buf_ptr += count; 939 - tty->flip.count += count; 940 - 941 939 if (byte_count > 0) { 942 940 printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n", 943 941 base, channel+1); ··· 942 948 byte_count -= 2; 943 949 } 944 950 } 945 - schedule_delayed_work(&tty->flip.work, 1); 951 + tty_flip_buffer_push(tty); 946 952 } 947 953 if (card->isa == YES) 948 954 ClearInterrupt(base);
+9 -17
drivers/char/istallion.c
··· 2711 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 2716 shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); 2716 2717 2717 2718 while (len > 0) { 2718 2719 stlen = MIN(len, stlen); 2719 - memcpy(tty->flip.char_buf_ptr, (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 - 2720 + tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen); 2725 2721 len -= stlen; 2726 2722 tail += stlen; 2727 2723 if (tail >= size) { ··· 2902 2906 2903 2907 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { 2904 2908 if (tty != (struct tty_struct *) NULL) { 2905 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 2906 - tty->flip.count++; 2907 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 2908 - *tty->flip.char_buf_ptr++ = 0; 2909 - if (portp->flags & ASYNC_SAK) { 2910 - do_SAK(tty); 2911 - EBRDENABLE(brdp); 2912 - } 2913 - tty_schedule_flip(tty); 2909 + tty_insert_flip_char(tty, 0, TTY_BREAK); 2910 + if (portp->flags & ASYNC_SAK) { 2911 + do_SAK(tty); 2912 + EBRDENABLE(brdp); 2914 2913 } 2914 + tty_schedule_flip(tty); 2915 2915 } 2916 2916 } 2917 2917 ··· 4932 4940 if (portp->tty != (struct tty_struct *) NULL) { 4933 4941 if (portp->tty->driver_data == portp) { 4934 4942 stli_comstats.ttystate = portp->tty->flags; 4935 - stli_comstats.rxbuffered = portp->tty->flip.count; 4943 + stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/; 4936 4944 if (portp->tty->termios != (struct termios *) NULL) { 4937 4945 stli_comstats.cflags = portp->tty->termios->c_cflag; 4938 4946 stli_comstats.iflags = portp->tty->termios->c_iflag;
+30 -43
drivers/char/moxa.c
··· 269 269 static int MoxaPortDCDON(int); 270 270 static void MoxaPortFlushData(int, int); 271 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 273 static int MoxaPortTxQueue(int); 274 274 static int MoxaPortRxQueue(int); 275 275 static int MoxaPortTxFree(int); ··· 300 300 .tiocmget = moxa_tiocmget, 301 301 .tiocmset = moxa_tiocmset, 302 302 }; 303 + 304 + static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; 303 305 304 306 #ifdef CONFIG_PCI 305 307 static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) ··· 647 645 if (ch == NULL) 648 646 return (0); 649 647 port = ch->port; 650 - save_flags(flags); 651 - cli(); 648 + 649 + spin_lock_irqsave(&moxa_lock, flags); 652 650 len = MoxaPortWriteData(port, (unsigned char *) buf, count); 653 - restore_flags(flags); 651 + spin_unlock_irqrestore(&moxa_lock, flags); 654 652 655 653 /********************************************* 656 654 if ( !(ch->statusflags & LOWWAIT) && ··· 725 723 if (ch == NULL) 726 724 return; 727 725 port = ch->port; 728 - save_flags(flags); 729 - cli(); 726 + spin_lock_irqsave(&moxa_lock, flags); 730 727 moxaXmitBuff[0] = c; 731 728 MoxaPortWriteData(port, moxaXmitBuff, 1); 732 - restore_flags(flags); 729 + spin_unlock_irqrestore(&moxa_lock, flags); 733 730 /************************************************ 734 731 if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) 735 732 *************************************************/ ··· 1031 1030 printk("block_til_ready before block: ttys%d, count = %d\n", 1032 1031 ch->line, ch->count); 1033 1032 #endif 1034 - save_flags(flags); 1035 - cli(); 1033 + spin_lock_irqsave(&moxa_lock, flags); 1036 1034 if (!tty_hung_up_p(filp)) 1037 1035 ch->count--; 1038 - restore_flags(flags); 1039 1036 ch->blocked_open++; 1037 + spin_unlock_irqrestore(&moxa_lock, flags); 1038 + 1040 1039 while (1) { 1041 1040 set_current_state(TASK_INTERRUPTIBLE); 1042 1041 if (tty_hung_up_p(filp) || ··· 1063 1062 } 1064 1063 set_current_state(TASK_RUNNING); 1065 1064 remove_wait_queue(&ch->open_wait, &wait); 1065 + 1066 + spin_lock_irqsave(&moxa_lock, flags); 1066 1067 if (!tty_hung_up_p(filp)) 1067 1068 ch->count++; 1068 1069 ch->blocked_open--; 1070 + spin_unlock_irqrestore(&moxa_lock, flags); 1069 1071 #ifdef SERIAL_DEBUG_OPEN 1070 1072 printk("block_til_ready after blocking: ttys%d, count = %d\n", 1071 1073 ch->line, ch->count); 1072 1074 #endif 1073 1075 if (retval) 1074 1076 return (retval); 1077 + /* FIXME: review to see if we need to use set_bit on these */ 1075 1078 ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 1076 - return (0); 1079 + return 0; 1077 1080 } 1078 1081 1079 1082 static void setup_empty_event(struct tty_struct *tty) ··· 1085 1080 struct moxa_str *ch = tty->driver_data; 1086 1081 unsigned long flags; 1087 1082 1088 - save_flags(flags); 1089 - cli(); 1083 + spin_lock_irqsave(&moxa_lock, flags); 1090 1084 ch->statusflags |= EMPTYWAIT; 1091 1085 moxaEmptyTimer_on[ch->port] = 0; 1092 1086 del_timer(&moxaEmptyTimer[ch->port]); 1093 1087 moxaEmptyTimer[ch->port].expires = jiffies + HZ; 1094 1088 moxaEmptyTimer_on[ch->port] = 1; 1095 1089 add_timer(&moxaEmptyTimer[ch->port]); 1096 - restore_flags(flags); 1090 + spin_unlock_irqrestore(&moxa_lock, flags); 1097 1091 } 1098 1092 1099 1093 static void check_xmit_empty(unsigned long data) ··· 1139 1135 { 1140 1136 struct tty_struct *tp; 1141 1137 struct termios *ts; 1142 - int i, count, rc, space; 1143 - unsigned char *charptr, *flagptr; 1144 1138 unsigned long flags; 1145 1139 1146 1140 ts = NULL; ··· 1152 1150 MoxaPortFlushData(ch->port, 0); 1153 1151 return; 1154 1152 } 1155 - space = TTY_FLIPBUF_SIZE - tp->flip.count; 1156 - if (space <= 0) 1157 - return; 1158 - charptr = tp->flip.char_buf_ptr; 1159 - flagptr = tp->flip.flag_buf_ptr; 1160 - rc = tp->flip.count; 1161 - save_flags(flags); 1162 - cli(); 1163 - count = MoxaPortReadData(ch->port, charptr, space); 1164 - restore_flags(flags); 1165 - for (i = 0; i < count; i++) 1166 - *flagptr++ = 0; 1167 - charptr += count; 1168 - rc += count; 1169 - tp->flip.count = rc; 1170 - tp->flip.char_buf_ptr = charptr; 1171 - tp->flip.flag_buf_ptr = flagptr; 1172 - tty_schedule_flip(ch->tty); 1153 + spin_lock_irqsave(&moxa_lock, flags); 1154 + MoxaPortReadData(ch->port, tp); 1155 + spin_unlock_irqrestore(&moxa_lock, flags); 1156 + tty_schedule_flip(tp); 1173 1157 } 1174 1158 1175 1159 #define Magic_code 0x404 ··· 1762 1774 * 14. MoxaPortDCDON(int port); * 1763 1775 * 15. MoxaPortFlushData(int port, int mode); * 1764 1776 * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * 1765 - * 17. MoxaPortReadData(int port, unsigned char * buffer, int length); * 1777 + * 17. MoxaPortReadData(int port, struct tty_struct *tty); * 1766 1778 * 18. MoxaPortTxBufSize(int port); * 1767 1779 * 19. MoxaPortRxBufSize(int port); * 1768 1780 * 20. MoxaPortTxQueue(int port); * ··· 1991 2003 * 1992 2004 * Function 21: Read data. 1993 2005 * Syntax: 1994 - * int MoxaPortReadData(int port, unsigned char * buffer, int length); 2006 + * int MoxaPortReadData(int port, struct tty_struct *tty); 1995 2007 * int port : port number (0 - 127) 1996 - * unsigned char * buffer : pointer to read data buffer. 1997 - * int length : read data buffer length 2008 + * struct tty_struct *tty : tty for data 1998 2009 * 1999 2010 * return: 0 - length : real read data length 2000 2011 * ··· 2491 2504 return (total); 2492 2505 } 2493 2506 2494 - int MoxaPortReadData(int port, unsigned char * buffer, int space) 2507 + int MoxaPortReadData(int port, struct tty_struct *tty) 2495 2508 { 2496 2509 register ushort head, pageofs; 2497 2510 int i, count, cnt, len, total, remain; ··· 2509 2522 count = (tail >= head) ? (tail - head) 2510 2523 : (tail - head + rx_mask + 1); 2511 2524 if (count == 0) 2512 - return (0); 2525 + return 0; 2513 2526 2514 - total = (space > count) ? count : space; 2527 + total = count; 2515 2528 remain = count - total; 2516 2529 moxaLog.rxcnt[port] += total; 2517 2530 count = total; ··· 2526 2539 len = (count > len) ? len : count; 2527 2540 ofs = baseAddr + DynPage_addr + bufhead + head; 2528 2541 for (i = 0; i < len; i++) 2529 - *buffer++ = readb(ofs + i); 2542 + tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); 2530 2543 head = (head + len) & rx_mask; 2531 2544 count -= len; 2532 2545 } ··· 2543 2556 writew(pageno, baseAddr + Control_reg); 2544 2557 ofs = baseAddr + DynPage_addr + pageofs; 2545 2558 for (i = 0; i < cnt; i++) 2546 - *buffer++ = readb(ofs + i); 2559 + tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); 2547 2560 if (count == 0) { 2548 2561 writew((head + len) & rx_mask, ofsAddr + RXrptr); 2549 2562 break;
+1 -1
drivers/char/mxser.c
··· 1982 1982 1983 1983 spin_lock_irqsave(&info->slock, flags); 1984 1984 1985 - recv_room = tty->ldisc.receive_room(tty); 1985 + recv_room = tty->receive_room; 1986 1986 if ((recv_room == 0) && (!info->ldisc_stop_rx)) { 1987 1987 //mxser_throttle(tty); 1988 1988 mxser_stoprx(tty);
+1 -17
drivers/char/n_hdlc.c
··· 212 212 .ioctl = n_hdlc_tty_ioctl, 213 213 .poll = n_hdlc_tty_poll, 214 214 .receive_buf = n_hdlc_tty_receive, 215 - .receive_room = n_hdlc_tty_room, 216 215 .write_wakeup = n_hdlc_tty_wakeup, 217 216 }; 218 217 ··· 336 337 337 338 tty->disc_data = n_hdlc; 338 339 n_hdlc->tty = tty; 340 + tty->receive_room = 65536; 339 341 340 342 #if defined(TTY_NO_WRITE_SPLIT) 341 343 /* change tty_io write() to not split large writes into 8K chunks */ ··· 476 476 n_hdlc_send_frames (n_hdlc, tty); 477 477 478 478 } /* end of n_hdlc_tty_wakeup() */ 479 - 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 479 496 480 /** 497 481 * n_hdlc_tty_receive - Called by tty driver when receive data is available
+1 -9
drivers/char/n_r3964.c
··· 147 147 struct poll_table_struct *wait); 148 148 static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, 149 149 char *fp, int count); 150 - static int r3964_receive_room(struct tty_struct *tty); 151 150 152 151 static struct tty_ldisc tty_ldisc_N_R3964 = { 153 152 .owner = THIS_MODULE, ··· 160 161 .set_termios = r3964_set_termios, 161 162 .poll = r3964_poll, 162 163 .receive_buf = r3964_receive_buf, 163 - .receive_room = r3964_receive_room, 164 164 }; 165 165 166 166 ··· 1117 1119 pInfo->nRetry = 0; 1118 1120 1119 1121 tty->disc_data = pInfo; 1122 + tty->receive_room = 65536; 1120 1123 1121 1124 init_timer(&pInfo->tmr); 1122 1125 pInfo->tmr.data = (unsigned long)pInfo; ··· 1403 1404 1404 1405 } 1405 1406 } 1406 - 1407 - static int r3964_receive_room(struct tty_struct *tty) 1408 - { 1409 - TRACE_L("receive_room"); 1410 - return -1; 1411 - } 1412 - 1413 1407 1414 1408 MODULE_LICENSE("GPL"); 1415 1409 MODULE_ALIAS_LDISC(N_R3964);
+37 -29
drivers/char/n_tty.c
··· 78 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 108 if (tty->read_cnt < N_TTY_BUF_SIZE) { 84 109 tty->read_buf[tty->read_head] = c; ··· 112 87 } 113 88 } 114 89 115 - static inline void put_tty_queue(unsigned char c, struct tty_struct *tty) 90 + static void put_tty_queue(unsigned char c, struct tty_struct *tty) 116 91 { 117 92 unsigned long flags; 118 93 /* ··· 161 136 spin_unlock_irqrestore(&tty->read_lock, flags); 162 137 tty->canon_head = tty->canon_data = tty->erasing = 0; 163 138 memset(&tty->read_flags, 0, sizeof tty->read_flags); 139 + n_tty_set_room(tty); 164 140 check_unthrottle(tty); 165 141 } 166 142 ··· 864 838 put_tty_queue(c, tty); 865 839 } 866 840 867 - /** 868 - * n_tty_receive_room - receive space 869 - * @tty: terminal 870 - * 871 - * Called by the driver to find out how much data it is 872 - * permitted to feed to the line discipline without any being lost 873 - * and thus to manage flow control. Not serialized. Answers for the 874 - * "instant". 875 - */ 876 - 877 - static int n_tty_receive_room(struct tty_struct *tty) 878 - { 879 - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; 880 - 881 - /* 882 - * If we are doing input canonicalization, and there are no 883 - * pending newlines, let characters through without limit, so 884 - * that erase characters will be handled. Other excess 885 - * characters will be beeped. 886 - */ 887 - if (left <= 0) 888 - left = tty->icanon && !tty->canon_data; 889 - return left; 890 - } 891 841 892 842 /** 893 843 * n_tty_write_wakeup - asynchronous I/O notifier ··· 955 953 tty->driver->flush_chars(tty); 956 954 } 957 955 956 + n_tty_set_room(tty); 957 + 958 958 if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { 959 959 kill_fasync(&tty->fasync, SIGIO, POLL_IN); 960 960 if (waitqueue_active(&tty->read_wait)) ··· 968 964 * mode. We don't want to throttle the driver if we're in 969 965 * canonical mode and don't have a newline yet! 970 966 */ 971 - if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) { 967 + if (tty->receive_room < TTY_THRESHOLD_THROTTLE) { 972 968 /* check TTY_THROTTLED first so it indicates our state */ 973 969 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && 974 970 tty->driver->throttle) ··· 1003 999 if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { 1004 1000 tty->raw = 1; 1005 1001 tty->real_raw = 1; 1002 + n_tty_set_room(tty); 1006 1003 return; 1007 1004 } 1008 1005 if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || ··· 1056 1051 else 1057 1052 tty->real_raw = 0; 1058 1053 } 1054 + n_tty_set_room(tty); 1059 1055 } 1060 1056 1061 1057 /** ··· 1136 1130 * 1137 1131 */ 1138 1132 1139 - static inline int copy_from_read_buf(struct tty_struct *tty, 1133 + static int copy_from_read_buf(struct tty_struct *tty, 1140 1134 unsigned char __user **b, 1141 1135 size_t *nr) 1142 1136 ··· 1314 1308 retval = -ERESTARTSYS; 1315 1309 break; 1316 1310 } 1311 + n_tty_set_room(tty); 1317 1312 clear_bit(TTY_DONT_FLIP, &tty->flags); 1318 1313 timeout = schedule_timeout(timeout); 1319 1314 set_bit(TTY_DONT_FLIP, &tty->flags); ··· 1407 1400 clear_bit(TTY_PUSH, &tty->flags); 1408 1401 } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) 1409 1402 goto do_it_again; 1403 + 1404 + n_tty_set_room(tty); 1410 1405 1411 1406 return retval; 1412 1407 } ··· 1562 1553 normal_poll, /* poll */ 1563 1554 NULL, /* hangup */ 1564 1555 n_tty_receive_buf, /* receive_buf */ 1565 - n_tty_receive_room, /* receive_room */ 1566 1556 n_tty_write_wakeup /* write_wakeup */ 1567 1557 }; 1568 1558
+2 -2
drivers/char/pty.c
··· 111 111 if (!to || tty->stopped) 112 112 return 0; 113 113 114 - c = to->ldisc.receive_room(to); 114 + c = to->receive_room; 115 115 if (c > count) 116 116 c = count; 117 117 to->ldisc.receive_buf(to, buf, NULL, c); ··· 126 126 if (!to || tty->stopped) 127 127 return 0; 128 128 129 - return to->ldisc.receive_room(to); 129 + return to->receive_room; 130 130 } 131 131 132 132 /*
+5 -8
drivers/char/rio/riointr.c
··· 38 38 #include <linux/slab.h> 39 39 #include <linux/errno.h> 40 40 #include <linux/tty.h> 41 + #include <linux/tty_flip.h> 41 42 #include <asm/io.h> 42 43 #include <asm/system.h> 43 44 #include <asm/string.h> ··· 561 560 struct PKT *PacketP; 562 561 register uint DataCnt; 563 562 uchar * ptr; 563 + unsigned char *buf; 564 564 int copied =0; 565 565 566 566 static int intCount, RxIntCnt; ··· 659 657 ** and available space. 660 658 */ 661 659 662 - transCount = min_t(unsigned int, PacketP->len & PKT_LEN_MASK, 663 - TTY_FLIPBUF_SIZE - TtyP->flip.count); 660 + transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK); 664 661 rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n", 665 662 PortP->PortNum, transCount); 666 663 /* ··· 679 678 #endif 680 679 ptr = (uchar *) PacketP->data + PortP->RxDataStart; 681 680 682 - rio_memcpy_fromio (TtyP->flip.char_buf_ptr, ptr, transCount); 683 - memset(TtyP->flip.flag_buf_ptr, TTY_NORMAL, transCount); 684 - 681 + tty_prepare_flip_string(TtyP, &buf, transCount); 682 + rio_memcpy_fromio (buf, ptr, transCount); 685 683 #ifdef STATS 686 684 /* 687 685 ** keep a count for statistical purposes ··· 690 690 PortP->RxDataStart += transCount; 691 691 PacketP->len -= transCount; 692 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 695 #ifdef ___DEBUG_IT___
+13 -26
drivers/char/riscom8.c
··· 46 46 #include <linux/major.h> 47 47 #include <linux/init.h> 48 48 #include <linux/delay.h> 49 + #include <linux/tty_flip.h> 49 50 50 51 #include <asm/uaccess.h> 51 52 ··· 355 354 struct riscom_port *port; 356 355 struct tty_struct *tty; 357 356 unsigned char status; 358 - unsigned char ch; 357 + unsigned char ch, flag; 359 358 360 359 if (!(port = rc_get_port(bp, "Receive"))) 361 360 return; 362 361 363 362 tty = port->tty; 364 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 365 - printk(KERN_WARNING "rc%d: port %d: Working around flip " 366 - "buffer overflow.\n", 367 - board_No(bp), port_No(port)); 368 - return; 369 - } 370 363 371 364 #ifdef RC_REPORT_OVERRUN 372 365 status = rc_in(bp, CD180_RCSR); 373 - if (status & RCSR_OE) { 366 + if (status & RCSR_OE) 374 367 port->overrun++; 375 - #if 0 376 - printk(KERN_ERR "rc%d: port %d: Overrun. Total %ld overruns\n", 377 - board_No(bp), port_No(port), port->overrun); 378 - #endif 379 - } 380 368 status &= port->mark_mask; 381 369 #else 382 370 status = rc_in(bp, CD180_RCSR) & port->mark_mask; ··· 383 393 } else if (status & RCSR_BREAK) { 384 394 printk(KERN_INFO "rc%d: port %d: Handling break...\n", 385 395 board_No(bp), port_No(port)); 386 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 396 + flag = TTY_BREAK; 387 397 if (port->flags & ASYNC_SAK) 388 398 do_SAK(tty); 389 399 390 400 } else if (status & RCSR_PE) 391 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 401 + flag = TTY_PARITY; 392 402 393 403 else if (status & RCSR_FE) 394 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 404 + flag = TTY_FRAME; 395 405 396 406 else if (status & RCSR_OE) 397 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 407 + flag = TTY_OVERRUN; 398 408 399 409 else 400 - *tty->flip.flag_buf_ptr++ = 0; 410 + flag = TTY_NORMAL; 401 411 402 - *tty->flip.char_buf_ptr++ = ch; 403 - tty->flip.count++; 404 - schedule_delayed_work(&tty->flip.work, 1); 412 + tty_insert_flip_char(tty, ch, flag); 413 + tty_flip_buffer_push(tty); 405 414 } 406 415 407 416 static inline void rc_receive(struct riscom_board const * bp) ··· 421 432 #endif 422 433 423 434 while (count--) { 424 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 435 + if (tty_buffer_request_room(tty, 1) == 0) { 425 436 printk(KERN_WARNING "rc%d: port %d: Working around " 426 437 "flip buffer overflow.\n", 427 438 board_No(bp), port_No(port)); 428 439 break; 429 440 } 430 - *tty->flip.char_buf_ptr++ = rc_in(bp, CD180_RDR); 431 - *tty->flip.flag_buf_ptr++ = 0; 432 - tty->flip.count++; 441 + tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL); 433 442 } 434 - schedule_delayed_work(&tty->flip.work, 1); 443 + tty_flip_buffer_push(tty); 435 444 } 436 445 437 446 static inline void rc_transmit(struct riscom_board const * bp)
+10 -9
drivers/char/rocket.c
··· 325 325 { 326 326 unsigned int CharNStat; 327 327 int ToRecv, wRecv, space = 0, count; 328 - unsigned char *cbuf; 329 - char *fbuf; 328 + unsigned char *cbuf, *chead; 329 + char *fbuf, *fhead; 330 330 struct tty_ldisc *ld; 331 331 332 332 ld = tty_ldisc_ref(tty); 333 333 334 334 ToRecv = sGetRxCnt(cp); 335 - if (ld) 336 - space = ld->receive_room(tty); 335 + space = tty->receive_room; 337 336 if (space > 2 * TTY_FLIPBUF_SIZE) 338 337 space = 2 * TTY_FLIPBUF_SIZE; 339 - cbuf = tty->flip.char_buf; 340 - fbuf = tty->flip.flag_buf; 341 338 count = 0; 342 339 #ifdef ROCKET_DEBUG_INTR 343 340 printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space); ··· 347 350 if (ToRecv > space) 348 351 ToRecv = space; 349 352 353 + ToRecv = tty_prepare_flip_string_flags(tty, &chead, &fhead, ToRecv); 350 354 if (ToRecv <= 0) 351 355 goto done; 356 + 357 + cbuf = chead; 358 + fbuf = fhead; 352 359 353 360 /* 354 361 * if status indicates there are errored characters in the ··· 400 399 else if (CharNStat & STMRCVROVRH) 401 400 *fbuf++ = TTY_OVERRUN; 402 401 else 403 - *fbuf++ = 0; 402 + *fbuf++ = TTY_NORMAL; 404 403 *cbuf++ = CharNStat & 0xff; 405 404 count++; 406 405 ToRecv--; ··· 427 426 sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); 428 427 if (ToRecv & 1) 429 428 cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); 430 - memset(fbuf, 0, ToRecv); 429 + memset(fbuf, TTY_NORMAL, ToRecv); 431 430 cbuf += ToRecv; 432 431 fbuf += ToRecv; 433 432 count += ToRecv; 434 433 } 435 434 /* Push the data up to the tty layer */ 436 - ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); 435 + ld->receive_buf(tty, cbuf, fbuf, count); 437 436 done: 438 437 tty_ldisc_deref(ld); 439 438 }
+3 -2
drivers/char/selection.c
··· 275 275 int paste_selection(struct tty_struct *tty) 276 276 { 277 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 280 struct tty_ldisc *ld; 280 281 DECLARE_WAITQUEUE(wait, current); 281 282 ··· 294 293 continue; 295 294 } 296 295 count = sel_buffer_lth - pasted; 297 - count = min(count, tty->ldisc.receive_room(tty)); 296 + count = min(count, tty->receive_room); 298 297 tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count); 299 298 pasted += count; 300 299 }
+1 -7
drivers/char/ser_a2232.c
··· 194 194 */ 195 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 197 #if 0 203 198 switch(err) { 204 199 case TTY_BREAK: ··· 207 212 } 208 213 #endif 209 214 210 - *tty->flip.flag_buf_ptr++ = err; 211 - *tty->flip.char_buf_ptr++ = ch; 215 + tty_insert_flip_char(tty, ch, err); 212 216 tty_flip_buffer_push(tty); 213 217 } 214 218
+10 -25
drivers/char/serial167.c
··· 422 422 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; 423 423 return IRQ_HANDLED; 424 424 } 425 - if (tty->flip.count < TTY_FLIPBUF_SIZE){ 426 - tty->flip.count++; 425 + if (tty_buffer_request_room(tty, 1) != 0){ 427 426 if (err & info->read_status_mask){ 428 427 if(err & CyBREAK){ 429 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 430 - *tty->flip.char_buf_ptr++ = data; 428 + tty_insert_flip_char(tty, data, TTY_BREAK); 431 429 if (info->flags & ASYNC_SAK){ 432 430 do_SAK(tty); 433 431 } 434 432 }else if(err & CyFRAME){ 435 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 436 - *tty->flip.char_buf_ptr++ = data; 433 + tty_insert_flip_char(tty, data, TTY_FRAME); 437 434 }else if(err & CyPARITY){ 438 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 439 - *tty->flip.char_buf_ptr++ = data; 435 + tty_insert_flip_char(tty, data, TTY_PARITY); 440 436 }else if(err & CyOVERRUN){ 441 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 442 - *tty->flip.char_buf_ptr++ = 0; 437 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 443 438 /* 444 439 If the flip buffer itself is 445 440 overflowing, we still loose 446 441 the next incoming character. 447 442 */ 448 - if(tty->flip.count < TTY_FLIPBUF_SIZE){ 449 - tty->flip.count++; 450 - *tty->flip.flag_buf_ptr++ = TTY_NORMAL; 451 - *tty->flip.char_buf_ptr++ = data; 452 - } 443 + tty_insert_flip_char(tty, data, TTY_NORMAL); 444 + } 453 445 /* These two conditions may imply */ 454 446 /* a normal read should be done. */ 455 447 /* else if(data & CyTIMEOUT) */ 456 448 /* else if(data & CySPECHAR) */ 457 449 }else{ 458 - *tty->flip.flag_buf_ptr++ = 0; 459 - *tty->flip.char_buf_ptr++ = 0; 450 + tty_insert_flip_char(tty, 0, TTY_NORMAL); 460 451 } 461 452 }else{ 462 - *tty->flip.flag_buf_ptr++ = 0; 463 - *tty->flip.char_buf_ptr++ = 0; 453 + tty_insert_flip_char(tty, data, TTY_NORMAL); 464 454 } 465 455 }else{ 466 456 /* there was a software buffer overrun ··· 682 692 #endif 683 693 while(char_count--){ 684 694 data = base_addr[CyRDR]; 685 - if (tty->flip.count >= TTY_FLIPBUF_SIZE){ 686 - continue; 687 - } 688 - tty->flip.count++; 689 - *tty->flip.flag_buf_ptr++ = TTY_NORMAL; 690 - *tty->flip.char_buf_ptr++ = data; 695 + tty_insert_flip_char(tty, data, TTY_NORMAL); 691 696 #ifdef CYCLOM_16Y_HACK 692 697 udelay(10L); 693 698 #endif
+14 -24
drivers/char/specialix.c
··· 85 85 #include <linux/interrupt.h> 86 86 #include <linux/errno.h> 87 87 #include <linux/tty.h> 88 + #include <linux/tty_flip.h> 88 89 #include <linux/mm.h> 89 90 #include <linux/serial.h> 90 91 #include <linux/fcntl.h> ··· 666 665 struct specialix_port *port; 667 666 struct tty_struct *tty; 668 667 unsigned char status; 669 - unsigned char ch; 668 + unsigned char ch, flag; 670 669 671 670 func_enter(); 672 671 ··· 677 676 return; 678 677 } 679 678 tty = port->tty; 680 - dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n", 681 - port, tty->flip.count, TTY_FLIPBUF_SIZE); 682 679 683 680 status = sx_in(bp, CD186x_RCSR); 684 681 ··· 690 691 691 692 /* This flip buffer check needs to be below the reading of the 692 693 status register to reset the chip's IRQ.... */ 693 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 694 + if (tty_buffer_request_room(tty, 1) == 0) { 694 695 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", 695 696 board_No(bp), port_No(port)); 696 697 func_exit(); ··· 711 712 } else if (status & RCSR_BREAK) { 712 713 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", 713 714 board_No(bp), port_No(port)); 714 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 715 + flag = TTY_BREAK; 715 716 if (port->flags & ASYNC_SAK) 716 717 do_SAK(tty); 717 718 718 719 } else if (status & RCSR_PE) 719 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 720 + flag = TTY_PARITY; 720 721 721 722 else if (status & RCSR_FE) 722 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 723 + flag = TTY_FRAME; 723 724 724 725 else if (status & RCSR_OE) 725 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 726 + flag = TTY_OVERRUN; 726 727 727 728 else 728 - *tty->flip.flag_buf_ptr++ = 0; 729 + flag = TTY_NORMAL; 729 730 730 - *tty->flip.char_buf_ptr++ = ch; 731 - tty->flip.count++; 732 - schedule_delayed_work(&tty->flip.work, 1); 733 - 731 + if(tty_insert_flip_char(tty, ch, flag)) 732 + tty_flip_buffer_push(tty); 734 733 func_exit(); 735 734 } 736 735 ··· 752 755 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); 753 756 port->hits[count > 8 ? 9 : count]++; 754 757 755 - while (count--) { 756 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 757 - printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n", 758 - board_No(bp), port_No(port)); 759 - break; 760 - } 761 - *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR); 762 - *tty->flip.flag_buf_ptr++ = 0; 763 - tty->flip.count++; 764 - } 765 - schedule_delayed_work(&tty->flip.work, 1); 758 + tty_buffer_request_room(tty, count); 766 759 760 + while (count--) 761 + tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); 762 + tty_flip_buffer_push(tty); 767 763 func_exit(); 768 764 } 769 765
+15 -35
drivers/char/stallion.c
··· 2901 2901 if (portp->tty != (struct tty_struct *) NULL) { 2902 2902 if (portp->tty->driver_data == portp) { 2903 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 2906 if (portp->tty->termios != (struct termios *) NULL) { 2906 2907 portp->stats.cflags = portp->tty->termios->c_cflag; 2907 2908 portp->stats.iflags = portp->tty->termios->c_iflag; ··· 4046 4045 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { 4047 4046 outb((RDCR + portp->uartaddr), ioaddr); 4048 4047 len = inb(ioaddr + EREG_DATA); 4049 - if ((tty == (struct tty_struct *) NULL) || 4050 - (tty->flip.char_buf_ptr == (char *) NULL) || 4051 - ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) { 4048 + if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { 4052 4049 len = MIN(len, sizeof(stl_unwanted)); 4053 4050 outb((RDSR + portp->uartaddr), ioaddr); 4054 4051 insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); ··· 4055 4056 } else { 4056 4057 len = MIN(len, buflen); 4057 4058 if (len > 0) { 4059 + unsigned char *ptr; 4058 4060 outb((RDSR + portp->uartaddr), ioaddr); 4059 - insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len); 4060 - memset(tty->flip.flag_buf_ptr, 0, len); 4061 - tty->flip.flag_buf_ptr += len; 4062 - tty->flip.char_buf_ptr += len; 4063 - tty->flip.count += len; 4061 + tty_prepare_flip_string(tty, &ptr, len); 4062 + insb((ioaddr + EREG_DATA), ptr, len); 4064 4063 tty_schedule_flip(tty); 4065 4064 portp->stats.rxtotal += len; 4066 4065 } ··· 4082 4085 portp->stats.txxoff++; 4083 4086 goto stl_rxalldone; 4084 4087 } 4085 - if ((tty != (struct tty_struct *) NULL) && 4086 - ((portp->rxignoremsk & status) == 0)) { 4088 + if (tty != NULL && (portp->rxignoremsk & status) == 0) { 4087 4089 if (portp->rxmarkmsk & status) { 4088 4090 if (status & ST_BREAK) { 4089 4091 status = TTY_BREAK; ··· 4102 4106 } else { 4103 4107 status = 0; 4104 4108 } 4105 - if (tty->flip.char_buf_ptr != (char *) NULL) { 4106 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 4107 - *tty->flip.flag_buf_ptr++ = status; 4108 - *tty->flip.char_buf_ptr++ = ch; 4109 - tty->flip.count++; 4110 - } 4111 - tty_schedule_flip(tty); 4112 - } 4109 + tty_insert_flip_char(tty, ch, status); 4110 + tty_schedule_flip(tty); 4113 4111 } 4114 4112 } else { 4115 4113 printk("STALLION: bad RX interrupt ack value=%x\n", ioack); ··· 5002 5012 len = inb(ioaddr + XP_DATA) + 1; 5003 5013 5004 5014 if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { 5005 - if ((tty == (struct tty_struct *) NULL) || 5006 - (tty->flip.char_buf_ptr == (char *) NULL) || 5007 - ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) { 5015 + if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { 5008 5016 len = MIN(len, sizeof(stl_unwanted)); 5009 5017 outb(GRXFIFO, (ioaddr + XP_ADDR)); 5010 5018 insb((ioaddr + XP_DATA), &stl_unwanted[0], len); ··· 5011 5023 } else { 5012 5024 len = MIN(len, buflen); 5013 5025 if (len > 0) { 5026 + unsigned char *ptr; 5014 5027 outb(GRXFIFO, (ioaddr + XP_ADDR)); 5015 - insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len); 5016 - memset(tty->flip.flag_buf_ptr, 0, len); 5017 - tty->flip.flag_buf_ptr += len; 5018 - tty->flip.char_buf_ptr += len; 5019 - tty->flip.count += len; 5028 + tty_prepare_flip_string(tty, &ptr, len); 5029 + insb((ioaddr + XP_DATA), ptr, len); 5020 5030 tty_schedule_flip(tty); 5021 5031 portp->stats.rxtotal += len; 5022 5032 } ··· 5082 5096 status = 0; 5083 5097 } 5084 5098 5085 - if (tty->flip.char_buf_ptr != (char *) NULL) { 5086 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 5087 - *tty->flip.flag_buf_ptr++ = status; 5088 - *tty->flip.char_buf_ptr++ = ch; 5089 - tty->flip.count++; 5090 - } 5091 - tty_schedule_flip(tty); 5092 - } 5099 + tty_insert_flip_char(tty, ch, status); 5100 + tty_schedule_flip(tty); 5093 5101 5094 5102 if (status == 0) 5095 5103 portp->stats.rxtotal++;
+4 -9
drivers/char/sx.c
··· 1085 1085 int rx_op; 1086 1086 struct tty_struct *tty; 1087 1087 int copied=0; 1088 + unsigned char *rp; 1088 1089 1089 1090 func_enter2 (); 1090 1091 tty = port->gs.tty; ··· 1096 1095 sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); 1097 1096 1098 1097 /* Don't copy more bytes than there is room for in the buffer */ 1099 - if (tty->flip.count + c > TTY_FLIPBUF_SIZE) 1100 - c = TTY_FLIPBUF_SIZE - tty->flip.count; 1098 + 1099 + c = tty_prepare_flip_string(tty, &rp, c); 1101 1100 1102 1101 sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); 1103 1102 ··· 1112 1111 sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, 1113 1112 read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op), 1114 1113 CHAN_OFFSET(port, hi_rxbuf)); 1115 - memcpy_fromio (tty->flip.char_buf_ptr, 1114 + memcpy_fromio (rp, 1116 1115 port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c); 1117 - memset(tty->flip.flag_buf_ptr, TTY_NORMAL, c); 1118 - 1119 - /* Update the kernel buffer end */ 1120 - tty->flip.count += c; 1121 - tty->flip.char_buf_ptr += c; 1122 - tty->flip.flag_buf_ptr += c; 1123 1116 1124 1117 /* This one last. ( Not essential.) 1125 1118 It allows the card to start putting more data into the buffer!
+16 -27
drivers/char/synclink.c
··· 1467 1467 { 1468 1468 int Fifocount; 1469 1469 u16 status; 1470 + int work = 0; 1470 1471 unsigned char DataByte; 1471 1472 struct tty_struct *tty = info->tty; 1472 1473 struct mgsl_icount *icount = &info->icount; ··· 1488 1487 /* flush the receive FIFO */ 1489 1488 1490 1489 while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { 1490 + int flag; 1491 + 1491 1492 /* read one byte from RxFIFO */ 1492 1493 outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), 1493 1494 info->io_base + CCAR ); ··· 1501 1498 RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) 1502 1499 usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); 1503 1500 1504 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 1505 - continue; 1506 - 1507 - *tty->flip.char_buf_ptr = DataByte; 1508 1501 icount->rx++; 1509 1502 1510 - *tty->flip.flag_buf_ptr = 0; 1503 + flag = 0; 1511 1504 if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + 1512 1505 RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { 1513 1506 printk("rxerr=%04X\n",status); ··· 1529 1530 status &= info->read_status_mask; 1530 1531 1531 1532 if (status & RXSTATUS_BREAK_RECEIVED) { 1532 - *tty->flip.flag_buf_ptr = TTY_BREAK; 1533 + flag = TTY_BREAK; 1533 1534 if (info->flags & ASYNC_SAK) 1534 1535 do_SAK(tty); 1535 1536 } else if (status & RXSTATUS_PARITY_ERROR) 1536 - *tty->flip.flag_buf_ptr = TTY_PARITY; 1537 + flag = TTY_PARITY; 1537 1538 else if (status & RXSTATUS_FRAMING_ERROR) 1538 - *tty->flip.flag_buf_ptr = TTY_FRAME; 1539 - if (status & RXSTATUS_OVERRUN) { 1540 - /* Overrun is special, since it's 1541 - * reported immediately, and doesn't 1542 - * affect the current character 1543 - */ 1544 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 1545 - tty->flip.count++; 1546 - tty->flip.flag_buf_ptr++; 1547 - tty->flip.char_buf_ptr++; 1548 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 1549 - } 1550 - } 1539 + flag = TTY_FRAME; 1551 1540 } /* end of if (error) */ 1552 - 1553 - tty->flip.flag_buf_ptr++; 1554 - tty->flip.char_buf_ptr++; 1555 - tty->flip.count++; 1541 + tty_insert_flip_char(tty, DataByte, flag); 1542 + if (status & RXSTATUS_OVERRUN) { 1543 + /* Overrun is special, since it's 1544 + * reported immediately, and doesn't 1545 + * affect the current character 1546 + */ 1547 + work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); 1548 + } 1556 1549 } 1557 1550 1558 1551 if ( debug_level >= DEBUG_LEVEL_ISR ) { 1559 - printk("%s(%d):mgsl_isr_receive_data flip count=%d\n", 1560 - __FILE__,__LINE__,tty->flip.count); 1561 1552 printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", 1562 1553 __FILE__,__LINE__,icount->rx,icount->brk, 1563 1554 icount->parity,icount->frame,icount->overrun); 1564 1555 } 1565 1556 1566 - if ( tty->flip.count ) 1557 + if(work) 1567 1558 tty_flip_buffer_push(tty); 1568 1559 } 1569 1560
+10 -24
drivers/char/synclinkmp.c
··· 2196 2196 if ( tty ) { 2197 2197 if (!(status & info->ignore_status_mask1)) { 2198 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 2200 if (info->flags & ASYNC_SAK) 2201 2201 do_SAK(tty); 2202 2202 } ··· 2240 2240 2241 2241 while((status = read_reg(info,CST0)) & BIT0) 2242 2242 { 2243 + int flag = 0; 2244 + int over = 0; 2243 2245 DataByte = read_reg(info,TRB); 2244 - 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 2246 2253 2247 icount->rx++; 2254 2248 ··· 2266 2272 2267 2273 if ( tty ) { 2268 2274 if (status & PE) 2269 - *tty->flip.flag_buf_ptr = TTY_PARITY; 2275 + flag = TTY_PARITY; 2270 2276 else if (status & FRME) 2271 - *tty->flip.flag_buf_ptr = TTY_FRAME; 2277 + flag = TTY_FRAME; 2272 2278 if (status & OVRN) { 2273 2279 /* Overrun is special, since it's 2274 2280 * reported immediately, and doesn't 2275 2281 * affect the current character 2276 2282 */ 2277 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 2278 - tty->flip.count++; 2279 - tty->flip.flag_buf_ptr++; 2280 - tty->flip.char_buf_ptr++; 2281 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 2282 - } 2283 + over = 1; 2283 2284 } 2284 2285 } 2285 2286 } /* end of if (error) */ 2286 2287 2287 2288 if ( tty ) { 2288 - tty->flip.flag_buf_ptr++; 2289 - tty->flip.char_buf_ptr++; 2290 - tty->flip.count++; 2289 + tty_insert_flip_char(tty, DataByte, flag); 2290 + if (over) 2291 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 2291 2292 } 2292 2293 } 2293 2294 2294 2295 if ( debug_level >= DEBUG_LEVEL_ISR ) { 2295 - printk("%s(%d):%s isr_rxrdy() flip count=%d\n", 2296 - __FILE__,__LINE__,info->device_name, 2297 - tty ? tty->flip.count : 0); 2298 2296 printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", 2299 2297 __FILE__,__LINE__,info->device_name, 2300 2298 icount->rx,icount->brk,icount->parity, 2301 2299 icount->frame,icount->overrun); 2302 2300 } 2303 2301 2304 - if ( tty && tty->flip.count ) 2302 + if ( tty ) 2305 2303 tty_flip_buffer_push(tty); 2306 2304 } 2307 2305
+233 -31
drivers/char/tty_io.c
··· 166 166 return tty; 167 167 } 168 168 169 + static void tty_buffer_free_all(struct tty_struct *); 170 + 169 171 static inline void free_tty_struct(struct tty_struct *tty) 170 172 { 171 173 kfree(tty->write_buf); 174 + tty_buffer_free_all(tty); 172 175 kfree(tty); 173 176 } 174 177 ··· 232 229 #endif 233 230 return 0; 234 231 } 232 + 233 + /* 234 + * Tty buffer allocation management 235 + */ 236 + 237 + static void tty_buffer_free_all(struct tty_struct *tty) 238 + { 239 + struct tty_buffer *thead; 240 + while((thead = tty->buf.head) != NULL) { 241 + tty->buf.head = thead->next; 242 + kfree(thead); 243 + } 244 + while((thead = tty->buf.free) != NULL) { 245 + tty->buf.free = thead->next; 246 + kfree(thead); 247 + } 248 + tty->buf.tail = NULL; 249 + } 250 + 251 + static void tty_buffer_init(struct tty_struct *tty) 252 + { 253 + tty->buf.head = NULL; 254 + tty->buf.tail = NULL; 255 + tty->buf.free = NULL; 256 + } 257 + 258 + static struct tty_buffer *tty_buffer_alloc(size_t size) 259 + { 260 + struct tty_buffer *p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); 261 + if(p == NULL) 262 + return NULL; 263 + p->used = 0; 264 + p->size = size; 265 + p->next = NULL; 266 + p->char_buf_ptr = (char *)(p->data); 267 + p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; 268 + /* printk("Flip create %p\n", p); */ 269 + return p; 270 + } 271 + 272 + /* Must be called with the tty_read lock held. This needs to acquire strategy 273 + code to decide if we should kfree or relink a given expired buffer */ 274 + 275 + static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) 276 + { 277 + /* Dumb strategy for now - should keep some stats */ 278 + /* printk("Flip dispose %p\n", b); */ 279 + if(b->size >= 512) 280 + kfree(b); 281 + else { 282 + b->next = tty->buf.free; 283 + tty->buf.free = b; 284 + } 285 + } 286 + 287 + static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) 288 + { 289 + struct tty_buffer **tbh = &tty->buf.free; 290 + while((*tbh) != NULL) { 291 + struct tty_buffer *t = *tbh; 292 + if(t->size >= size) { 293 + *tbh = t->next; 294 + t->next = NULL; 295 + t->used = 0; 296 + /* DEBUG ONLY */ 297 + memset(t->data, '*', size); 298 + /* printk("Flip recycle %p\n", t); */ 299 + return t; 300 + } 301 + tbh = &((*tbh)->next); 302 + } 303 + /* Round the buffer size out */ 304 + size = (size + 0xFF) & ~ 0xFF; 305 + return tty_buffer_alloc(size); 306 + /* Should possibly check if this fails for the largest buffer we 307 + have queued and recycle that ? */ 308 + } 309 + 310 + int tty_buffer_request_room(struct tty_struct *tty, size_t size) 311 + { 312 + struct tty_buffer *b = tty->buf.head, *n; 313 + int left = 0; 314 + 315 + /* OPTIMISATION: We could keep a per tty "zero" sized buffer to 316 + remove this conditional if its worth it. This would be invisible 317 + to the callers */ 318 + if(b != NULL) 319 + left = b->size - b->used; 320 + if(left >= size) 321 + return size; 322 + /* This is the slow path - looking for new buffers to use */ 323 + n = tty_buffer_find(tty, size); 324 + if(n == NULL) 325 + return left; 326 + n->next = b; 327 + if(b != NULL) 328 + b->next = n; 329 + else 330 + tty->buf.head = n; 331 + tty->buf.tail = n; 332 + return size; 333 + } 334 + 335 + EXPORT_SYMBOL_GPL(tty_buffer_request_room); 336 + 337 + int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size) 338 + { 339 + int copied = 0; 340 + do { 341 + int space = tty_buffer_request_room(tty, size - copied); 342 + struct tty_buffer *tb = tty->buf.tail; 343 + /* If there is no space then tb may be NULL */ 344 + if(unlikely(space == 0)) 345 + break; 346 + memcpy(tb->char_buf_ptr + tb->used, chars, space); 347 + memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); 348 + tb->used += space; 349 + copied += space; 350 + chars += space; 351 + /* printk("Flip insert %d.\n", space); */ 352 + } 353 + /* There is a small chance that we need to split the data over 354 + several buffers. If this is the case we must loop */ 355 + while (unlikely(size > copied)); 356 + return copied; 357 + } 358 + 359 + EXPORT_SYMBOL_GPL(tty_insert_flip_string); 360 + 361 + int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size) 362 + { 363 + int copied = 0; 364 + do { 365 + int space = tty_buffer_request_room(tty, size - copied); 366 + struct tty_buffer *tb = tty->buf.tail; 367 + /* If there is no space then tb may be NULL */ 368 + if(unlikely(space == 0)) 369 + break; 370 + memcpy(tb->char_buf_ptr + tb->used, chars, space); 371 + memcpy(tb->flag_buf_ptr + tb->used, flags, space); 372 + tb->used += space; 373 + copied += space; 374 + chars += space; 375 + flags += space; 376 + } 377 + /* There is a small chance that we need to split the data over 378 + several buffers. If this is the case we must loop */ 379 + while (unlikely(size > copied)); 380 + return copied; 381 + } 382 + 383 + EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); 384 + 385 + 386 + /* 387 + * Prepare a block of space in the buffer for data. Returns the length 388 + * available and buffer pointer to the space which is now allocated and 389 + * accounted for as ready for normal characters. This is used for drivers 390 + * that need their own block copy routines into the buffer. There is no 391 + * guarantee the buffer is a DMA target! 392 + */ 393 + 394 + int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) 395 + { 396 + int space = tty_buffer_request_room(tty, size); 397 + struct tty_buffer *tb = tty->buf.tail; 398 + *chars = tb->char_buf_ptr + tb->used; 399 + memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); 400 + tb->used += space; 401 + return space; 402 + } 403 + 404 + EXPORT_SYMBOL_GPL(tty_prepare_flip_string); 405 + 406 + /* 407 + * Prepare a block of space in the buffer for data. Returns the length 408 + * available and buffer pointer to the space which is now allocated and 409 + * accounted for as ready for characters. This is used for drivers 410 + * that need their own block copy routines into the buffer. There is no 411 + * guarantee the buffer is a DMA target! 412 + */ 413 + 414 + int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) 415 + { 416 + int space = tty_buffer_request_room(tty, size); 417 + struct tty_buffer *tb = tty->buf.tail; 418 + *chars = tb->char_buf_ptr + tb->used; 419 + *flags = tb->flag_buf_ptr + tb->used; 420 + tb->used += space; 421 + return space; 422 + } 423 + 424 + EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); 425 + 426 + 235 427 236 428 /* 237 429 * This is probably overkill for real world processors but ··· 690 492 if (ld == NULL) 691 493 return -EINVAL; 692 494 495 + /* 496 + * No more input please, we are switching. The new ldisc 497 + * will update this value in the ldisc open function 498 + */ 499 + 500 + tty->receive_room = 0; 501 + 502 + /* 503 + * Problem: What do we do if this blocks ? 504 + */ 505 + 693 506 tty_wait_until_sent(tty, 0); 694 507 695 508 if (tty->ldisc.num == ldisc) { ··· 769 560 * we say so later on. 770 561 */ 771 562 772 - work = cancel_delayed_work(&tty->flip.work); 563 + work = cancel_delayed_work(&tty->buf.work); 773 564 /* 774 - * Wait for ->hangup_work and ->flip.work handlers to terminate 565 + * Wait for ->hangup_work and ->buf.work handlers to terminate 775 566 */ 776 567 777 568 flush_scheduled_work(); ··· 825 616 /* Restart it in case no characters kick it off. Safe if 826 617 already running */ 827 618 if (work) 828 - schedule_delayed_work(&tty->flip.work, 1); 619 + schedule_delayed_work(&tty->buf.work, 1); 829 620 return retval; 830 621 } 831 622 ··· 1930 1721 */ 1931 1722 clear_bit(TTY_LDISC, &tty->flags); 1932 1723 clear_bit(TTY_DONT_FLIP, &tty->flags); 1933 - cancel_delayed_work(&tty->flip.work); 1724 + cancel_delayed_work(&tty->buf.work); 1934 1725 1935 1726 /* 1936 - * Wait for ->hangup_work and ->flip.work handlers to terminate 1727 + * Wait for ->hangup_work and ->buf.work handlers to terminate 1937 1728 */ 1938 1729 1939 1730 flush_scheduled_work(); ··· 2727 2518 2728 2519 /* 2729 2520 * This routine is called out of the software interrupt to flush data 2730 - * from the flip buffer to the line discipline. 2521 + * from the buffer chain to the line discipline. 2731 2522 */ 2732 2523 2733 2524 static void flush_to_ldisc(void *private_) 2734 2525 { 2735 2526 struct tty_struct *tty = (struct tty_struct *) private_; 2736 - unsigned char *cp; 2737 - char *fp; 2738 - int count; 2739 2527 unsigned long flags; 2740 2528 struct tty_ldisc *disc; 2529 + struct tty_buffer *tbuf; 2741 2530 2742 2531 disc = tty_ldisc_ref(tty); 2743 2532 if (disc == NULL) /* !TTY_LDISC */ ··· 2745 2538 /* 2746 2539 * Do it after the next timer tick: 2747 2540 */ 2748 - schedule_delayed_work(&tty->flip.work, 1); 2541 + schedule_delayed_work(&tty->buf.work, 1); 2749 2542 goto out; 2750 2543 } 2751 2544 spin_lock_irqsave(&tty->read_lock, flags); 2752 - if (tty->flip.buf_num) { 2753 - cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; 2754 - fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; 2755 - tty->flip.buf_num = 0; 2756 - tty->flip.char_buf_ptr = tty->flip.char_buf; 2757 - tty->flip.flag_buf_ptr = tty->flip.flag_buf; 2758 - } else { 2759 - cp = tty->flip.char_buf; 2760 - fp = tty->flip.flag_buf; 2761 - tty->flip.buf_num = 1; 2762 - tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE; 2763 - tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; 2545 + while((tbuf = tty->buf.head) != NULL) { 2546 + tty->buf.head = tbuf->next; 2547 + spin_unlock_irqrestore(&tty->read_lock, flags); 2548 + /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ 2549 + disc->receive_buf(tty, tbuf->char_buf_ptr, 2550 + tbuf->flag_buf_ptr, 2551 + tbuf->used); 2552 + spin_lock_irqsave(&tty->read_lock, flags); 2553 + tty_buffer_free(tty, tbuf); 2764 2554 } 2765 - count = tty->flip.count; 2766 - tty->flip.count = 0; 2555 + tty->buf.tail = NULL; 2767 2556 spin_unlock_irqrestore(&tty->read_lock, flags); 2768 - 2769 - disc->receive_buf(tty, cp, fp, count); 2770 2557 out: 2771 2558 tty_ldisc_deref(disc); 2772 2559 } ··· 2855 2654 if (tty->low_latency) 2856 2655 flush_to_ldisc((void *) tty); 2857 2656 else 2858 - schedule_delayed_work(&tty->flip.work, 1); 2657 + schedule_delayed_work(&tty->buf.work, 1); 2859 2658 } 2860 2659 2861 2660 EXPORT_SYMBOL(tty_flip_buffer_push); 2661 + 2862 2662 2863 2663 /* 2864 2664 * This subroutine initializes a tty structure. ··· 2871 2669 tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); 2872 2670 tty->pgrp = -1; 2873 2671 tty->overrun_time = jiffies; 2874 - tty->flip.char_buf_ptr = tty->flip.char_buf; 2875 - tty->flip.flag_buf_ptr = tty->flip.flag_buf; 2876 - INIT_WORK(&tty->flip.work, flush_to_ldisc, tty); 2877 - init_MUTEX(&tty->flip.pty_sem); 2672 + tty->buf.head = tty->buf.tail = NULL; 2673 + tty_buffer_init(tty); 2674 + INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); 2675 + init_MUTEX(&tty->buf.pty_sem); 2878 2676 init_MUTEX(&tty->termios_sem); 2879 2677 init_waitqueue_head(&tty->write_wait); 2880 2678 init_waitqueue_head(&tty->read_wait);
+1 -2
drivers/char/viocons.c
··· 993 993 * Don't attempt to copy more data into the buffer than we 994 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 997 printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); 998 998 break; 999 999 } 1000 - tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL); 1001 1000 } 1002 1001 1003 1002 /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */
+2 -14
drivers/char/vme_scc.c
··· 434 434 SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); 435 435 return IRQ_HANDLED; 436 436 } 437 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 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 - } 437 + tty_insert_flip_char(tty, ch, 0); 444 438 445 439 /* Check if another character is already ready; in that case, the 446 440 * spcond_int() function must be used, because this character may have an ··· 481 487 else 482 488 err = 0; 483 489 484 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 485 - *tty->flip.char_buf_ptr = ch; 486 - *tty->flip.flag_buf_ptr = err; 487 - tty->flip.flag_buf_ptr++; 488 - tty->flip.char_buf_ptr++; 489 - tty->flip.count++; 490 - } 490 + tty_insert_flip_char(tty, ch, err); 491 491 492 492 /* ++TeSche: *All* errors have to be cleared manually, 493 493 * else the condition persists for the next chars
+1 -12
drivers/input/serio/serport.c
··· 96 96 init_waitqueue_head(&serport->wait); 97 97 98 98 tty->disc_data = serport; 99 + tty->receive_room = 256; 99 100 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 100 101 101 102 return 0; ··· 138 137 139 138 out: 140 139 spin_unlock_irqrestore(&serport->lock, flags); 141 - } 142 - 143 - /* 144 - * serport_ldisc_room() reports how much room we do have for receiving data. 145 - * Although we in fact have infinite room, we need to specify some value 146 - * here, and 256 seems to be reasonable. 147 - */ 148 - 149 - static int serport_ldisc_room(struct tty_struct *tty) 150 - { 151 - return 256; 152 140 } 153 141 154 142 /* ··· 227 237 .read = serport_ldisc_read, 228 238 .ioctl = serport_ldisc_ioctl, 229 239 .receive_buf = serport_ldisc_receive, 230 - .receive_room = serport_ldisc_room, 231 240 .write_wakeup = serport_ldisc_write_wakeup 232 241 }; 233 242
+1 -2
drivers/isdn/capi/capi.c
··· 463 463 #endif 464 464 goto bad; 465 465 } 466 - if (ld->receive_room && 467 - ld->receive_room(mp->tty) < datalen) { 466 + if (mp->tty->receive_room < datalen) { 468 467 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) 469 468 printk(KERN_DEBUG "capi: no room in tty\n"); 470 469 #endif
+112
drivers/isdn/i4l/isdn_common.c
··· 857 857 return count; 858 858 } 859 859 860 + /* 861 + * isdn_readbchan_tty() tries to get data from the read-queue. 862 + * It MUST be called with interrupts off. 863 + * 864 + * Be aware that this is not an atomic operation when sleep != 0, even though 865 + * interrupts are turned off! Well, like that we are currently only called 866 + * on behalf of a read system call on raw device files (which are documented 867 + * to be dangerous and for for debugging purpose only). The inode semaphore 868 + * takes care that this is not called for the same minor device number while 869 + * we are sleeping, but access is not serialized against simultaneous read() 870 + * from the corresponding ttyI device. Can other ugly events, like changes 871 + * of the mapping (di,ch)<->minor, happen during the sleep? --he 872 + */ 873 + int 874 + isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) 875 + { 876 + int count; 877 + int count_pull; 878 + int count_put; 879 + int dflag; 880 + struct sk_buff *skb; 881 + char last = 0; 882 + int len; 883 + 884 + if (!dev->drv[di]) 885 + return 0; 886 + if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) 887 + return 0; 888 + 889 + len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]); 890 + if(len == 0) 891 + return len; 892 + 893 + count = 0; 894 + while (len) { 895 + if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel]))) 896 + break; 897 + #ifdef CONFIG_ISDN_AUDIO 898 + if (ISDN_AUDIO_SKB_LOCK(skb)) 899 + break; 900 + ISDN_AUDIO_SKB_LOCK(skb) = 1; 901 + if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) { 902 + char *p = skb->data; 903 + unsigned long DLEmask = (1 << channel); 904 + 905 + dflag = 0; 906 + count_pull = count_put = 0; 907 + while ((count_pull < skb->len) && (len > 0)) { 908 + len--; 909 + if (dev->drv[di]->DLEflag & DLEmask) { 910 + last = DLE; 911 + dev->drv[di]->DLEflag &= ~DLEmask; 912 + } else { 913 + last = *p; 914 + if (last == DLE) { 915 + dev->drv[di]->DLEflag |= DLEmask; 916 + (ISDN_AUDIO_SKB_DLECOUNT(skb))--; 917 + } 918 + p++; 919 + count_pull++; 920 + } 921 + count_put++; 922 + } 923 + if (count_pull >= skb->len) 924 + dflag = 1; 925 + } else { 926 + #endif 927 + /* No DLE's in buff, so simply copy it */ 928 + dflag = 1; 929 + if ((count_pull = skb->len) > len) { 930 + count_pull = len; 931 + dflag = 0; 932 + } 933 + count_put = count_pull; 934 + if(count_put > 1) 935 + tty_insert_flip_string(tty, skb->data, count_put - 1); 936 + last = skb->data[count_put] - 1; 937 + len -= count_put; 938 + #ifdef CONFIG_ISDN_AUDIO 939 + } 940 + #endif 941 + count += count_put; 942 + if (dflag) { 943 + /* We got all the data in this buff. 944 + * Now we can dequeue it. 945 + */ 946 + if(cisco_hack) 947 + tty_insert_flip_char(tty, last, 0xFF); 948 + else 949 + tty_insert_flip_char(tty, last, TTY_NORMAL); 950 + #ifdef CONFIG_ISDN_AUDIO 951 + ISDN_AUDIO_SKB_LOCK(skb) = 0; 952 + #endif 953 + skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); 954 + dev_kfree_skb(skb); 955 + } else { 956 + tty_insert_flip_char(tty, last, TTY_NORMAL); 957 + /* Not yet emptied this buff, so it 958 + * must stay in the queue, for further calls 959 + * but we pull off the data we got until now. 960 + */ 961 + skb_pull(skb, count_pull); 962 + #ifdef CONFIG_ISDN_AUDIO 963 + ISDN_AUDIO_SKB_LOCK(skb) = 0; 964 + #endif 965 + } 966 + dev->drv[di]->rcvcount[channel] -= count_put; 967 + } 968 + return count; 969 + } 970 + 971 + 860 972 static __inline int 861 973 isdn_minor2drv(int minor) 862 974 {
+1
drivers/isdn/i4l/isdn_common.h
··· 37 37 extern void isdn_unexclusive_channel(int di, int ch); 38 38 extern int isdn_getnum(char **); 39 39 extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); 40 + extern int isdn_readbchan_tty(int, int, struct tty_struct *, int); 40 41 extern int isdn_get_free_channel(int, int, int, int, int, char *); 41 42 extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); 42 43 extern int register_isdn(isdn_if * i);
+36 -39
drivers/isdn/i4l/isdn_tty.c
··· 64 64 int c; 65 65 int len; 66 66 struct tty_struct *tty; 67 + char last; 67 68 68 69 if (info->online) { 69 70 if ((tty = info->tty)) { 70 71 if (info->mcr & UART_MCR_RTS) { 71 - c = TTY_FLIPBUF_SIZE - tty->flip.count; 72 72 len = skb->len 73 73 #ifdef CONFIG_ISDN_AUDIO 74 74 + ISDN_AUDIO_SKB_DLECOUNT(skb) 75 75 #endif 76 76 ; 77 + 78 + c = tty_buffer_request_room(tty, len); 77 79 if (c >= len) { 78 80 #ifdef CONFIG_ISDN_AUDIO 79 - if (ISDN_AUDIO_SKB_DLECOUNT(skb)) 80 - while (skb->len--) { 81 + if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { 82 + int l = skb->len; 83 + unsigned char *dp = skb->data; 84 + while (--l) { 81 85 if (*skb->data == DLE) 82 86 tty_insert_flip_char(tty, DLE, 0); 83 - tty_insert_flip_char(tty, *skb->data++, 0); 87 + tty_insert_flip_char(tty, *dp++, 0); 88 + } 89 + last = *dp; 84 90 } else { 85 91 #endif 86 - memcpy(tty->flip.char_buf_ptr, 87 - skb->data, len); 88 - tty->flip.count += len; 89 - tty->flip.char_buf_ptr += len; 90 - memset(tty->flip.flag_buf_ptr, 0, len); 91 - tty->flip.flag_buf_ptr += len; 92 + if(len > 1) 93 + tty_insert_flip_string(tty, skb->data, len - 1); 94 + last = skb->data[len - 1]; 92 95 #ifdef CONFIG_ISDN_AUDIO 93 96 } 94 97 #endif 95 98 if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) 96 - tty->flip.flag_buf_ptr[len - 1] = 0xff; 97 - schedule_delayed_work(&tty->flip.work, 1); 99 + tty_insert_flip_char(tty, last, 0xFF); 100 + else 101 + tty_insert_flip_char(tty, last, TTY_NORMAL); 102 + tty_flip_buffer_push(tty); 98 103 kfree_skb(skb); 99 104 return 1; 100 105 } ··· 119 114 int resched = 0; 120 115 int midx; 121 116 int i; 122 - int c; 123 117 int r; 124 118 struct tty_struct *tty; 125 119 modem_info *info; ··· 135 131 #endif 136 132 if ((tty = info->tty)) { 137 133 if (info->mcr & UART_MCR_RTS) { 138 - c = TTY_FLIPBUF_SIZE - tty->flip.count; 139 - if (c > 0) { 140 - r = isdn_readbchan(info->isdn_driver, info->isdn_channel, 141 - tty->flip.char_buf_ptr, 142 - tty->flip.flag_buf_ptr, c, NULL); 143 - /* CISCO AsyncPPP Hack */ 144 - if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) 145 - memset(tty->flip.flag_buf_ptr, 0, r); 146 - tty->flip.count += r; 147 - tty->flip.flag_buf_ptr += r; 148 - tty->flip.char_buf_ptr += r; 149 - if (r) 150 - schedule_delayed_work(&tty->flip.work, 1); 151 - } 134 + /* CISCO AsyncPPP Hack */ 135 + if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) 136 + r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); 137 + else 138 + r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); 139 + if (r) 140 + tty_flip_buffer_push(tty); 152 141 } else 153 142 r = 1; 154 143 } else ··· 246 249 } 247 250 #endif 248 251 #endif 249 - /* Try to deliver directly via tty-flip-buf if queue is empty */ 252 + /* Try to deliver directly via tty-buf if queue is empty */ 250 253 spin_lock_irqsave(&info->readlock, flags); 251 254 if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) 252 255 if (isdn_tty_try_read(info, skb)) { ··· 531 534 /* The next routine is called once from within timer-interrupt 532 535 * triggered within isdn_tty_modem_ncarrier(). It calls 533 536 * isdn_tty_modem_result() to stuff a "NO CARRIER" Message 534 - * into the tty's flip-buffer. 537 + * into the tty's buffer. 535 538 */ 536 539 static void 537 540 isdn_tty_modem_do_ncarrier(unsigned long data) ··· 2344 2347 u_long flags; 2345 2348 struct sk_buff *skb = NULL; 2346 2349 char *sp = NULL; 2350 + int l = strlen(msg); 2347 2351 2348 2352 if (!msg) { 2349 2353 printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); ··· 2357 2359 return; 2358 2360 } 2359 2361 2360 - /* use queue instead of direct flip, if online and */ 2361 - /* data is in queue or flip buffer is full */ 2362 - if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || 2363 - (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { 2364 - skb = alloc_skb(strlen(msg), GFP_ATOMIC); 2362 + /* use queue instead of direct, if online and */ 2363 + /* data is in queue or buffer is full */ 2364 + if ((info->online && tty_buffer_request_room(tty, l) < l) || 2365 + (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { 2366 + skb = alloc_skb(l, GFP_ATOMIC); 2365 2367 if (!skb) { 2366 2368 spin_unlock_irqrestore(&info->readlock, flags); 2367 2369 return; 2368 2370 } 2369 - sp = skb_put(skb, strlen(msg)); 2371 + sp = skb_put(skb, l); 2370 2372 #ifdef CONFIG_ISDN_AUDIO 2371 2373 ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; 2372 2374 ISDN_AUDIO_SKB_LOCK(skb) = 0; ··· 2390 2392 if (skb) { 2391 2393 *sp++ = c; 2392 2394 } else { 2393 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 2395 + if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) 2394 2396 break; 2395 - tty_insert_flip_char(tty, c, 0); 2396 2397 } 2397 2398 } 2398 2399 if (skb) { ··· 2399 2402 dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; 2400 2403 spin_unlock_irqrestore(&info->readlock, flags); 2401 2404 /* Schedule dequeuing */ 2402 - if ((dev->modempoll) && (info->rcvsched)) 2405 + if (dev->modempoll && info->rcvsched) 2403 2406 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); 2404 2407 2405 2408 } else { 2406 2409 spin_unlock_irqrestore(&info->readlock, flags); 2407 - schedule_delayed_work(&tty->flip.work, 1); 2410 + tty_flip_buffer_push(tty); 2408 2411 } 2409 2412 } 2410 2413
+1 -6
drivers/net/hamradio/6pack.c
··· 456 456 457 457 /* ----------------------------------------------------------------------- */ 458 458 459 - static int sixpack_receive_room(struct tty_struct *tty) 460 - { 461 - return 65536; /* We can handle an infinite amount of data. :-) */ 462 - } 463 - 464 459 /* 465 460 * Handle the 'receiver data ready' interrupt. 466 461 * This function is called by the 'tty_io' module in the kernel when ··· 666 671 667 672 /* Done. We have linked the TTY line to a channel. */ 668 673 tty->disc_data = sp; 674 + tty->receive_room = 65536; 669 675 670 676 /* Now we're ready to register. */ 671 677 if (register_netdev(dev)) ··· 798 802 .close = sixpack_close, 799 803 .ioctl = sixpack_ioctl, 800 804 .receive_buf = sixpack_receive_buf, 801 - .receive_room = sixpack_receive_room, 802 805 .write_wakeup = sixpack_write_wakeup, 803 806 }; 804 807
+1 -6
drivers/net/hamradio/mkiss.c
··· 753 753 754 754 ax->tty = tty; 755 755 tty->disc_data = ax; 756 + tty->receive_room = 65535; 756 757 757 758 if (tty->driver->flush_buffer) 758 759 tty->driver->flush_buffer(tty); ··· 941 940 tty->driver->unthrottle(tty); 942 941 } 943 942 944 - static int mkiss_receive_room(struct tty_struct *tty) 945 - { 946 - return 65536; /* We can handle an infinite amount of data. :-) */ 947 - } 948 - 949 943 /* 950 944 * Called by the driver when there's room for more data. If we have 951 945 * more packets to send, we send them here. ··· 979 983 .close = mkiss_close, 980 984 .ioctl = mkiss_ioctl, 981 985 .receive_buf = mkiss_receive_buf, 982 - .receive_room = mkiss_receive_room, 983 986 .write_wakeup = mkiss_write_wakeup 984 987 }; 985 988
+1 -17
drivers/net/irda/irtty-sir.c
··· 289 289 } 290 290 291 291 /* 292 - * Function irtty_receive_room (tty) 293 - * 294 - * Used by the TTY to find out how much data we can receive at a time 295 - * 296 - */ 297 - static int irtty_receive_room(struct tty_struct *tty) 298 - { 299 - struct sirtty_cb *priv = tty->disc_data; 300 - 301 - IRDA_ASSERT(priv != NULL, return 0;); 302 - IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return 0;); 303 - 304 - return 65536; /* We can handle an infinite amount of data. :-) */ 305 - } 306 - 307 - /* 308 292 * Function irtty_write_wakeup (tty) 309 293 * 310 294 * Called by the driver when there's room for more data. If we have ··· 518 534 519 535 dev->priv = priv; 520 536 tty->disc_data = priv; 537 + tty->receive_room = 65536; 521 538 522 539 up(&irtty_sem); 523 540 ··· 590 605 .ioctl = irtty_ioctl, 591 606 .poll = NULL, 592 607 .receive_buf = irtty_receive_buf, 593 - .receive_room = irtty_receive_room, 594 608 .write_wakeup = irtty_write_wakeup, 595 609 .owner = THIS_MODULE, 596 610 };
+1 -8
drivers/net/ppp_async.c
··· 189 189 goto out_free; 190 190 191 191 tty->disc_data = ap; 192 - 192 + tty->receive_room = 65536; 193 193 return 0; 194 194 195 195 out_free: ··· 343 343 return 0; 344 344 } 345 345 346 - static int 347 - ppp_asynctty_room(struct tty_struct *tty) 348 - { 349 - return 65535; 350 - } 351 - 352 346 /* 353 347 * This can now be called from hard interrupt level as well 354 348 * as soft interrupt level or mainline. ··· 392 398 .write = ppp_asynctty_write, 393 399 .ioctl = ppp_asynctty_ioctl, 394 400 .poll = ppp_asynctty_poll, 395 - .receive_room = ppp_asynctty_room, 396 401 .receive_buf = ppp_asynctty_receive, 397 402 .write_wakeup = ppp_asynctty_wakeup, 398 403 };
+1 -8
drivers/net/ppp_synctty.c
··· 237 237 goto out_free; 238 238 239 239 tty->disc_data = ap; 240 - 240 + tty->receive_room = 65536; 241 241 return 0; 242 242 243 243 out_free: ··· 384 384 return 0; 385 385 } 386 386 387 - static int 388 - ppp_sync_room(struct tty_struct *tty) 389 - { 390 - return 65535; 391 - } 392 - 393 387 /* 394 388 * This can now be called from hard interrupt level as well 395 389 * as soft interrupt level or mainline. ··· 433 439 .write = ppp_sync_write, 434 440 .ioctl = ppp_synctty_ioctl, 435 441 .poll = ppp_sync_poll, 436 - .receive_room = ppp_sync_room, 437 442 .receive_buf = ppp_sync_receive, 438 443 .write_wakeup = ppp_sync_wakeup, 439 444 };
+1 -10
drivers/net/slip.c
··· 651 651 ******************************************/ 652 652 653 653 654 - static int slip_receive_room(struct tty_struct *tty) 655 - { 656 - return 65536; /* We can handle an infinite amount of data. :-) */ 657 - } 658 - 659 654 /* 660 655 * Handle the 'receiver data ready' interrupt. 661 656 * This function is called by the 'tty_io' module in the kernel when ··· 864 869 sl->line = tty_devnum(tty); 865 870 sl->pid = current->pid; 866 871 867 - /* FIXME: already done before we were called - seems this can go */ 868 - if (tty->driver->flush_buffer) 869 - tty->driver->flush_buffer(tty); 870 - 871 872 if (!test_bit(SLF_INUSE, &sl->flags)) { 872 873 /* Perform the low-level SLIP initialization. */ 873 874 if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) ··· 888 897 889 898 /* Done. We have linked the TTY line to a channel. */ 890 899 rtnl_unlock(); 900 + tty->receive_room = 65536; /* We don't flow control */ 891 901 return sl->dev->base_addr; 892 902 893 903 err_free_bufs: ··· 1321 1329 .close = slip_close, 1322 1330 .ioctl = slip_ioctl, 1323 1331 .receive_buf = slip_receive_buf, 1324 - .receive_room = slip_receive_room, 1325 1332 .write_wakeup = slip_write_wakeup, 1326 1333 }; 1327 1334
+1 -1
drivers/net/wan/pc300_tty.c
··· 689 689 } 690 690 } 691 691 cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; 692 - kfree(buf); 692 + kfree((void *)buf); 693 693 buf = cpc_tty->buf_rx.first; 694 694 flg_rx = 1; 695 695 }
+1 -6
drivers/net/wan/x25_asy.c
··· 515 515 return 0; 516 516 } 517 517 518 - static int x25_asy_receive_room(struct tty_struct *tty) 519 - { 520 - return 65536; /* We can handle an infinite amount of data. :-) */ 521 - } 522 - 523 518 /* 524 519 * Handle the 'receiver data ready' interrupt. 525 520 * This function is called by the 'tty_io' module in the kernel when ··· 568 573 569 574 sl->tty = tty; 570 575 tty->disc_data = sl; 576 + tty->receive_room = 65536; 571 577 if (tty->driver->flush_buffer) { 572 578 tty->driver->flush_buffer(tty); 573 579 } ··· 775 779 .close = x25_asy_close_tty, 776 780 .ioctl = x25_asy_ioctl, 777 781 .receive_buf = x25_asy_receive_buf, 778 - .receive_room = x25_asy_receive_room, 779 782 .write_wakeup = x25_asy_write_wakeup, 780 783 }; 781 784
+3 -7
drivers/net/wireless/strip.c
··· 1675 1675 /************************************************************************/ 1676 1676 /* Receiving routines */ 1677 1677 1678 - static int strip_receive_room(struct tty_struct *tty) 1679 - { 1680 - return 0x10000; /* We can handle an infinite amount of data. :-) */ 1681 - } 1682 - 1683 1678 /* 1684 1679 * This function parses the response to the ATS300? command, 1685 1680 * extracting the radio version and serial number. ··· 2419 2424 /* 2420 2425 * Here's the order things happen: 2421 2426 * When the user runs "slattach -p strip ..." 2422 - * 1. The TTY module calls strip_open 2427 + * 1. The TTY module calls strip_open;; 2423 2428 * 2. strip_open calls strip_alloc 2424 2429 * 3. strip_alloc calls register_netdev 2425 2430 * 4. register_netdev calls strip_dev_init ··· 2647 2652 2648 2653 strip_info->tty = tty; 2649 2654 tty->disc_data = strip_info; 2655 + tty->receive_room = 65536; 2656 + 2650 2657 if (tty->driver->flush_buffer) 2651 2658 tty->driver->flush_buffer(tty); 2652 2659 ··· 2759 2762 .close = strip_close, 2760 2763 .ioctl = strip_ioctl, 2761 2764 .receive_buf = strip_receive_buf, 2762 - .receive_room = strip_receive_room, 2763 2765 .write_wakeup = strip_write_some_more, 2764 2766 }; 2765 2767
+8 -17
drivers/s390/char/con3215.c
··· 16 16 #include <linux/types.h> 17 17 #include <linux/kdev_t.h> 18 18 #include <linux/tty.h> 19 + #include <linux/tty_flip.h> 19 20 #include <linux/vt_kern.h> 20 21 #include <linux/init.h> 21 22 #include <linux/console.h> ··· 433 432 if (count > slen) 434 433 count = slen; 435 434 } else 436 - if (count >= TTY_FLIPBUF_SIZE - tty->flip.count) 437 - count = TTY_FLIPBUF_SIZE - tty->flip.count - 1; 438 435 EBCASC(raw->inbuf, count); 439 436 cchar = ctrlchar_handle(raw->inbuf, count, tty); 440 437 switch (cchar & CTRLCHAR_MASK) { ··· 440 441 break; 441 442 442 443 case CTRLCHAR_CTRL: 443 - tty->flip.count++; 444 - *tty->flip.flag_buf_ptr++ = TTY_NORMAL; 445 - *tty->flip.char_buf_ptr++ = cchar; 444 + tty_insert_flip_char(tty, cchar, TTY_NORMAL); 446 445 tty_flip_buffer_push(raw->tty); 447 446 break; 448 447 449 448 case CTRLCHAR_NONE: 450 - memcpy(tty->flip.char_buf_ptr, 451 - raw->inbuf, count); 452 449 if (count < 2 || 453 - (strncmp(raw->inbuf+count-2, "^n", 2) && 454 - strncmp(raw->inbuf+count-2, "\252n", 2)) ) { 455 - /* don't add the auto \n */ 456 - tty->flip.char_buf_ptr[count] = '\n'; 457 - memset(tty->flip.flag_buf_ptr, 458 - TTY_NORMAL, count + 1); 450 + (strncmp(raw->inbuf+count-2, "\252n", 2) && 451 + strncmp(raw->inbuf+count-2, "^n", 2)) ) { 452 + /* add the auto \n */ 453 + raw->inbuf[count] = '\n'; 459 454 count++; 460 455 } else 461 - count-=2; 462 - tty->flip.char_buf_ptr += count; 463 - tty->flip.flag_buf_ptr += count; 464 - tty->flip.count += count; 456 + count -= 2; 457 + tty_insert_flip_string(tty, raw->inbuf, count); 465 458 tty_flip_buffer_push(raw->tty); 466 459 break; 467 460 }
+8 -13
drivers/s390/char/sclp_tty.c
··· 13 13 #include <linux/kmod.h> 14 14 #include <linux/tty.h> 15 15 #include <linux/tty_driver.h> 16 + #include <linux/tty_flip.h> 16 17 #include <linux/sched.h> 17 18 #include <linux/wait.h> 18 19 #include <linux/slab.h> ··· 497 496 case CTRLCHAR_SYSRQ: 498 497 break; 499 498 case CTRLCHAR_CTRL: 500 - sclp_tty->flip.count++; 501 - *sclp_tty->flip.flag_buf_ptr++ = TTY_NORMAL; 502 - *sclp_tty->flip.char_buf_ptr++ = cchar; 499 + tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL); 503 500 tty_flip_buffer_push(sclp_tty); 504 501 break; 505 502 case CTRLCHAR_NONE: 506 503 /* send (normal) input to line discipline */ 507 - memcpy(sclp_tty->flip.char_buf_ptr, buf, count); 508 504 if (count < 2 || 509 - (strncmp ((const char *) buf + count - 2, "^n", 2) && 510 - strncmp ((const char *) buf + count - 2, "\0252n", 2))) { 511 - sclp_tty->flip.char_buf_ptr[count] = '\n'; 512 - count++; 505 + (strncmp((const char *) buf + count - 2, "^n", 2) && 506 + strncmp((const char *) buf + count - 2, "\252n", 2))) { 507 + /* add the auto \n */ 508 + tty_insert_flip_string(sclp_tty, buf, count); 509 + tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL); 513 510 } else 514 - count -= 2; 515 - memset(sclp_tty->flip.flag_buf_ptr, TTY_NORMAL, count); 516 - sclp_tty->flip.char_buf_ptr += count; 517 - sclp_tty->flip.flag_buf_ptr += count; 518 - sclp_tty->flip.count += count; 511 + tty_insert_flip_string(sclp_tty, buf, count - 2); 519 512 tty_flip_buffer_push(sclp_tty); 520 513 break; 521 514 }
+2 -10
drivers/s390/char/sclp_vt220.c
··· 16 16 #include <linux/kernel.h> 17 17 #include <linux/tty.h> 18 18 #include <linux/tty_driver.h> 19 + #include <linux/tty_flip.h> 19 20 #include <linux/sched.h> 20 21 #include <linux/errno.h> 21 22 #include <linux/mm.h> ··· 483 482 /* Send input to line discipline */ 484 483 buffer++; 485 484 count--; 486 - /* Prevent buffer overrun by discarding input. Note that 487 - * because buffer_push works asynchronously, we cannot wait 488 - * for the buffer to be emptied. */ 489 - if (count + sclp_vt220_tty->flip.count > TTY_FLIPBUF_SIZE) 490 - count = TTY_FLIPBUF_SIZE - sclp_vt220_tty->flip.count; 491 - memcpy(sclp_vt220_tty->flip.char_buf_ptr, buffer, count); 492 - memset(sclp_vt220_tty->flip.flag_buf_ptr, TTY_NORMAL, count); 493 - sclp_vt220_tty->flip.char_buf_ptr += count; 494 - sclp_vt220_tty->flip.flag_buf_ptr += count; 495 - sclp_vt220_tty->flip.count += count; 485 + tty_insert_flip_string(sclp_vt220_tty, buffer, count); 496 486 tty_flip_buffer_push(sclp_vt220_tty); 497 487 break; 498 488 }
+7 -21
drivers/s390/net/ctctty.c
··· 25 25 #include <linux/config.h> 26 26 #include <linux/module.h> 27 27 #include <linux/tty.h> 28 + #include <linux/tty_flip.h> 28 29 #include <linux/serial_reg.h> 29 30 #include <linux/interrupt.h> 30 31 #include <linux/delay.h> ··· 102 101 static int 103 102 ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) 104 103 { 105 - int c; 106 104 int len; 107 105 struct tty_struct *tty; 108 106 109 107 DBF_TEXT(trace, 5, __FUNCTION__); 110 108 if ((tty = info->tty)) { 111 109 if (info->mcr & UART_MCR_RTS) { 112 - c = TTY_FLIPBUF_SIZE - tty->flip.count; 113 110 len = skb->len; 114 - if (c >= len) { 115 - memcpy(tty->flip.char_buf_ptr, skb->data, len); 116 - memset(tty->flip.flag_buf_ptr, 0, len); 117 - tty->flip.count += len; 118 - tty->flip.char_buf_ptr += len; 119 - tty->flip.flag_buf_ptr += len; 120 - tty_flip_buffer_push(tty); 121 - kfree_skb(skb); 122 - return 1; 123 - } 111 + tty_insert_flip_string(tty, skb->data, len); 112 + tty_flip_buffer_push(tty); 113 + kfree_skb(skb); 114 + return 1; 124 115 } 125 116 } 126 117 return 0; ··· 131 138 DBF_TEXT(trace, 5, __FUNCTION__); 132 139 if ((tty = info->tty)) { 133 140 if (info->mcr & UART_MCR_RTS) { 134 - int c = TTY_FLIPBUF_SIZE - tty->flip.count; 135 141 struct sk_buff *skb; 136 142 137 - if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) { 143 + if ((skb = skb_dequeue(&info->rx_queue))) { 138 144 int len = skb->len; 139 - if (len > c) 140 - len = c; 141 - memcpy(tty->flip.char_buf_ptr, skb->data, len); 145 + tty_insert_flip_string(tty, skb->data, len); 142 146 skb_pull(skb, len); 143 - memset(tty->flip.flag_buf_ptr, 0, len); 144 - tty->flip.count += len; 145 - tty->flip.char_buf_ptr += len; 146 - tty->flip.flag_buf_ptr += len; 147 147 tty_flip_buffer_push(tty); 148 148 if (skb->len > 0) 149 149 skb_queue_head(&info->rx_queue, skb);
-9
drivers/serial/21285.c
··· 94 94 95 95 status = *CSR_UARTFLG; 96 96 while (!(status & 0x10) && max_count--) { 97 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 98 - if (tty->low_latency) 99 - tty_flip_buffer_push(tty); 100 - /* 101 - * If this failed then we will throw away the 102 - * bytes but must do so to clear interrupts 103 - */ 104 - } 105 - 106 97 ch = *CSR_UARTDR; 107 98 flag = TTY_NORMAL; 108 99 port->icount.rx++;
+8 -10
drivers/serial/68328serial.c
··· 294 294 { 295 295 struct tty_struct *tty = info->tty; 296 296 m68328_uart *uart = &uart_addr[info->line]; 297 - unsigned char ch; 297 + unsigned char ch, flag; 298 298 299 299 /* 300 300 * This do { } while() loop will get ALL chars out of Rx FIFO ··· 332 332 /* 333 333 * Make sure that we do not overflow the buffer 334 334 */ 335 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 335 + if (tty_request_buffer_room(tty, 1) == 0) { 336 336 schedule_work(&tty->flip.work); 337 337 return; 338 338 } 339 339 340 + flag = TTY_NORMAL; 341 + 340 342 if(rx & URX_PARITY_ERROR) { 341 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 343 + flag = TTY_PARITY; 342 344 status_handle(info, rx); 343 345 } else if(rx & URX_OVRUN) { 344 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 346 + flag = TTY_OVERRUN; 345 347 status_handle(info, rx); 346 348 } else if(rx & URX_FRAME_ERROR) { 347 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 349 + flag = TTY_FRAME; 348 350 status_handle(info, rx); 349 - } else { 350 - *tty->flip.flag_buf_ptr++ = 0; /* XXX */ 351 351 } 352 - *tty->flip.char_buf_ptr++ = ch; 353 - tty->flip.count++; 354 - 352 + tty_insert_flip_char(tty, ch, flag); 355 353 #ifndef CONFIG_XCOPILOT_BUGS 356 354 } while((rx = uart->urx.w) & URX_DATA_READY); 357 355 #endif
+14 -40
drivers/serial/68360serial.c
··· 394 394 static _INLINE_ void receive_chars(ser_info_t *info) 395 395 { 396 396 struct tty_struct *tty = info->tty; 397 - unsigned char ch, *cp; 397 + unsigned char ch, flag, *cp; 398 398 /*int ignored = 0;*/ 399 399 int i; 400 400 ushort status; ··· 438 438 cp = (char *)bdp->buf; 439 439 status = bdp->status; 440 440 441 - /* Check to see if there is room in the tty buffer for 442 - * the characters in our BD buffer. If not, we exit 443 - * now, leaving the BD with the characters. We'll pick 444 - * them up again on the next receive interrupt (which could 445 - * be a timeout). 446 - */ 447 - if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) 448 - break; 449 - 450 441 while (i-- > 0) { 451 442 ch = *cp++; 452 - *tty->flip.char_buf_ptr = ch; 453 443 icount->rx++; 454 444 455 445 #ifdef SERIAL_DEBUG_INTR 456 446 printk("DR%02x:%02x...", ch, status); 457 447 #endif 458 - *tty->flip.flag_buf_ptr = 0; 448 + flag = TTY_NORMAL; 449 + 459 450 if (status & (BD_SC_BR | BD_SC_FR | 460 451 BD_SC_PR | BD_SC_OV)) { 461 452 /* ··· 481 490 if (info->flags & ASYNC_SAK) 482 491 do_SAK(tty); 483 492 } else if (status & BD_SC_PR) 484 - *tty->flip.flag_buf_ptr = TTY_PARITY; 493 + flag = TTY_PARITY; 485 494 else if (status & BD_SC_FR) 486 - *tty->flip.flag_buf_ptr = TTY_FRAME; 487 - if (status & BD_SC_OV) { 488 - /* 489 - * Overrun is special, since it's 490 - * reported immediately, and doesn't 491 - * affect the current character 492 - */ 493 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 494 - tty->flip.count++; 495 - tty->flip.flag_buf_ptr++; 496 - tty->flip.char_buf_ptr++; 497 - *tty->flip.flag_buf_ptr = 498 - TTY_OVERRUN; 499 - } 500 - } 495 + flag = TTY_FRAME; 501 496 } 502 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 503 - break; 504 - 505 - tty->flip.flag_buf_ptr++; 506 - tty->flip.char_buf_ptr++; 507 - tty->flip.count++; 497 + tty_insert_flip_char(tty, ch, flag); 498 + if (status & BD_SC_OV) 499 + /* 500 + * Overrun is special, since it's 501 + * reported immediately, and doesn't 502 + * affect the current character 503 + */ 504 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 508 505 } 509 506 510 507 /* This BD is ready to be used again. Clear status. ··· 520 541 /* Check to see if there is room in the tty buffer for 521 542 * the break. If not, we exit now, losing the break. FIXME 522 543 */ 523 - if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE) 524 - return; 525 - *(tty->flip.flag_buf_ptr++) = TTY_BREAK; 526 - *(tty->flip.char_buf_ptr++) = 0; 527 - tty->flip.count++; 528 - 544 + tty_insert_flip_char(tty, 0, TTY_BREAK); 529 545 schedule_work(&tty->flip.work); 530 546 } 531 547
-13
drivers/serial/8250.c
··· 1142 1142 char flag; 1143 1143 1144 1144 do { 1145 - /* The following is not allowed by the tty layer and 1146 - unsafe. It should be fixed ASAP */ 1147 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 1148 - if (tty->low_latency) { 1149 - spin_unlock(&up->port.lock); 1150 - tty_flip_buffer_push(tty); 1151 - spin_lock(&up->port.lock); 1152 - } 1153 - /* 1154 - * If this failed then we will throw away the 1155 - * bytes but must do so to clear interrupts 1156 - */ 1157 - } 1158 1145 ch = serial_inp(up, UART_RX); 1159 1146 flag = TTY_NORMAL; 1160 1147 up->port.icount.rx++;
-9
drivers/serial/amba-pl010.c
··· 154 154 155 155 status = UART_GET_FR(port); 156 156 while (UART_RX_DATA(status) && max_count--) { 157 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 158 - if (tty->low_latency) 159 - tty_flip_buffer_push(tty); 160 - /* 161 - * If this failed then we will throw away the 162 - * bytes but must do so to clear interrupts. 163 - */ 164 - } 165 - 166 157 ch = UART_GET_CHAR(port); 167 158 flag = TTY_NORMAL; 168 159
-9
drivers/serial/amba-pl011.c
··· 120 120 121 121 status = readw(uap->port.membase + UART01x_FR); 122 122 while ((status & UART01x_FR_RXFE) == 0 && max_count--) { 123 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 124 - if (tty->low_latency) 125 - tty_flip_buffer_push(tty); 126 - /* 127 - * If this failed then we will throw away the 128 - * bytes but must do so to clear interrupts 129 - */ 130 - } 131 - 132 123 ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; 133 124 flag = TTY_NORMAL; 134 125 uap->port.icount.rx++;
+9 -22
drivers/serial/au1x00_uart.c
··· 241 241 receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) 242 242 { 243 243 struct tty_struct *tty = up->port.info->tty; 244 - unsigned char ch; 244 + unsigned char ch, flag; 245 245 int max_count = 256; 246 246 247 247 do { 248 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 249 - tty->flip.work.func((void *)tty); 250 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 251 - return; // if TTY_DONT_FLIP is set 252 - } 253 248 ch = serial_inp(up, UART_RX); 254 - *tty->flip.char_buf_ptr = ch; 255 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 249 + flag = TTY_NORMAL; 256 250 up->port.icount.rx++; 257 251 258 252 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | ··· 286 292 #endif 287 293 if (*status & UART_LSR_BI) { 288 294 DEBUG_INTR("handling break...."); 289 - *tty->flip.flag_buf_ptr = TTY_BREAK; 295 + flag = TTY_BREAK; 290 296 } else if (*status & UART_LSR_PE) 291 - *tty->flip.flag_buf_ptr = TTY_PARITY; 297 + flag = TTY_PARITY; 292 298 else if (*status & UART_LSR_FE) 293 - *tty->flip.flag_buf_ptr = TTY_FRAME; 299 + flag = TTY_FRAME; 294 300 } 295 301 if (uart_handle_sysrq_char(&up->port, ch, regs)) 296 302 goto ignore_char; 297 - if ((*status & up->port.ignore_status_mask) == 0) { 298 - tty->flip.flag_buf_ptr++; 299 - tty->flip.char_buf_ptr++; 300 - tty->flip.count++; 301 - } 302 - if ((*status & UART_LSR_OE) && 303 - tty->flip.count < TTY_FLIPBUF_SIZE) { 303 + if ((*status & up->port.ignore_status_mask) == 0) 304 + tty_insert_flip_char(tty, ch, flag); 305 + if (*status & UART_LSR_OE) 304 306 /* 305 307 * Overrun is special, since it's reported 306 308 * immediately, and doesn't affect the current 307 309 * character. 308 310 */ 309 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 310 - tty->flip.flag_buf_ptr++; 311 - tty->flip.char_buf_ptr++; 312 - tty->flip.count++; 311 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 313 312 } 314 313 ignore_char: 315 314 *status = serial_inp(up, UART_LSR);
-2
drivers/serial/clps711x.c
··· 104 104 while (!(status & SYSFLG_URXFE)) { 105 105 ch = clps_readl(UARTDR(port)); 106 106 107 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 108 - goto ignore_char; 109 107 port->icount.rx++; 110 108 111 109 flg = TTY_NORMAL;
-2
drivers/serial/dz.c
··· 216 216 217 217 if (!tty) 218 218 break; 219 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 220 - break; 221 219 222 220 icount->rx++; 223 221
+23 -32
drivers/serial/icom.c
··· 729 729 unsigned short int status; 730 730 struct uart_icount *icount; 731 731 unsigned long offset; 732 + unsigned char flag; 732 733 733 734 trace(icom_port, "RCV_COMPLETE", 0); 734 735 rcv_buff = icom_port->next_rcv; 735 736 736 737 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); 737 738 while (status & SA_FL_RCV_DONE) { 739 + int first = -1; 738 740 739 741 trace(icom_port, "FID_STATUS", status); 740 742 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); 741 743 744 + count = tty_buffer_request_room(tty, count); 742 745 trace(icom_port, "RCV_COUNT", count); 743 - if (count > (TTY_FLIPBUF_SIZE - tty->flip.count)) 744 - count = TTY_FLIPBUF_SIZE - tty->flip.count; 745 746 746 747 trace(icom_port, "REAL_COUNT", count); 747 748 ··· 750 749 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) - 751 750 icom_port->recv_buf_pci; 752 751 753 - memcpy(tty->flip.char_buf_ptr,(unsigned char *) 754 - ((unsigned long)icom_port->recv_buf + offset), count); 755 - 752 + /* Block copy all but the last byte as this may have status */ 756 753 if (count > 0) { 757 - tty->flip.count += count - 1; 758 - tty->flip.char_buf_ptr += count - 1; 759 - 760 - memset(tty->flip.flag_buf_ptr, 0, count); 761 - tty->flip.flag_buf_ptr += count - 1; 754 + first = icom_port->recv_buf[offset]; 755 + tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1); 762 756 } 763 757 764 758 icount = &icom_port->uart_port.icount; ··· 761 765 762 766 /* Break detect logic */ 763 767 if ((status & SA_FLAGS_FRAME_ERROR) 764 - && (tty->flip.char_buf_ptr[0] == 0x00)) { 768 + && first == 0) { 765 769 status &= ~SA_FLAGS_FRAME_ERROR; 766 770 status |= SA_FLAGS_BREAK_DET; 767 771 trace(icom_port, "BREAK_DET", 0); 768 772 } 773 + 774 + flag = TTY_NORMAL; 769 775 770 776 if (status & 771 777 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR | ··· 795 797 status &= icom_port->read_status_mask; 796 798 797 799 if (status & SA_FLAGS_BREAK_DET) { 798 - *tty->flip.flag_buf_ptr = TTY_BREAK; 800 + flag = TTY_BREAK; 799 801 } else if (status & SA_FLAGS_PARITY_ERROR) { 800 802 trace(icom_port, "PARITY_ERROR", 0); 801 - *tty->flip.flag_buf_ptr = TTY_PARITY; 803 + flag = TTY_PARITY; 802 804 } else if (status & SA_FLAGS_FRAME_ERROR) 803 - *tty->flip.flag_buf_ptr = TTY_FRAME; 805 + flag = TTY_FRAME; 804 806 805 - if (status & SA_FLAGS_OVERRUN) { 806 - /* 807 - * Overrun is special, since it's 808 - * reported immediately, and doesn't 809 - * affect the current character 810 - */ 811 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 812 - tty->flip.count++; 813 - tty->flip.flag_buf_ptr++; 814 - tty->flip.char_buf_ptr++; 815 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 816 - } 817 - } 818 807 } 819 808 820 - tty->flip.flag_buf_ptr++; 821 - tty->flip.char_buf_ptr++; 822 - tty->flip.count++; 823 - ignore_char: 824 - icom_port->statStg->rcv[rcv_buff].flags = 0; 809 + tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag); 810 + 811 + if (status & SA_FLAGS_OVERRUN) 812 + /* 813 + * Overrun is special, since it's 814 + * reported immediately, and doesn't 815 + * affect the current character 816 + */ 817 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 818 + ignore_char: 819 + icom_port->statStg->rcv[rcv_buff].flags = 0; 825 820 icom_port->statStg->rcv[rcv_buff].leLength = 0; 826 821 icom_port->statStg->rcv[rcv_buff].WorkingLength = 827 822 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
-3
drivers/serial/imx.c
··· 256 256 error_return: 257 257 tty_insert_flip_char(tty, rx, flg); 258 258 259 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 260 - goto out; 261 - 262 259 ignore_char: 263 260 rx = URXD0((u32)sport->port.membase); 264 261 } while(rx & URXD_CHARRDY);
+2 -8
drivers/serial/ioc4_serial.c
··· 2327 2327 spin_lock_irqsave(&the_port->lock, pflags); 2328 2328 tty = info->tty; 2329 2329 2330 - if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count) 2331 - request_count = TTY_FLIPBUF_SIZE - tty->flip.count; 2330 + request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS - 2); 2332 2331 2333 2332 if (request_count > 0) { 2334 2333 icount = &the_port->icount; 2335 2334 read_count = do_read(the_port, ch, request_count); 2336 2335 if (read_count > 0) { 2337 - flip = 1; 2338 - memcpy(tty->flip.char_buf_ptr, ch, read_count); 2339 - memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count); 2340 - tty->flip.char_buf_ptr += read_count; 2341 - tty->flip.flag_buf_ptr += read_count; 2342 - tty->flip.count += read_count; 2336 + tty_insert_flip_string(tty, ch, read_count); 2343 2337 icount->rx += read_count; 2344 2338 } 2345 2339 }
+10 -24
drivers/serial/ip22zilog.c
··· 259 259 struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ 260 260 261 261 while (1) { 262 - unsigned char ch, r1; 263 - 264 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 265 - tty->flip.work.func((void *)tty); 266 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 267 - return; /* XXX Ignores SysRq when we need it most. Fix. */ 268 - } 262 + unsigned char ch, r1, flag; 269 263 270 264 r1 = read_zsreg(channel, R1); 271 265 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { ··· 297 303 } 298 304 299 305 /* A real serial line, record the character and status. */ 300 - *tty->flip.char_buf_ptr = ch; 301 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 306 + flag = TTY_NORMAL; 302 307 up->port.icount.rx++; 303 308 if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { 304 309 if (r1 & BRK_ABRT) { ··· 314 321 up->port.icount.overrun++; 315 322 r1 &= up->port.read_status_mask; 316 323 if (r1 & BRK_ABRT) 317 - *tty->flip.flag_buf_ptr = TTY_BREAK; 324 + flag = TTY_BREAK; 318 325 else if (r1 & PAR_ERR) 319 - *tty->flip.flag_buf_ptr = TTY_PARITY; 326 + flag = TTY_PARITY; 320 327 else if (r1 & CRC_ERR) 321 - *tty->flip.flag_buf_ptr = TTY_FRAME; 328 + flag = TTY_FRAME; 322 329 } 323 330 if (uart_handle_sysrq_char(&up->port, ch, regs)) 324 331 goto next_char; 325 332 326 333 if (up->port.ignore_status_mask == 0xff || 327 - (r1 & up->port.ignore_status_mask) == 0) { 328 - tty->flip.flag_buf_ptr++; 329 - tty->flip.char_buf_ptr++; 330 - tty->flip.count++; 331 - } 332 - if ((r1 & Rx_OVR) && 333 - tty->flip.count < TTY_FLIPBUF_SIZE) { 334 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 335 - tty->flip.flag_buf_ptr++; 336 - tty->flip.char_buf_ptr++; 337 - tty->flip.count++; 338 - } 334 + (r1 & up->port.ignore_status_mask) == 0) 335 + tty_insert_flip_char(tty, ch, flag); 336 + 337 + if (r1 & Rx_OVR) 338 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 339 339 next_char: 340 340 ch = readb(&channel->control); 341 341 ZSDELAY();
+10 -21
drivers/serial/m32r_sio.c
··· 331 331 { 332 332 struct tty_struct *tty = up->port.info->tty; 333 333 unsigned char ch; 334 + unsigned char flag; 334 335 int max_count = 256; 335 336 336 337 do { 337 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 338 - tty->flip.work.func((void *)tty); 339 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 340 - return; // if TTY_DONT_FLIP is set 341 - } 342 338 ch = sio_in(up, SIORXB); 343 - *tty->flip.char_buf_ptr = ch; 344 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 339 + flag = TTY_NORMAL; 345 340 up->port.icount.rx++; 346 341 347 342 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | ··· 375 380 376 381 if (*status & UART_LSR_BI) { 377 382 DEBUG_INTR("handling break...."); 378 - *tty->flip.flag_buf_ptr = TTY_BREAK; 383 + flag = TTY_BREAK; 379 384 } else if (*status & UART_LSR_PE) 380 - *tty->flip.flag_buf_ptr = TTY_PARITY; 385 + flag = TTY_PARITY; 381 386 else if (*status & UART_LSR_FE) 382 - *tty->flip.flag_buf_ptr = TTY_FRAME; 387 + flag = TTY_FRAME; 383 388 } 384 389 if (uart_handle_sysrq_char(&up->port, ch, regs)) 385 390 goto ignore_char; 386 - if ((*status & up->port.ignore_status_mask) == 0) { 387 - tty->flip.flag_buf_ptr++; 388 - tty->flip.char_buf_ptr++; 389 - tty->flip.count++; 390 - } 391 - if ((*status & UART_LSR_OE) && 392 - tty->flip.count < TTY_FLIPBUF_SIZE) { 391 + if ((*status & up->port.ignore_status_mask) == 0) 392 + tty_insert_flip_char(tty, ch, flag); 393 + 394 + if (*status & UART_LSR_OE) { 393 395 /* 394 396 * Overrun is special, since it's reported 395 397 * immediately, and doesn't affect the current 396 398 * character. 397 399 */ 398 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 399 - tty->flip.flag_buf_ptr++; 400 - tty->flip.char_buf_ptr++; 401 - tty->flip.count++; 400 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 402 401 } 403 402 ignore_char: 404 403 *status = serial_in(up, UART_LSR);
+7 -16
drivers/serial/mcfserial.c
··· 313 313 { 314 314 volatile unsigned char *uartp; 315 315 struct tty_struct *tty = info->tty; 316 - unsigned char status, ch; 316 + unsigned char status, ch, flag; 317 317 318 318 if (!tty) 319 319 return; ··· 321 321 uartp = info->addr; 322 322 323 323 while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { 324 - 325 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 326 - break; 327 - 328 324 ch = uartp[MCFUART_URB]; 329 325 info->stats.rx++; 330 326 ··· 331 335 } 332 336 #endif 333 337 334 - tty->flip.count++; 338 + flag = TTY_NORMAL; 335 339 if (status & MCFUART_USR_RXERR) { 336 340 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; 337 341 if (status & MCFUART_USR_RXBREAK) { 338 342 info->stats.rxbreak++; 339 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 343 + flag = TTY_BREAK; 340 344 } else if (status & MCFUART_USR_RXPARITY) { 341 345 info->stats.rxparity++; 342 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 346 + flag = TTY_PARITY; 343 347 } else if (status & MCFUART_USR_RXOVERRUN) { 344 348 info->stats.rxoverrun++; 345 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 349 + flag = TTY_OVERRUN; 346 350 } else if (status & MCFUART_USR_RXFRAMING) { 347 351 info->stats.rxframing++; 348 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 349 - } else { 350 - /* This should never happen... */ 351 - *tty->flip.flag_buf_ptr++ = 0; 352 + flag = TTY_FRAME; 352 353 } 353 - } else { 354 - *tty->flip.flag_buf_ptr++ = 0; 355 354 } 356 - *tty->flip.char_buf_ptr++ = ch; 355 + tty_insert_flip_char(tty, ch, flag); 357 356 } 358 357 359 358 schedule_work(&tty->flip.work);
+16 -30
drivers/serial/mpc52xx_uart.c
··· 405 405 mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) 406 406 { 407 407 struct tty_struct *tty = port->info->tty; 408 - unsigned char ch; 408 + unsigned char ch, flag; 409 409 unsigned short status; 410 410 411 411 /* While we can read, do so ! */ 412 412 while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & 413 413 MPC52xx_PSC_SR_RXRDY) { 414 414 415 - /* If we are full, just stop reading */ 416 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 417 - break; 418 - 419 415 /* Get the char */ 420 416 ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); 421 417 ··· 424 428 #endif 425 429 426 430 /* Store it */ 427 - *tty->flip.char_buf_ptr = ch; 428 - *tty->flip.flag_buf_ptr = 0; 431 + 432 + flag = TTY_NORMAL; 429 433 port->icount.rx++; 430 434 431 435 if ( status & (MPC52xx_PSC_SR_PE | 432 436 MPC52xx_PSC_SR_FE | 433 - MPC52xx_PSC_SR_RB | 434 - MPC52xx_PSC_SR_OE) ) { 437 + MPC52xx_PSC_SR_RB) ) { 435 438 436 439 if (status & MPC52xx_PSC_SR_RB) { 437 - *tty->flip.flag_buf_ptr = TTY_BREAK; 440 + flag = TTY_BREAK; 438 441 uart_handle_break(port); 439 442 } else if (status & MPC52xx_PSC_SR_PE) 440 - *tty->flip.flag_buf_ptr = TTY_PARITY; 443 + flag = TTY_PARITY; 441 444 else if (status & MPC52xx_PSC_SR_FE) 442 - *tty->flip.flag_buf_ptr = TTY_FRAME; 443 - if (status & MPC52xx_PSC_SR_OE) { 444 - /* 445 - * Overrun is special, since it's 446 - * reported immediately, and doesn't 447 - * affect the current character 448 - */ 449 - if (tty->flip.count < (TTY_FLIPBUF_SIZE-1)) { 450 - tty->flip.flag_buf_ptr++; 451 - tty->flip.char_buf_ptr++; 452 - tty->flip.count++; 453 - } 454 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 455 - } 445 + flag = TTY_FRAME; 456 446 457 447 /* Clear error condition */ 458 448 out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); 459 449 460 450 } 461 - 462 - tty->flip.char_buf_ptr++; 463 - tty->flip.flag_buf_ptr++; 464 - tty->flip.count++; 465 - 451 + tty_insert_flip_char(tty, ch, flag); 452 + if (status & MPC52xx_PSC_SR_OE) { 453 + /* 454 + * Overrun is special, since it's 455 + * reported immediately, and doesn't 456 + * affect the current character 457 + */ 458 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 459 + } 466 460 } 467 461 468 462 tty_flip_buffer_push(tty);
+3 -3
drivers/serial/mpsc.c
··· 769 769 bytes_in = be16_to_cpu(rxre->bytecnt); 770 770 771 771 /* Following use of tty struct directly is deprecated */ 772 - if (unlikely((tty->flip.count + bytes_in) >= TTY_FLIPBUF_SIZE)){ 772 + if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) { 773 773 if (tty->low_latency) 774 774 tty_flip_buffer_push(tty); 775 775 /* 776 - * If this failed then we will throw awa the bytes 777 - * but mst do so to clear interrupts. 776 + * If this failed then we will throw away the bytes 777 + * but must do so to clear interrupts. 778 778 */ 779 779 } 780 780
+1 -8
drivers/serial/mux.c
··· 223 223 if (MUX_EOFIFO(data)) 224 224 break; 225 225 226 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 227 - continue; 228 - 229 - *tty->flip.char_buf_ptr = data & 0xffu; 230 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 231 226 port->icount.rx++; 232 227 233 228 if (MUX_BREAK(data)) { ··· 234 239 if (uart_handle_sysrq_char(port, data & 0xffu, NULL)) 235 240 continue; 236 241 237 - tty->flip.flag_buf_ptr++; 238 - tty->flip.char_buf_ptr++; 239 - tty->flip.count++; 242 + tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); 240 243 } 241 244 242 245 if (start_count != port->icount.rx) {
+8 -31
drivers/serial/pmac_zilog.c
··· 210 210 struct pt_regs *regs) 211 211 { 212 212 struct tty_struct *tty = NULL; 213 - unsigned char ch, r1, drop, error; 213 + unsigned char ch, r1, drop, error, flag; 214 214 int loops = 0; 215 215 216 - retry: 217 216 /* The interrupt can be enabled when the port isn't open, typically 218 217 * that happens when using one port is open and the other closed (stale 219 218 * interrupt) or when one port is used as a console. ··· 244 245 while (1) { 245 246 error = 0; 246 247 drop = 0; 247 - 248 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 249 - /* Have to drop the lock here */ 250 - pmz_debug("pmz: flip overflow\n"); 251 - spin_unlock(&uap->port.lock); 252 - tty->flip.work.func((void *)tty); 253 - spin_lock(&uap->port.lock); 254 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 255 - drop = 1; 256 - if (ZS_IS_ASLEEP(uap)) 257 - return NULL; 258 - if (!ZS_IS_OPEN(uap)) 259 - goto retry; 260 - } 261 248 262 249 r1 = read_zsreg(uap, R1); 263 250 ch = read_zsdata(uap); ··· 280 295 if (drop) 281 296 goto next_char; 282 297 283 - *tty->flip.char_buf_ptr = ch; 284 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 298 + flag = TTY_NORMAL; 285 299 uap->port.icount.rx++; 286 300 287 301 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { ··· 300 316 uap->port.icount.overrun++; 301 317 r1 &= uap->port.read_status_mask; 302 318 if (r1 & BRK_ABRT) 303 - *tty->flip.flag_buf_ptr = TTY_BREAK; 319 + flag = TTY_BREAK; 304 320 else if (r1 & PAR_ERR) 305 - *tty->flip.flag_buf_ptr = TTY_PARITY; 321 + flag = TTY_PARITY; 306 322 else if (r1 & CRC_ERR) 307 - *tty->flip.flag_buf_ptr = TTY_FRAME; 323 + flag = TTY_FRAME; 308 324 } 309 325 310 326 if (uap->port.ignore_status_mask == 0xff || 311 327 (r1 & uap->port.ignore_status_mask) == 0) { 312 - tty->flip.flag_buf_ptr++; 313 - tty->flip.char_buf_ptr++; 314 - tty->flip.count++; 328 + tty_insert_flip_char(tty, ch, flag); 315 329 } 316 - if ((r1 & Rx_OVR) && 317 - tty->flip.count < TTY_FLIPBUF_SIZE) { 318 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 319 - tty->flip.flag_buf_ptr++; 320 - tty->flip.char_buf_ptr++; 321 - tty->flip.count++; 322 - } 330 + if (r1 & Rx_OVR) 331 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 323 332 next_char: 324 333 /* We can get stuck in an infinite loop getting char 0 when the 325 334 * line is in a wrong HW state, we break that here.
-8
drivers/serial/pxa.c
··· 107 107 int max_count = 256; 108 108 109 109 do { 110 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 111 - if (tty->low_latency) 112 - tty_flip_buffer_push(tty); 113 - /* 114 - * If this failed then we will throw away the 115 - * bytes but must do so to clear interrupts 116 - */ 117 - } 118 110 ch = serial_in(up, UART_RX); 119 111 flag = TTY_NORMAL; 120 112 up->port.icount.rx++;
-10
drivers/serial/s3c2410.c
··· 323 323 if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) 324 324 break; 325 325 326 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 327 - if (tty->low_latency) 328 - tty_flip_buffer_push(tty); 329 - 330 - /* 331 - * If this failed then we will throw away the 332 - * bytes but must do so to clear interrupts 333 - */ 334 - } 335 - 336 326 uerstat = rd_regl(port, S3C2410_UERSTAT); 337 327 ch = rd_regb(port, S3C2410_URXH); 338 328
-2
drivers/serial/sa1100.c
··· 201 201 while (status & UTSR1_TO_SM(UTSR1_RNE)) { 202 202 ch = UART_GET_CHAR(sport); 203 203 204 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 205 - goto ignore_char; 206 204 sport->port.icount.rx++; 207 205 208 206 flg = TTY_NORMAL;
-9
drivers/serial/serial_lh7a40x.c
··· 148 148 unsigned int data, flag;/* Received data and status */ 149 149 150 150 while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { 151 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 152 - if (tty->low_latency) 153 - tty_flip_buffer_push(tty); 154 - /* 155 - * If this failed then we will throw away the 156 - * bytes but must do so to clear interrupts 157 - */ 158 - } 159 - 160 151 data = UR (port, UART_R_DATA); 161 152 flag = TTY_NORMAL; 162 153 ++port->icount.rx;
-11
drivers/serial/serial_txx9.c
··· 303 303 char flag; 304 304 305 305 do { 306 - /* The following is not allowed by the tty layer and 307 - unsafe. It should be fixed ASAP */ 308 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 309 - if (tty->low_latency) { 310 - spin_unlock(&up->port.lock); 311 - tty_flip_buffer_push(tty); 312 - spin_lock(&up->port.lock); 313 - } 314 - /* If this failed then we will throw away the 315 - bytes but must do so to clear interrupts */ 316 - } 317 306 ch = sio_in(up, TXX9_SIRFIFO); 318 307 flag = TTY_NORMAL; 319 308 up->port.icount.rx++;
+32 -49
drivers/serial/sh-sci.c
··· 482 482 struct tty_struct *tty = port->info->tty; 483 483 int i, count, copied = 0; 484 484 unsigned short status; 485 + unsigned char flag; 485 486 486 487 status = sci_in(port, SCxSR); 487 488 if (!(status & SCxSR_RDxF(port))) ··· 500 499 #endif 501 500 502 501 /* Don't copy more bytes than there is room for in the buffer */ 503 - if (tty->flip.count + count > TTY_FLIPBUF_SIZE) 504 - count = TTY_FLIPBUF_SIZE - tty->flip.count; 502 + count = tty_buffer_request_room(tty, count); 505 503 506 504 /* If for any reason we can't copy more data, we're done! */ 507 505 if (count == 0) ··· 512 512 || uart_handle_sysrq_char(port, c, regs)) { 513 513 count = 0; 514 514 } else { 515 - tty->flip.char_buf_ptr[0] = c; 516 - tty->flip.flag_buf_ptr[0] = TTY_NORMAL; 515 + tty_insert_flip_char(tty, c, TTY_NORMAL); 517 516 } 518 517 } else { 519 518 for (i=0; i<count; i++) { ··· 541 542 } 542 543 543 544 /* Store data and status */ 544 - tty->flip.char_buf_ptr[i] = c; 545 545 if (status&SCxSR_FER(port)) { 546 - tty->flip.flag_buf_ptr[i] = TTY_FRAME; 546 + flag = TTY_FRAME; 547 547 pr_debug("sci: frame error\n"); 548 548 } else if (status&SCxSR_PER(port)) { 549 - tty->flip.flag_buf_ptr[i] = TTY_PARITY; 549 + flag = TTY_PARITY; 550 550 pr_debug("sci: parity error\n"); 551 - } else { 552 - tty->flip.flag_buf_ptr[i] = TTY_NORMAL; 553 - } 551 + } else 552 + flag = TTY_NORMAL; 553 + tty_insert_flip_char(tty, c, flag); 554 554 } 555 555 } 556 556 557 557 sci_in(port, SCxSR); /* dummy read */ 558 558 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); 559 559 560 - /* Update the kernel buffer end */ 561 - tty->flip.count += count; 562 - tty->flip.char_buf_ptr += count; 563 - tty->flip.flag_buf_ptr += count; 564 560 copied += count; 565 561 port->icount.rx += count; 566 562 } ··· 602 608 unsigned short status = sci_in(port, SCxSR); 603 609 struct tty_struct *tty = port->info->tty; 604 610 605 - if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { 611 + if (status&SCxSR_ORER(port)) { 606 612 /* overrun error */ 607 - copied++; 608 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 613 + if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) 614 + copied++; 609 615 pr_debug("sci: overrun error\n"); 610 616 } 611 617 612 - if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { 618 + if (status&SCxSR_FER(port)) { 613 619 if (sci_rxd_in(port) == 0) { 614 620 /* Notify of BREAK */ 615 621 struct sci_port * sci_port = (struct sci_port *)port; 616 - if(!sci_port->break_flag) { 617 - sci_port->break_flag = 1; 618 - sci_schedule_break_timer((struct sci_port *)port); 622 + if(!sci_port->break_flag) { 623 + sci_port->break_flag = 1; 624 + sci_schedule_break_timer((struct sci_port *)port); 619 625 /* Do sysrq handling. */ 620 - if(uart_handle_break(port)) { 626 + if(uart_handle_break(port)) 621 627 return 0; 622 - } 623 628 pr_debug("sci: BREAK detected\n"); 624 - copied++; 625 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 629 + if(tty_insert_flip_char(tty, 0, TTY_BREAK)) 630 + copied++; 626 631 } 627 632 } 628 633 else { 629 634 /* frame error */ 630 - copied++; 631 - *tty->flip.flag_buf_ptr++ = TTY_FRAME; 635 + if(tty_insert_flip_char(tty, 0, TTY_FRAME)) 636 + copied++; 632 637 pr_debug("sci: frame error\n"); 633 638 } 634 639 } 635 640 636 - if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { 641 + if (status&SCxSR_PER(port)) { 642 + if(tty_insert_flip_char(tty, 0, TTY_PARITY)) 643 + copied++; 637 644 /* parity error */ 638 - copied++; 639 - *tty->flip.flag_buf_ptr++ = TTY_PARITY; 640 645 pr_debug("sci: parity error\n"); 641 646 } 642 647 643 - if (copied) { 644 - tty->flip.count += copied; 648 + if (copied) 645 649 tty_flip_buffer_push(tty); 646 - } 647 650 648 651 return copied; 649 652 } ··· 652 661 struct tty_struct *tty = port->info->tty; 653 662 struct sci_port *s = &sci_ports[port->line]; 654 663 655 - if (!s->break_flag && status & SCxSR_BRK(port) && 656 - tty->flip.count < TTY_FLIPBUF_SIZE) { 664 + if (!s->break_flag && status & SCxSR_BRK(port)) 657 665 #if defined(CONFIG_CPU_SH3) 658 666 /* Debounce break */ 659 667 s->break_flag = 1; 660 668 #endif 661 669 /* Notify of BREAK */ 662 - copied++; 663 - *tty->flip.flag_buf_ptr++ = TTY_BREAK; 670 + if(tty_insert_flip_char(tty, 0, TTY_BREAK)) 671 + copied++; 664 672 pr_debug("sci: BREAK detected\n"); 665 673 } 666 674 ··· 667 677 /* XXX: Handle SCIF overrun error */ 668 678 if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { 669 679 sci_out(port, SCLSR, 0); 670 - if(tty->flip.count<TTY_FLIPBUF_SIZE) { 680 + if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { 671 681 copied++; 672 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 673 682 pr_debug("sci: overrun error\n"); 674 683 } 675 684 } 676 685 #endif 677 686 678 - if (copied) { 679 - tty->flip.count += copied; 687 + if (copied) 680 688 tty_flip_buffer_push(tty); 681 - } 682 - 683 689 return copied; 684 690 } 685 691 ··· 718 732 struct tty_struct *tty = port->info->tty; 719 733 720 734 sci_out(port, SCLSR, 0); 721 - if(tty->flip.count<TTY_FLIPBUF_SIZE) { 722 - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; 723 - tty->flip.count++; 724 - tty_flip_buffer_push(tty); 725 - pr_debug("scif: overrun error\n"); 726 - } 735 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 736 + tty_flip_buffer_push(tty); 737 + pr_debug("scif: overrun error\n"); 727 738 } 728 739 #endif 729 740 sci_rx_interrupt(irq, ptr, regs);
+1 -5
drivers/serial/sn_console.c
··· 519 519 520 520 /* record the character to pass up to the tty layer */ 521 521 if (tty) { 522 - *tty->flip.char_buf_ptr = ch; 523 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 524 - tty->flip.char_buf_ptr++; 525 - tty->flip.count++; 526 - if (tty->flip.count == TTY_FLIPBUF_SIZE) 522 + if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) 527 523 break; 528 524 } 529 525 port->sc_port.icount.rx++;
+9 -29
drivers/serial/sunsab.c
··· 159 159 saw_console_brk = 1; 160 160 161 161 for (i = 0; i < count; i++) { 162 - unsigned char ch = buf[i]; 162 + unsigned char ch = buf[i], flag; 163 163 164 164 if (tty == NULL) { 165 165 uart_handle_sysrq_char(&up->port, ch, regs); 166 166 continue; 167 167 } 168 168 169 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 170 - tty->flip.work.func((void *)tty); 171 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 172 - return tty; // if TTY_DONT_FLIP is set 173 - } 174 - 175 - *tty->flip.char_buf_ptr = ch; 176 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 169 + flag = TTY_NORMAL; 177 170 up->port.icount.rx++; 178 171 179 172 if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR | ··· 202 209 stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff); 203 210 204 211 if (stat->sreg.isr1 & SAB82532_ISR1_BRK) { 205 - *tty->flip.flag_buf_ptr = TTY_BREAK; 212 + flag = TTY_BREAK; 206 213 } else if (stat->sreg.isr0 & SAB82532_ISR0_PERR) 207 - *tty->flip.flag_buf_ptr = TTY_PARITY; 214 + flag = TTY_PARITY; 208 215 else if (stat->sreg.isr0 & SAB82532_ISR0_FERR) 209 - *tty->flip.flag_buf_ptr = TTY_FRAME; 216 + flag = TTY_FRAME; 210 217 } 211 218 212 219 if (uart_handle_sysrq_char(&up->port, ch, regs)) 213 220 continue; 214 221 215 222 if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && 216 - (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0){ 217 - tty->flip.flag_buf_ptr++; 218 - tty->flip.char_buf_ptr++; 219 - tty->flip.count++; 220 - } 221 - if ((stat->sreg.isr0 & SAB82532_ISR0_RFO) && 222 - tty->flip.count < TTY_FLIPBUF_SIZE) { 223 - /* 224 - * Overrun is special, since it's reported 225 - * immediately, and doesn't affect the current 226 - * character. 227 - */ 228 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 229 - tty->flip.flag_buf_ptr++; 230 - tty->flip.char_buf_ptr++; 231 - tty->flip.count++; 232 - } 223 + (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) 224 + tty_insert_flip_char(tty, ch, flag); 225 + if (stat->sreg.isr0 & SAB82532_ISR0_RFO) 226 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 233 227 } 234 228 235 229 if (saw_console_brk)
+9 -23
drivers/serial/sunsu.c
··· 323 323 receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) 324 324 { 325 325 struct tty_struct *tty = up->port.info->tty; 326 - unsigned char ch; 326 + unsigned char ch, flag; 327 327 int max_count = 256; 328 328 int saw_console_brk = 0; 329 329 330 330 do { 331 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 332 - tty->flip.work.func((void *)tty); 333 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 334 - return tty; // if TTY_DONT_FLIP is set 335 - } 336 331 ch = serial_inp(up, UART_RX); 337 - *tty->flip.char_buf_ptr = ch; 338 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 332 + flag = TTY_NORMAL; 339 333 up->port.icount.rx++; 340 334 341 335 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | ··· 371 377 } 372 378 373 379 if (*status & UART_LSR_BI) { 374 - *tty->flip.flag_buf_ptr = TTY_BREAK; 380 + flag = TTY_BREAK; 375 381 } else if (*status & UART_LSR_PE) 376 - *tty->flip.flag_buf_ptr = TTY_PARITY; 382 + flag = TTY_PARITY; 377 383 else if (*status & UART_LSR_FE) 378 - *tty->flip.flag_buf_ptr = TTY_FRAME; 384 + flag = TTY_FRAME; 379 385 } 380 386 if (uart_handle_sysrq_char(&up->port, ch, regs)) 381 387 goto ignore_char; 382 - if ((*status & up->port.ignore_status_mask) == 0) { 383 - tty->flip.flag_buf_ptr++; 384 - tty->flip.char_buf_ptr++; 385 - tty->flip.count++; 386 - } 387 - if ((*status & UART_LSR_OE) && 388 - tty->flip.count < TTY_FLIPBUF_SIZE) { 388 + if ((*status & up->port.ignore_status_mask) == 0) 389 + tty_insert_flip_char(tty, ch, flag); 390 + if (*status & UART_LSR_OE) 389 391 /* 390 392 * Overrun is special, since it's reported 391 393 * immediately, and doesn't affect the current 392 394 * character. 393 395 */ 394 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 395 - tty->flip.flag_buf_ptr++; 396 - tty->flip.char_buf_ptr++; 397 - tty->flip.count++; 398 - } 396 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 399 397 ignore_char: 400 398 *status = serial_inp(up, UART_LSR); 401 399 } while ((*status & UART_LSR_DR) && (max_count-- > 0));
+8 -26
drivers/serial/sunzilog.c
··· 319 319 struct pt_regs *regs) 320 320 { 321 321 struct tty_struct *tty; 322 - unsigned char ch, r1; 322 + unsigned char ch, r1, flag; 323 323 324 324 tty = NULL; 325 325 if (up->port.info != NULL && /* Unopened serial console */ ··· 362 362 continue; 363 363 } 364 364 365 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 366 - tty->flip.work.func((void *)tty); 367 - /* 368 - * The 8250 bails out of the loop here, 369 - * but we need to read everything, or die. 370 - */ 371 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 372 - continue; 373 - } 374 - 375 365 /* A real serial line, record the character and status. */ 376 - *tty->flip.char_buf_ptr = ch; 377 - *tty->flip.flag_buf_ptr = TTY_NORMAL; 366 + flag = TTY_NORMAL; 378 367 up->port.icount.rx++; 379 368 if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { 380 369 if (r1 & BRK_ABRT) { ··· 380 391 up->port.icount.overrun++; 381 392 r1 &= up->port.read_status_mask; 382 393 if (r1 & BRK_ABRT) 383 - *tty->flip.flag_buf_ptr = TTY_BREAK; 394 + flag = TTY_BREAK; 384 395 else if (r1 & PAR_ERR) 385 - *tty->flip.flag_buf_ptr = TTY_PARITY; 396 + flag = TTY_PARITY; 386 397 else if (r1 & CRC_ERR) 387 - *tty->flip.flag_buf_ptr = TTY_FRAME; 398 + flag = TTY_FRAME; 388 399 } 389 400 if (uart_handle_sysrq_char(&up->port, ch, regs)) 390 401 continue; 391 402 392 403 if (up->port.ignore_status_mask == 0xff || 393 404 (r1 & up->port.ignore_status_mask) == 0) { 394 - tty->flip.flag_buf_ptr++; 395 - tty->flip.char_buf_ptr++; 396 - tty->flip.count++; 405 + tty_insert_flip_char(tty, ch, flag); 397 406 } 398 - if ((r1 & Rx_OVR) && 399 - tty->flip.count < TTY_FLIPBUF_SIZE) { 400 - *tty->flip.flag_buf_ptr = TTY_OVERRUN; 401 - tty->flip.flag_buf_ptr++; 402 - tty->flip.char_buf_ptr++; 403 - tty->flip.count++; 404 - } 407 + if (r1 & Rx_OVR) 408 + tty_insert_flip_char(tty, 0, TTY_OVERRUN); 405 409 } 406 410 407 411 return tty;
-5
drivers/serial/vr41xx_siu.c
··· 371 371 lsr = *status; 372 372 373 373 do { 374 - if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 375 - if (tty->low_latency) 376 - tty_flip_buffer_push(tty); 377 - } 378 - 379 374 ch = siu_read(port, UART_RX); 380 375 port->icount.rx++; 381 376 flag = TTY_NORMAL;
+3 -8
drivers/usb/class/cdc-acm.c
··· 335 335 336 336 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); 337 337 338 - for (i = 0; i < buf->size && !acm->throttle; i++) { 339 - /* if we insert more than TTY_FLIPBUF_SIZE characters, 340 - we drop them. */ 341 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 342 - tty_flip_buffer_push(tty); 343 - } 344 - tty_insert_flip_char(tty, buf->base[i], 0); 345 - } 338 + tty_buffer_request_room(tty, buf->size); 339 + if (!acm->throttle) 340 + tty_insert_flip_string(tty, buf->base, buf->size); 346 341 tty_flip_buffer_push(tty); 347 342 348 343 spin_lock(&acm->throttle_lock);
+8 -11
drivers/usb/gadget/serial.c
··· 1271 1271 unsigned int len; 1272 1272 struct gs_port *port; 1273 1273 int ret; 1274 + struct tty_struct *tty; 1274 1275 1275 1276 /* TEMPORARY -- only port 0 is supported right now */ 1276 1277 port = dev->dev_port[0]; ··· 1291 1290 goto exit; 1292 1291 } 1293 1292 1294 - if (port->port_tty == NULL) { 1293 + 1294 + tty = port->port_tty; 1295 + 1296 + if (tty == NULL) { 1295 1297 printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", 1296 1298 port->port_num); 1297 1299 ret = -EIO; ··· 1308 1304 goto exit; 1309 1305 } 1310 1306 1311 - len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count); 1312 - if (len < size) 1313 - size = len; 1314 - 1315 - if (size > 0) { 1316 - memcpy(port->port_tty->flip.char_buf_ptr, packet, size); 1317 - port->port_tty->flip.char_buf_ptr += size; 1318 - port->port_tty->flip.count += size; 1307 + len = tty_buffer_request_room(tty, size); 1308 + if (len > 0) { 1309 + tty_insert_flip_string(tty, packet, len); 1319 1310 tty_flip_buffer_push(port->port_tty); 1320 1311 wake_up_interruptible(&port->port_tty->read_wait); 1321 1312 } 1322 - 1323 1313 ret = 0; 1324 - 1325 1314 exit: 1326 1315 spin_unlock(&port->port_lock); 1327 1316 return ret;
+1 -1
drivers/usb/serial/Kconfig
··· 84 84 85 85 config USB_SERIAL_WHITEHEAT 86 86 tristate "USB ConnectTech WhiteHEAT Serial Driver" 87 - depends on USB_SERIAL && BROKEN_ON_SMP 87 + depends on USB_SERIAL 88 88 help 89 89 Say Y here if you want to use a ConnectTech WhiteHEAT 4 port 90 90 USB to serial converter device.
+2 -9
drivers/usb/serial/cyberjack.c
··· 364 364 struct tty_struct *tty; 365 365 unsigned char *data = urb->transfer_buffer; 366 366 short todo; 367 - int i; 368 367 int result; 369 368 370 369 dbg("%s - port %d", __FUNCTION__, port->number); ··· 380 381 return; 381 382 } 382 383 if (urb->actual_length) { 383 - for (i = 0; i < urb->actual_length ; ++i) { 384 - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ 385 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 386 - tty_flip_buffer_push(tty); 387 - } 388 - /* this doesn't actually push the data through unless tty->low_latency is set */ 389 - tty_insert_flip_char(tty, data[i], 0); 390 - } 384 + tty_buffer_request_room(tty, urb->actual_length); 385 + tty_insert_flip_string(tty, data, urb->actual_length); 391 386 tty_flip_buffer_push(tty); 392 387 } 393 388
+1 -3
drivers/usb/serial/cypress_m8.c
··· 1263 1263 1264 1264 /* process read if there is data other than line status */ 1265 1265 if (tty && (bytes > i)) { 1266 + bytes = tty_buffer_request_room(tty, bytes); 1266 1267 for (; i < bytes ; ++i) { 1267 1268 dbg("pushing byte number %d - %d - %c", i, data[i], 1268 1269 data[i]); 1269 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 1270 - tty_flip_buffer_push(tty); 1271 - } 1272 1270 tty_insert_flip_char(tty, data[i], tty_flag); 1273 1271 } 1274 1272 tty_flip_buffer_push(port->tty);
+12 -16
drivers/usb/serial/digi_acceleport.c
··· 946 946 spin_lock_irqsave( &priv->dp_port_lock, flags ); 947 947 948 948 /* send any buffered chars from throttle time on to tty subsystem */ 949 - len = min(priv->dp_in_buf_len, TTY_FLIPBUF_SIZE - tty->flip.count ); 949 + 950 + len = tty_buffer_request_room(tty, priv->dp_in_buf_len); 950 951 if( len > 0 ) { 951 - memcpy( tty->flip.char_buf_ptr, priv->dp_in_buf, len ); 952 - memcpy( tty->flip.flag_buf_ptr, priv->dp_in_flag_buf, len ); 953 - tty->flip.char_buf_ptr += len; 954 - tty->flip.flag_buf_ptr += len; 955 - tty->flip.count += len; 952 + tty_insert_flip_string_flags(tty, priv->dp_in_buf, priv->dp_in_flag_buf, len); 956 953 tty_flip_buffer_push( tty ); 957 954 } 958 955 ··· 1824 1827 int status = ((unsigned char *)urb->transfer_buffer)[2]; 1825 1828 unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3; 1826 1829 int flag,throttled; 1830 + int i; 1827 1831 1828 1832 /* do not process callbacks on closed ports */ 1829 1833 /* but do continue the read chain */ ··· 1883 1885 } 1884 1886 1885 1887 } else { 1886 - 1887 - len = min( len, TTY_FLIPBUF_SIZE - tty->flip.count ); 1888 - 1888 + len = tty_buffer_request_room(tty, len); 1889 1889 if( len > 0 ) { 1890 - memcpy( tty->flip.char_buf_ptr, data, len ); 1891 - memset( tty->flip.flag_buf_ptr, flag, len ); 1892 - tty->flip.char_buf_ptr += len; 1893 - tty->flip.flag_buf_ptr += len; 1894 - tty->flip.count += len; 1890 + /* Hot path */ 1891 + if(flag == TTY_NORMAL) 1892 + tty_insert_flip_string(tty, data, len); 1893 + else { 1894 + for(i = 0; i < len; i++) 1895 + tty_insert_flip_char(tty, data[i], flag); 1896 + } 1895 1897 tty_flip_buffer_push( tty ); 1896 1898 } 1897 - 1898 1899 } 1899 - 1900 1900 } 1901 1901 1902 1902 spin_unlock( &priv->dp_port_lock );
+2 -14
drivers/usb/serial/empeg.c
··· 344 344 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 345 345 struct tty_struct *tty; 346 346 unsigned char *data = urb->transfer_buffer; 347 - int i; 348 347 int result; 349 348 350 349 dbg("%s - port %d", __FUNCTION__, port->number); ··· 358 359 tty = port->tty; 359 360 360 361 if (urb->actual_length) { 361 - for (i = 0; i < urb->actual_length ; ++i) { 362 - /* gb - 2000/11/13 363 - * If we insert too many characters we'll overflow the buffer. 364 - * This means we'll lose bytes - Decidedly bad. 365 - */ 366 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 367 - tty_flip_buffer_push(tty); 368 - } 369 - tty_insert_flip_char(tty, data[i], 0); 370 - } 371 - /* gb - 2000/11/13 372 - * Goes straight through instead of scheduling - if tty->low_latency is set. 373 - */ 362 + tty_buffer_request_room(tty, urb->actual_length); 363 + tty_insert_flip_string(tty, data, urb->actual_length); 374 364 tty_flip_buffer_push(tty); 375 365 bytes_in += urb->actual_length; 376 366 }
+1 -14
drivers/usb/serial/ftdi_sio.c
··· 1610 1610 length = 0; 1611 1611 } 1612 1612 1613 - /* have to make sure we don't overflow the buffer 1614 - with tty_insert_flip_char's */ 1615 - if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { 1616 - tty_flip_buffer_push(tty); 1617 - need_flip = 0; 1618 - 1619 - if (tty->flip.count != 0) { 1620 - /* flip didn't work, this happens when ftdi_process_read() is 1621 - * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ 1622 - dbg("%s - flip buffer push failed", __FUNCTION__); 1623 - break; 1624 - } 1625 - } 1626 1613 if (priv->rx_flags & THROTTLED) { 1627 1614 dbg("%s - throttled", __FUNCTION__); 1628 1615 break; 1629 1616 } 1630 - if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { 1617 + if (tty_buffer_request_room(tty, length) < length) { 1631 1618 /* break out & wait for throttling/unthrottling to happen */ 1632 1619 dbg("%s - receive room low", __FUNCTION__); 1633 1620 break;
+2 -11
drivers/usb/serial/garmin_gps.c
··· 275 275 char *data, unsigned int actual_length) 276 276 { 277 277 struct tty_struct *tty = port->tty; 278 - int i; 279 278 280 279 if (tty && actual_length) { 281 280 282 281 usb_serial_debug_data(debug, &port->dev, 283 282 __FUNCTION__, actual_length, data); 284 283 285 - for (i = 0; i < actual_length ; ++i) { 286 - /* if we insert more than TTY_FLIPBUF_SIZE characters, 287 - we drop them. */ 288 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 289 - tty_flip_buffer_push(tty); 290 - } 291 - /* this doesn't actually push the data through unless 292 - tty->low_latency is set */ 293 - tty_insert_flip_char(tty, data[i], 0); 294 - } 284 + tty_buffer_request_room(tty, actual_length); 285 + tty_insert_flip_string(tty, data, actual_length); 295 286 tty_flip_buffer_push(tty); 296 287 } 297 288 }
+2 -9
drivers/usb/serial/generic.c
··· 254 254 struct usb_serial *serial = port->serial; 255 255 struct tty_struct *tty; 256 256 unsigned char *data = urb->transfer_buffer; 257 - int i; 258 257 int result; 259 258 260 259 dbg("%s - port %d", __FUNCTION__, port->number); ··· 267 268 268 269 tty = port->tty; 269 270 if (tty && urb->actual_length) { 270 - for (i = 0; i < urb->actual_length ; ++i) { 271 - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ 272 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 273 - tty_flip_buffer_push(tty); 274 - } 275 - /* this doesn't actually push the data through unless tty->low_latency is set */ 276 - tty_insert_flip_char(tty, data[i], 0); 277 - } 271 + tty_buffer_request_room(tty, urb->actual_length); 272 + tty_insert_flip_string(tty, data, urb->actual_length); 278 273 tty_flip_buffer_push(tty); 279 274 } 280 275
+7 -13
drivers/usb/serial/io_edgeport.c
··· 1965 1965 int cnt; 1966 1966 1967 1967 do { 1968 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 1969 - tty_flip_buffer_push(tty); 1970 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 1971 - dev_err(dev, "%s - dropping data, %d bytes lost\n", 1972 - __FUNCTION__, length); 1973 - return; 1974 - } 1968 + cnt = tty_buffer_request_room(tty, length); 1969 + if (cnt < length) { 1970 + dev_err(dev, "%s - dropping data, %d bytes lost\n", 1971 + __FUNCTION__, length - cnt); 1972 + if(cnt == 0) 1973 + break; 1975 1974 } 1976 - cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); 1977 - memcpy(tty->flip.char_buf_ptr, data, cnt); 1978 - memset(tty->flip.flag_buf_ptr, 0, cnt); 1979 - tty->flip.char_buf_ptr += cnt; 1980 - tty->flip.flag_buf_ptr += cnt; 1981 - tty->flip.count += cnt; 1975 + tty_insert_flip_string(tty, data, cnt); 1982 1976 data += cnt; 1983 1977 length -= cnt; 1984 1978 } while (length > 0);
+7 -13
drivers/usb/serial/io_ti.c
··· 1865 1865 int cnt; 1866 1866 1867 1867 do { 1868 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 1869 - tty_flip_buffer_push(tty); 1870 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 1871 - dev_err(dev, "%s - dropping data, %d bytes lost\n", 1872 - __FUNCTION__, length); 1873 - return; 1874 - } 1868 + cnt = tty_buffer_request_room(tty, length); 1869 + if (cnt < length) { 1870 + dev_err(dev, "%s - dropping data, %d bytes lost\n", 1871 + __FUNCTION__, length - cnt); 1872 + if(cnt == 0) 1873 + break; 1875 1874 } 1876 - cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); 1877 - memcpy(tty->flip.char_buf_ptr, data, cnt); 1878 - memset(tty->flip.flag_buf_ptr, 0, cnt); 1879 - tty->flip.char_buf_ptr += cnt; 1880 - tty->flip.flag_buf_ptr += cnt; 1881 - tty->flip.count += cnt; 1875 + tty_insert_flip_string(tty, data, cnt); 1882 1876 data += cnt; 1883 1877 length -= cnt; 1884 1878 } while (length > 0);
+3 -9
drivers/usb/serial/ipaq.c
··· 711 711 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 712 712 struct tty_struct *tty; 713 713 unsigned char *data = urb->transfer_buffer; 714 - int i, result; 714 + int result; 715 715 716 716 dbg("%s - port %d", __FUNCTION__, port->number); 717 717 ··· 724 724 725 725 tty = port->tty; 726 726 if (tty && urb->actual_length) { 727 - for (i = 0; i < urb->actual_length ; ++i) { 728 - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ 729 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 730 - tty_flip_buffer_push(tty); 731 - } 732 - /* this doesn't actually push the data through unless tty->low_latency is set */ 733 - tty_insert_flip_char(tty, data[i], 0); 734 - } 727 + tty_buffer_request_room(tty, urb->actual_length); 728 + tty_insert_flip_string(tty, data, urb->actual_length); 735 729 tty_flip_buffer_push(tty); 736 730 bytes_in += urb->actual_length; 737 731 }
+2 -9
drivers/usb/serial/ipw.c
··· 166 166 struct usb_serial_port *port = urb->context; 167 167 unsigned char *data = urb->transfer_buffer; 168 168 struct tty_struct *tty; 169 - int i; 170 169 int result; 171 170 172 171 dbg("%s - port %d", __FUNCTION__, port->number); ··· 179 180 180 181 tty = port->tty; 181 182 if (tty && urb->actual_length) { 182 - for (i = 0; i < urb->actual_length ; ++i) { 183 - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ 184 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 185 - tty_flip_buffer_push(tty); 186 - } 187 - /* this doesn't actually push the data through unless tty->low_latency is set */ 188 - tty_insert_flip_char(tty, data[i], 0); 189 - } 183 + tty_buffer_request_room(tty, urb->actual_length); 184 + tty_insert_flip_string(tty, data, urb->actual_length); 190 185 tty_flip_buffer_push(tty); 191 186 } 192 187
+2 -11
drivers/usb/serial/kl5kusb105.c
··· 648 648 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, 649 649 urb->actual_length, data); 650 650 } else { 651 - int i; 652 651 int bytes_sent = ((__u8 *) data)[0] + 653 652 ((unsigned int) ((__u8 *) data)[1] << 8); 654 653 tty = port->tty; ··· 668 669 bytes_sent = urb->actual_length - 2; 669 670 } 670 671 671 - for (i = 2; i < 2+bytes_sent; i++) { 672 - /* if we insert more than TTY_FLIPBUF_SIZE characters, 673 - * we drop them. */ 674 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 675 - tty_flip_buffer_push(tty); 676 - } 677 - /* this doesn't actually push the data through unless 678 - * tty->low_latency is set */ 679 - tty_insert_flip_char(tty, ((__u8*) data)[i], 0); 680 - } 672 + tty_buffer_request_room(tty, bytes_sent); 673 + tty_insert_flip_string(tty, data + 2, bytes_sent); 681 674 tty_flip_buffer_push(tty); 682 675 683 676 /* again lockless, but debug info only */
+2 -9
drivers/usb/serial/kobil_sct.c
··· 365 365 366 366 static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) 367 367 { 368 - int i; 369 368 int result; 370 369 struct usb_serial_port *port = (struct usb_serial_port *) purb->context; 371 370 struct tty_struct *tty; ··· 396 397 */ 397 398 // END DEBUG 398 399 399 - for (i = 0; i < purb->actual_length; ++i) { 400 - // if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. 401 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 402 - tty_flip_buffer_push(tty); 403 - } 404 - // this doesn't actually push the data through unless tty->low_latency is set 405 - tty_insert_flip_char(tty, data[i], 0); 406 - } 400 + tty_buffer_request_room(tty, purb->actual_length); 401 + tty_insert_flip_string(tty, data, purb->actual_length); 407 402 tty_flip_buffer_push(tty); 408 403 } 409 404
+3 -6
drivers/usb/serial/option.c
··· 321 321 322 322 static void option_indat_callback(struct urb *urb, struct pt_regs *regs) 323 323 { 324 - int i, err; 324 + int err; 325 325 int endpoint; 326 326 struct usb_serial_port *port; 327 327 struct tty_struct *tty; ··· 338 338 } else { 339 339 tty = port->tty; 340 340 if (urb->actual_length) { 341 - for (i = 0; i < urb->actual_length ; ++i) { 342 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 343 - tty_flip_buffer_push(tty); 344 - tty_insert_flip_char(tty, data[i], 0); 345 - } 341 + tty_buffer_request_room(tty, urb->actual_length); 342 + tty_insert_flip_string(tty, data, urb->actual_length); 346 343 tty_flip_buffer_push(tty); 347 344 } else { 348 345 dbg("%s: empty read urb received", __FUNCTION__);
+2 -6
drivers/usb/serial/pl2303.c
··· 924 924 925 925 tty = port->tty; 926 926 if (tty && urb->actual_length) { 927 + tty_buffer_request_room(tty, urb->actual_length + 1); 927 928 /* overrun is special, not associated with a char */ 928 929 if (status & UART_OVERRUN_ERROR) 929 930 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 930 - 931 - for (i = 0; i < urb->actual_length; ++i) { 932 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 933 - tty_flip_buffer_push(tty); 934 - } 931 + for (i = 0; i < urb->actual_length; ++i) 935 932 tty_insert_flip_char (tty, data[i], tty_flag); 936 - } 937 933 tty_flip_buffer_push (tty); 938 934 } 939 935
+7 -13
drivers/usb/serial/ti_usb_3410_5052.c
··· 1280 1280 int cnt; 1281 1281 1282 1282 do { 1283 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 1284 - tty_flip_buffer_push(tty); 1285 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 1286 - dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length); 1287 - return; 1288 - } 1283 + cnt = tty_buffer_request_room(tty, length); 1284 + if (cnt < length) { 1285 + dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length - cnt); 1286 + if(cnt == 0) 1287 + break; 1289 1288 } 1290 - cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); 1291 - memcpy(tty->flip.char_buf_ptr, data, cnt); 1292 - memset(tty->flip.flag_buf_ptr, 0, cnt); 1293 - tty->flip.char_buf_ptr += cnt; 1294 - tty->flip.flag_buf_ptr += cnt; 1295 - tty->flip.count += cnt; 1289 + tty_insert_flip_string(tty, data, cnt); 1290 + tty_flip_buffer_push(tty); 1296 1291 data += cnt; 1297 1292 length -= cnt; 1298 1293 } while (length > 0); 1299 1294 1300 - tty_flip_buffer_push(tty); 1301 1295 } 1302 1296 1303 1297
+2 -9
drivers/usb/serial/visor.c
··· 488 488 unsigned char *data = urb->transfer_buffer; 489 489 struct tty_struct *tty; 490 490 unsigned long flags; 491 - int i; 492 491 int throttled; 493 492 int result; 494 493 ··· 502 503 503 504 tty = port->tty; 504 505 if (tty && urb->actual_length) { 505 - for (i = 0; i < urb->actual_length ; ++i) { 506 - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ 507 - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 508 - tty_flip_buffer_push(tty); 509 - } 510 - /* this doesn't actually push the data through unless tty->low_latency is set */ 511 - tty_insert_flip_char(tty, data[i], 0); 512 - } 506 + tty_buffer_request_room(tty, urb->actual_length); 507 + tty_insert_flip_string(tty, data, urb->actual_length); 513 508 tty_flip_buffer_push(tty); 514 509 } 515 510 spin_lock_irqsave(&priv->lock, flags);
+5 -6
drivers/usb/serial/whiteheat.c
··· 1434 1434 urb = wrap->urb; 1435 1435 1436 1436 if (tty && urb->actual_length) { 1437 - if (urb->actual_length > TTY_FLIPBUF_SIZE - tty->flip.count) { 1437 + int len = tty_buffer_request_room(tty, urb->actual_length); 1438 + /* This stuff can go away now I suspect */ 1439 + if (unlikely(len < urb->actual_length)) { 1438 1440 spin_lock_irqsave(&info->lock, flags); 1439 1441 list_add(tmp, &info->rx_urb_q); 1440 1442 spin_unlock_irqrestore(&info->lock, flags); ··· 1444 1442 schedule_work(&info->rx_work); 1445 1443 return; 1446 1444 } 1447 - 1448 - memcpy(tty->flip.char_buf_ptr, urb->transfer_buffer, urb->actual_length); 1449 - tty->flip.char_buf_ptr += urb->actual_length; 1450 - tty->flip.count += urb->actual_length; 1451 - sent += urb->actual_length; 1445 + tty_insert_flip_string(tty, urb->transfer_buffer, len); 1446 + sent += len; 1452 1447 } 1453 1448 1454 1449 urb->dev = port->serial->dev;
+1 -1
include/linux/kbd_kern.h
··· 151 151 152 152 static inline void con_schedule_flip(struct tty_struct *t) 153 153 { 154 - schedule_work(&t->flip.work); 154 + schedule_work(&t->buf.work); 155 155 } 156 156 157 157 #endif
+16 -9
include/linux/tty.h
··· 51 51 */ 52 52 #define TTY_FLIPBUF_SIZE 512 53 53 54 - struct tty_flip_buffer { 54 + struct tty_buffer { 55 + struct tty_buffer *next; 56 + char *char_buf_ptr; 57 + unsigned char *flag_buf_ptr; 58 + int used; 59 + int size; 60 + /* Data points here */ 61 + unsigned long data[0]; 62 + }; 63 + 64 + struct tty_bufhead { 55 65 struct work_struct work; 56 66 struct semaphore pty_sem; 57 - char *char_buf_ptr; 58 - unsigned char *flag_buf_ptr; 59 - int count; 60 - int buf_num; 61 - unsigned char char_buf[2*TTY_FLIPBUF_SIZE]; 62 - char flag_buf[2*TTY_FLIPBUF_SIZE]; 63 - unsigned char slop[4]; /* N.B. bug overwrites buffer by 1 */ 67 + struct tty_buffer *head; /* Queue head */ 68 + struct tty_buffer *tail; /* Active buffer */ 69 + struct tty_buffer *free; /* Free queue head */ 64 70 }; 65 71 /* 66 72 * The pty uses char_buf and flag_buf as a contiguous buffer ··· 192 186 unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; 193 187 unsigned char low_latency:1, warned:1; 194 188 unsigned char ctrl_status; 189 + unsigned int receive_room; /* Bytes free for queue */ 195 190 196 191 struct tty_struct *link; 197 192 struct fasync_struct *fasync; 198 - struct tty_flip_buffer flip; 193 + struct tty_bufhead buf; 199 194 int max_flip_cnt; 200 195 int alt_speed; /* For magic substitution of 38400 bps */ 201 196 wait_queue_head_t write_wait;
+14 -6
include/linux/tty_flip.h
··· 1 1 #ifndef _LINUX_TTY_FLIP_H 2 2 #define _LINUX_TTY_FLIP_H 3 3 4 + extern int tty_buffer_request_room(struct tty_struct *tty, size_t size); 5 + extern int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size); 6 + extern int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size); 7 + extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); 8 + extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); 9 + 4 10 #ifdef INCLUDE_INLINE_FUNCS 5 11 #define _INLINE_ extern 6 12 #else 7 13 #define _INLINE_ static __inline__ 8 14 #endif 9 15 10 - _INLINE_ void tty_insert_flip_char(struct tty_struct *tty, 16 + _INLINE_ int tty_insert_flip_char(struct tty_struct *tty, 11 17 unsigned char ch, char flag) 12 18 { 13 - if (tty->flip.count < TTY_FLIPBUF_SIZE) { 14 - tty->flip.count++; 15 - *tty->flip.flag_buf_ptr++ = flag; 16 - *tty->flip.char_buf_ptr++ = ch; 19 + struct tty_buffer *tb = tty->buf.tail; 20 + if (tb && tb->used < tb->size) { 21 + tb->flag_buf_ptr[tb->used] = flag; 22 + tb->char_buf_ptr[tb->used++] = ch; 23 + return 1; 17 24 } 25 + return tty_insert_flip_string_flags(tty, &ch, &flag, 1); 18 26 } 19 27 20 28 _INLINE_ void tty_schedule_flip(struct tty_struct *tty) 21 29 { 22 - schedule_delayed_work(&tty->flip.work, 1); 30 + schedule_delayed_work(&tty->buf.work, 1); 23 31 } 24 32 25 33 #undef _INLINE_
-9
include/linux/tty_ldisc.h
··· 81 81 * pointer of flag bytes which indicate whether a character was 82 82 * received with a parity error, etc. 83 83 * 84 - * int (*receive_room)(struct tty_struct *); 85 - * 86 - * This function is called by the low-level tty driver to 87 - * determine how many characters the line discpline can accept. 88 - * The low-level driver must not send more characters than was 89 - * indicated by receive_room, or the line discpline may drop 90 - * those characters. 91 - * 92 84 * void (*write_wakeup)(struct tty_struct *); 93 85 * 94 86 * This function is called by the low-level tty driver to signal ··· 128 136 */ 129 137 void (*receive_buf)(struct tty_struct *, const unsigned char *cp, 130 138 char *fp, int count); 131 - int (*receive_room)(struct tty_struct *); 132 139 void (*write_wakeup)(struct tty_struct *); 133 140 134 141 struct module *owner;
+2 -7
net/bluetooth/rfcomm/tty.c
··· 480 480 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); 481 481 482 482 if (test_bit(TTY_DONT_FLIP, &tty->flags)) { 483 - register int i; 484 - for (i = 0; i < skb->len; i++) { 485 - if (tty->flip.count >= TTY_FLIPBUF_SIZE) 486 - tty_flip_buffer_push(tty); 487 - 488 - tty_insert_flip_char(tty, skb->data[i], 0); 489 - } 483 + tty_buffer_request_room(tty, skb->len); 484 + tty_insert_flip_string(tty, skb->data, skb->len); 490 485 tty_flip_buffer_push(tty); 491 486 } else 492 487 tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);