aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/n_tty.c7
-rw-r--r--drivers/tty/pty.c2
-rw-r--r--drivers/tty/tty_buffer.c102
-rw-r--r--drivers/tty/tty_io.c2
-rw-r--r--drivers/tty/tty_ldisc.c10
-rw-r--r--drivers/tty/tty_port.c2
-rw-r--r--include/linux/tty.h6
-rw-r--r--include/linux/tty_flip.h2
8 files changed, 70 insertions, 63 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 531e539dbfc..60b076cc4e2 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -149,8 +149,11 @@ static void n_tty_set_room(struct tty_struct *tty)
149 tty->receive_room = left; 149 tty->receive_room = left;
150 150
151 /* Did this open up the receive buffer? We may need to flip */ 151 /* Did this open up the receive buffer? We may need to flip */
152 if (left && !old_left) 152 if (left && !old_left) {
153 schedule_work(&tty->buf.work); 153 WARN_RATELIMIT(tty->port->itty == NULL,
154 "scheduling with invalid itty");
155 schedule_work(&tty->port->buf.work);
156 }
154} 157}
155 158
156static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata) 159static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata)
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index c3269086267..4219f040adb 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -93,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty)
93 93
94static int pty_space(struct tty_struct *to) 94static int pty_space(struct tty_struct *to)
95{ 95{
96 int n = 8192 - to->buf.memory_used; 96 int n = 8192 - to->port->buf.memory_used;
97 if (n < 0) 97 if (n < 0)
98 return 0; 98 return 0;
99 return n; 99 return n;
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index ddd74d41cbb..06725f5cc81 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -27,9 +27,9 @@
27 * Locking: none 27 * Locking: none
28 */ 28 */
29 29
30void tty_buffer_free_all(struct tty_struct *tty) 30void tty_buffer_free_all(struct tty_port *port)
31{ 31{
32 struct tty_bufhead *buf = &tty->buf; 32 struct tty_bufhead *buf = &port->buf;
33 struct tty_buffer *thead; 33 struct tty_buffer *thead;
34 34
35 while ((thead = buf->head) != NULL) { 35 while ((thead = buf->head) != NULL) {
@@ -56,11 +56,11 @@ void tty_buffer_free_all(struct tty_struct *tty)
56 * Locking: Caller must hold tty->buf.lock 56 * Locking: Caller must hold tty->buf.lock
57 */ 57 */
58 58
59static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) 59static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size)
60{ 60{
61 struct tty_buffer *p; 61 struct tty_buffer *p;
62 62
63 if (tty->buf.memory_used + size > 65536) 63 if (port->buf.memory_used + size > 65536)
64 return NULL; 64 return NULL;
65 p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); 65 p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
66 if (p == NULL) 66 if (p == NULL)
@@ -72,7 +72,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
72 p->read = 0; 72 p->read = 0;
73 p->char_buf_ptr = (char *)(p->data); 73 p->char_buf_ptr = (char *)(p->data);
74 p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; 74 p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
75 tty->buf.memory_used += size; 75 port->buf.memory_used += size;
76 return p; 76 return p;
77} 77}
78 78
@@ -87,9 +87,9 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
87 * Locking: Caller must hold tty->buf.lock 87 * Locking: Caller must hold tty->buf.lock
88 */ 88 */
89 89
90static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) 90static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b)
91{ 91{
92 struct tty_bufhead *buf = &tty->buf; 92 struct tty_bufhead *buf = &port->buf;
93 93
94 /* Dumb strategy for now - should keep some stats */ 94 /* Dumb strategy for now - should keep some stats */
95 buf->memory_used -= b->size; 95 buf->memory_used -= b->size;
@@ -114,14 +114,14 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
114 * Locking: Caller must hold tty->buf.lock 114 * Locking: Caller must hold tty->buf.lock
115 */ 115 */
116 116
117static void __tty_buffer_flush(struct tty_struct *tty) 117static void __tty_buffer_flush(struct tty_port *port)
118{ 118{
119 struct tty_bufhead *buf = &tty->buf; 119 struct tty_bufhead *buf = &port->buf;
120 struct tty_buffer *thead; 120 struct tty_buffer *thead;
121 121
122 while ((thead = buf->head) != NULL) { 122 while ((thead = buf->head) != NULL) {
123 buf->head = thead->next; 123 buf->head = thead->next;
124 tty_buffer_free(tty, thead); 124 tty_buffer_free(port, thead);
125 } 125 }
126 buf->tail = NULL; 126 buf->tail = NULL;
127} 127}
@@ -140,7 +140,7 @@ static void __tty_buffer_flush(struct tty_struct *tty)
140void tty_buffer_flush(struct tty_struct *tty) 140void tty_buffer_flush(struct tty_struct *tty)
141{ 141{
142 struct tty_port *port = tty->port; 142 struct tty_port *port = tty->port;
143 struct tty_bufhead *buf = &tty->buf; 143 struct tty_bufhead *buf = &port->buf;
144 unsigned long flags; 144 unsigned long flags;
145 145
146 spin_lock_irqsave(&buf->lock, flags); 146 spin_lock_irqsave(&buf->lock, flags);
@@ -155,7 +155,7 @@ void tty_buffer_flush(struct tty_struct *tty)
155 test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); 155 test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
156 return; 156 return;
157 } else 157 } else
158 __tty_buffer_flush(tty); 158 __tty_buffer_flush(port);
159 spin_unlock_irqrestore(&buf->lock, flags); 159 spin_unlock_irqrestore(&buf->lock, flags);
160} 160}
161 161
@@ -171,9 +171,9 @@ void tty_buffer_flush(struct tty_struct *tty)
171 * Locking: Caller must hold tty->buf.lock 171 * Locking: Caller must hold tty->buf.lock
172 */ 172 */
173 173
174static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) 174static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size)
175{ 175{
176 struct tty_buffer **tbh = &tty->buf.free; 176 struct tty_buffer **tbh = &port->buf.free;
177 while ((*tbh) != NULL) { 177 while ((*tbh) != NULL) {
178 struct tty_buffer *t = *tbh; 178 struct tty_buffer *t = *tbh;
179 if (t->size >= size) { 179 if (t->size >= size) {
@@ -182,14 +182,14 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
182 t->used = 0; 182 t->used = 0;
183 t->commit = 0; 183 t->commit = 0;
184 t->read = 0; 184 t->read = 0;
185 tty->buf.memory_used += t->size; 185 port->buf.memory_used += t->size;
186 return t; 186 return t;
187 } 187 }
188 tbh = &((*tbh)->next); 188 tbh = &((*tbh)->next);
189 } 189 }
190 /* Round the buffer size out */ 190 /* Round the buffer size out */
191 size = (size + 0xFF) & ~0xFF; 191 size = (size + 0xFF) & ~0xFF;
192 return tty_buffer_alloc(tty, size); 192 return tty_buffer_alloc(port, size);
193 /* Should possibly check if this fails for the largest buffer we 193 /* Should possibly check if this fails for the largest buffer we
194 have queued and recycle that ? */ 194 have queued and recycle that ? */
195} 195}
@@ -200,11 +200,11 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
200 * 200 *
201 * Make at least size bytes of linear space available for the tty 201 * Make at least size bytes of linear space available for the tty
202 * buffer. If we fail return the size we managed to find. 202 * buffer. If we fail return the size we managed to find.
203 * Locking: Caller must hold tty->buf.lock 203 * Locking: Caller must hold port->buf.lock
204 */ 204 */
205static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) 205static int __tty_buffer_request_room(struct tty_port *port, size_t size)
206{ 206{
207 struct tty_bufhead *buf = &tty->buf; 207 struct tty_bufhead *buf = &port->buf;
208 struct tty_buffer *b, *n; 208 struct tty_buffer *b, *n;
209 int left; 209 int left;
210 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to 210 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
@@ -218,7 +218,7 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
218 218
219 if (left < size) { 219 if (left < size) {
220 /* This is the slow path - looking for new buffers to use */ 220 /* This is the slow path - looking for new buffers to use */
221 if ((n = tty_buffer_find(tty, size)) != NULL) { 221 if ((n = tty_buffer_find(port, size)) != NULL) {
222 if (b != NULL) { 222 if (b != NULL) {
223 b->next = n; 223 b->next = n;
224 b->commit = b->used; 224 b->commit = b->used;
@@ -241,16 +241,17 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
241 * Make at least size bytes of linear space available for the tty 241 * Make at least size bytes of linear space available for the tty
242 * buffer. If we fail return the size we managed to find. 242 * buffer. If we fail return the size we managed to find.
243 * 243 *
244 * Locking: Takes tty->buf.lock 244 * Locking: Takes port->buf.lock
245 */ 245 */
246int tty_buffer_request_room(struct tty_struct *tty, size_t size) 246int tty_buffer_request_room(struct tty_struct *tty, size_t size)
247{ 247{
248 struct tty_port *port = tty->port;
248 unsigned long flags; 249 unsigned long flags;
249 int length; 250 int length;
250 251
251 spin_lock_irqsave(&tty->buf.lock, flags); 252 spin_lock_irqsave(&port->buf.lock, flags);
252 length = __tty_buffer_request_room(tty, size); 253 length = __tty_buffer_request_room(port, size);
253 spin_unlock_irqrestore(&tty->buf.lock, flags); 254 spin_unlock_irqrestore(&port->buf.lock, flags);
254 return length; 255 return length;
255} 256}
256EXPORT_SYMBOL_GPL(tty_buffer_request_room); 257EXPORT_SYMBOL_GPL(tty_buffer_request_room);
@@ -265,13 +266,13 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
265 * Queue a series of bytes to the tty buffering. All the characters 266 * Queue a series of bytes to the tty buffering. All the characters
266 * passed are marked with the supplied flag. Returns the number added. 267 * passed are marked with the supplied flag. Returns the number added.
267 * 268 *
268 * Locking: Called functions may take tty->buf.lock 269 * Locking: Called functions may take port->buf.lock
269 */ 270 */
270 271
271int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, 272int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
272 const unsigned char *chars, char flag, size_t size) 273 const unsigned char *chars, char flag, size_t size)
273{ 274{
274 struct tty_bufhead *buf = &tty->buf; 275 struct tty_bufhead *buf = &tty->port->buf;
275 int copied = 0; 276 int copied = 0;
276 do { 277 do {
277 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); 278 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
@@ -280,7 +281,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
280 struct tty_buffer *tb; 281 struct tty_buffer *tb;
281 282
282 spin_lock_irqsave(&buf->lock, flags); 283 spin_lock_irqsave(&buf->lock, flags);
283 space = __tty_buffer_request_room(tty, goal); 284 space = __tty_buffer_request_room(tty->port, goal);
284 tb = buf->tail; 285 tb = buf->tail;
285 /* If there is no space then tb may be NULL */ 286 /* If there is no space then tb may be NULL */
286 if (unlikely(space == 0)) { 287 if (unlikely(space == 0)) {
@@ -311,13 +312,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
311 * the flags array indicates the status of the character. Returns the 312 * the flags array indicates the status of the character. Returns the
312 * number added. 313 * number added.
313 * 314 *
314 * Locking: Called functions may take tty->buf.lock 315 * Locking: Called functions may take port->buf.lock
315 */ 316 */
316 317
317int tty_insert_flip_string_flags(struct tty_struct *tty, 318int tty_insert_flip_string_flags(struct tty_struct *tty,
318 const unsigned char *chars, const char *flags, size_t size) 319 const unsigned char *chars, const char *flags, size_t size)
319{ 320{
320 struct tty_bufhead *buf = &tty->buf; 321 struct tty_bufhead *buf = &tty->port->buf;
321 int copied = 0; 322 int copied = 0;
322 do { 323 do {
323 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); 324 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
@@ -326,7 +327,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
326 struct tty_buffer *tb; 327 struct tty_buffer *tb;
327 328
328 spin_lock_irqsave(&buf->lock, __flags); 329 spin_lock_irqsave(&buf->lock, __flags);
329 space = __tty_buffer_request_room(tty, goal); 330 space = __tty_buffer_request_room(tty->port, goal);
330 tb = buf->tail; 331 tb = buf->tail;
331 /* If there is no space then tb may be NULL */ 332 /* If there is no space then tb may be NULL */
332 if (unlikely(space == 0)) { 333 if (unlikely(space == 0)) {
@@ -357,12 +358,12 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags);
357 * Note that this function can only be used when the low_latency flag 358 * Note that this function can only be used when the low_latency flag
358 * is unset. Otherwise the workqueue won't be flushed. 359 * is unset. Otherwise the workqueue won't be flushed.
359 * 360 *
360 * Locking: Takes tty->buf.lock 361 * Locking: Takes port->buf.lock
361 */ 362 */
362 363
363void tty_schedule_flip(struct tty_struct *tty) 364void tty_schedule_flip(struct tty_struct *tty)
364{ 365{
365 struct tty_bufhead *buf = &tty->buf; 366 struct tty_bufhead *buf = &tty->port->buf;
366 unsigned long flags; 367 unsigned long flags;
367 368
368 spin_lock_irqsave(&buf->lock, flags); 369 spin_lock_irqsave(&buf->lock, flags);
@@ -385,19 +386,19 @@ EXPORT_SYMBOL(tty_schedule_flip);
385 * that need their own block copy routines into the buffer. There is no 386 * that need their own block copy routines into the buffer. There is no
386 * guarantee the buffer is a DMA target! 387 * guarantee the buffer is a DMA target!
387 * 388 *
388 * Locking: May call functions taking tty->buf.lock 389 * Locking: May call functions taking port->buf.lock
389 */ 390 */
390 391
391int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, 392int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
392 size_t size) 393 size_t size)
393{ 394{
394 struct tty_bufhead *buf = &tty->buf; 395 struct tty_bufhead *buf = &tty->port->buf;
395 int space; 396 int space;
396 unsigned long flags; 397 unsigned long flags;
397 struct tty_buffer *tb; 398 struct tty_buffer *tb;
398 399
399 spin_lock_irqsave(&buf->lock, flags); 400 spin_lock_irqsave(&buf->lock, flags);
400 space = __tty_buffer_request_room(tty, size); 401 space = __tty_buffer_request_room(tty->port, size);
401 402
402 tb = buf->tail; 403 tb = buf->tail;
403 if (likely(space)) { 404 if (likely(space)) {
@@ -423,19 +424,19 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
423 * that need their own block copy routines into the buffer. There is no 424 * that need their own block copy routines into the buffer. There is no
424 * guarantee the buffer is a DMA target! 425 * guarantee the buffer is a DMA target!
425 * 426 *
426 * Locking: May call functions taking tty->buf.lock 427 * Locking: May call functions taking port->buf.lock
427 */ 428 */
428 429
429int tty_prepare_flip_string_flags(struct tty_struct *tty, 430int tty_prepare_flip_string_flags(struct tty_struct *tty,
430 unsigned char **chars, char **flags, size_t size) 431 unsigned char **chars, char **flags, size_t size)
431{ 432{
432 struct tty_bufhead *buf = &tty->buf; 433 struct tty_bufhead *buf = &tty->port->buf;
433 int space; 434 int space;
434 unsigned long __flags; 435 unsigned long __flags;
435 struct tty_buffer *tb; 436 struct tty_buffer *tb;
436 437
437 spin_lock_irqsave(&buf->lock, __flags); 438 spin_lock_irqsave(&buf->lock, __flags);
438 space = __tty_buffer_request_room(tty, size); 439 space = __tty_buffer_request_room(tty->port, size);
439 440
440 tb = buf->tail; 441 tb = buf->tail;
441 if (likely(space)) { 442 if (likely(space)) {
@@ -464,13 +465,16 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
464 465
465static void flush_to_ldisc(struct work_struct *work) 466static void flush_to_ldisc(struct work_struct *work)
466{ 467{
467 struct tty_struct *tty = 468 struct tty_port *port = container_of(work, struct tty_port, buf.work);
468 container_of(work, struct tty_struct, buf.work); 469 struct tty_bufhead *buf = &port->buf;
469 struct tty_port *port = tty->port; 470 struct tty_struct *tty;
470 struct tty_bufhead *buf = &tty->buf;
471 unsigned long flags; 471 unsigned long flags;
472 struct tty_ldisc *disc; 472 struct tty_ldisc *disc;
473 473
474 tty = port->itty;
475 if (WARN_RATELIMIT(tty == NULL, "tty is NULL"))
476 return;
477
474 disc = tty_ldisc_ref(tty); 478 disc = tty_ldisc_ref(tty);
475 if (disc == NULL) /* !TTY_LDISC */ 479 if (disc == NULL) /* !TTY_LDISC */
476 return; 480 return;
@@ -489,7 +493,7 @@ static void flush_to_ldisc(struct work_struct *work)
489 if (head->next == NULL) 493 if (head->next == NULL)
490 break; 494 break;
491 buf->head = head->next; 495 buf->head = head->next;
492 tty_buffer_free(tty, head); 496 tty_buffer_free(port, head);
493 continue; 497 continue;
494 } 498 }
495 /* Ldisc or user is trying to flush the buffers 499 /* Ldisc or user is trying to flush the buffers
@@ -515,7 +519,7 @@ static void flush_to_ldisc(struct work_struct *work)
515 /* We may have a deferred request to flush the input buffer, 519 /* We may have a deferred request to flush the input buffer,
516 if so pull the chain under the lock and empty the queue */ 520 if so pull the chain under the lock and empty the queue */
517 if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { 521 if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) {
518 __tty_buffer_flush(tty); 522 __tty_buffer_flush(port);
519 clear_bit(TTYP_FLUSHPENDING, &port->iflags); 523 clear_bit(TTYP_FLUSHPENDING, &port->iflags);
520 wake_up(&tty->read_wait); 524 wake_up(&tty->read_wait);
521 } 525 }
@@ -535,7 +539,7 @@ static void flush_to_ldisc(struct work_struct *work)
535void tty_flush_to_ldisc(struct tty_struct *tty) 539void tty_flush_to_ldisc(struct tty_struct *tty)
536{ 540{
537 if (!tty->low_latency) 541 if (!tty->low_latency)
538 flush_work(&tty->buf.work); 542 flush_work(&tty->port->buf.work);
539} 543}
540 544
541/** 545/**
@@ -553,7 +557,7 @@ void tty_flush_to_ldisc(struct tty_struct *tty)
553 557
554void tty_flip_buffer_push(struct tty_struct *tty) 558void tty_flip_buffer_push(struct tty_struct *tty)
555{ 559{
556 struct tty_bufhead *buf = &tty->buf; 560 struct tty_bufhead *buf = &tty->port->buf;
557 unsigned long flags; 561 unsigned long flags;
558 562
559 spin_lock_irqsave(&buf->lock, flags); 563 spin_lock_irqsave(&buf->lock, flags);
@@ -578,9 +582,9 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
578 * Locking: none 582 * Locking: none
579 */ 583 */
580 584
581void tty_buffer_init(struct tty_struct *tty) 585void tty_buffer_init(struct tty_port *port)
582{ 586{
583 struct tty_bufhead *buf = &tty->buf; 587 struct tty_bufhead *buf = &port->buf;
584 588
585 spin_lock_init(&buf->lock); 589 spin_lock_init(&buf->lock);
586 buf->head = NULL; 590 buf->head = NULL;
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 202008f38ca..a3eba7f359e 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -186,7 +186,6 @@ void free_tty_struct(struct tty_struct *tty)
186 if (tty->dev) 186 if (tty->dev)
187 put_device(tty->dev); 187 put_device(tty->dev);
188 kfree(tty->write_buf); 188 kfree(tty->write_buf);
189 tty_buffer_free_all(tty);
190 tty->magic = 0xDEADDEAD; 189 tty->magic = 0xDEADDEAD;
191 kfree(tty); 190 kfree(tty);
192} 191}
@@ -2935,7 +2934,6 @@ void initialize_tty_struct(struct tty_struct *tty,
2935 tty_ldisc_init(tty); 2934 tty_ldisc_init(tty);
2936 tty->session = NULL; 2935 tty->session = NULL;
2937 tty->pgrp = NULL; 2936 tty->pgrp = NULL;
2938 tty_buffer_init(tty);
2939 mutex_init(&tty->legacy_mutex); 2937 mutex_init(&tty->legacy_mutex);
2940 mutex_init(&tty->termios_mutex); 2938 mutex_init(&tty->termios_mutex);
2941 mutex_init(&tty->ldisc_mutex); 2939 mutex_init(&tty->ldisc_mutex);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 47e3968df10..f4e6754525d 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -512,7 +512,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
512static int tty_ldisc_halt(struct tty_struct *tty) 512static int tty_ldisc_halt(struct tty_struct *tty)
513{ 513{
514 clear_bit(TTY_LDISC, &tty->flags); 514 clear_bit(TTY_LDISC, &tty->flags);
515 return cancel_work_sync(&tty->buf.work); 515 return cancel_work_sync(&tty->port->buf.work);
516} 516}
517 517
518/** 518/**
@@ -525,7 +525,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
525{ 525{
526 flush_work(&tty->hangup_work); 526 flush_work(&tty->hangup_work);
527 flush_work(&tty->SAK_work); 527 flush_work(&tty->SAK_work);
528 flush_work(&tty->buf.work); 528 flush_work(&tty->port->buf.work);
529} 529}
530 530
531/** 531/**
@@ -704,9 +704,9 @@ enable:
704 /* Restart the work queue in case no characters kick it off. Safe if 704 /* Restart the work queue in case no characters kick it off. Safe if
705 already running */ 705 already running */
706 if (work) 706 if (work)
707 schedule_work(&tty->buf.work); 707 schedule_work(&tty->port->buf.work);
708 if (o_work) 708 if (o_work)
709 schedule_work(&o_tty->buf.work); 709 schedule_work(&o_tty->port->buf.work);
710 mutex_unlock(&tty->ldisc_mutex); 710 mutex_unlock(&tty->ldisc_mutex);
711 tty_unlock(tty); 711 tty_unlock(tty);
712 return retval; 712 return retval;
@@ -817,7 +817,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
817 */ 817 */
818 clear_bit(TTY_LDISC, &tty->flags); 818 clear_bit(TTY_LDISC, &tty->flags);
819 tty_unlock(tty); 819 tty_unlock(tty);
820 cancel_work_sync(&tty->buf.work); 820 cancel_work_sync(&tty->port->buf.work);
821 mutex_unlock(&tty->ldisc_mutex); 821 mutex_unlock(&tty->ldisc_mutex);
822retry: 822retry:
823 tty_lock(tty); 823 tty_lock(tty);
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index d7bdd8d0c23..416b42f7c34 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -21,6 +21,7 @@
21void tty_port_init(struct tty_port *port) 21void tty_port_init(struct tty_port *port)
22{ 22{
23 memset(port, 0, sizeof(*port)); 23 memset(port, 0, sizeof(*port));
24 tty_buffer_init(port);
24 init_waitqueue_head(&port->open_wait); 25 init_waitqueue_head(&port->open_wait);
25 init_waitqueue_head(&port->close_wait); 26 init_waitqueue_head(&port->close_wait);
26 init_waitqueue_head(&port->delta_msr_wait); 27 init_waitqueue_head(&port->delta_msr_wait);
@@ -126,6 +127,7 @@ static void tty_port_destructor(struct kref *kref)
126 struct tty_port *port = container_of(kref, struct tty_port, kref); 127 struct tty_port *port = container_of(kref, struct tty_port, kref);
127 if (port->xmit_buf) 128 if (port->xmit_buf)
128 free_page((unsigned long)port->xmit_buf); 129 free_page((unsigned long)port->xmit_buf);
130 tty_buffer_free_all(port);
129 if (port->ops->destruct) 131 if (port->ops->destruct)
130 port->ops->destruct(port); 132 port->ops->destruct(port);
131 else 133 else
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 9be74d649a5..d7ff88fb896 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -188,6 +188,7 @@ struct tty_port_operations {
188}; 188};
189 189
190struct tty_port { 190struct tty_port {
191 struct tty_bufhead buf; /* Locked internally */
191 struct tty_struct *tty; /* Back pointer */ 192 struct tty_struct *tty; /* Back pointer */
192 struct tty_struct *itty; /* internal back ptr */ 193 struct tty_struct *itty; /* internal back ptr */
193 const struct tty_port_operations *ops; /* Port operations */ 194 const struct tty_port_operations *ops; /* Port operations */
@@ -259,7 +260,6 @@ struct tty_struct {
259 260
260 struct tty_struct *link; 261 struct tty_struct *link;
261 struct fasync_struct *fasync; 262 struct fasync_struct *fasync;
262 struct tty_bufhead buf; /* Locked internally */
263 int alt_speed; /* For magic substitution of 38400 bps */ 263 int alt_speed; /* For magic substitution of 38400 bps */
264 wait_queue_head_t write_wait; 264 wait_queue_head_t write_wait;
265 wait_queue_head_t read_wait; 265 wait_queue_head_t read_wait;
@@ -388,9 +388,9 @@ extern void disassociate_ctty(int priv);
388extern void no_tty(void); 388extern void no_tty(void);
389extern void tty_flip_buffer_push(struct tty_struct *tty); 389extern void tty_flip_buffer_push(struct tty_struct *tty);
390extern void tty_flush_to_ldisc(struct tty_struct *tty); 390extern void tty_flush_to_ldisc(struct tty_struct *tty);
391extern void tty_buffer_free_all(struct tty_struct *tty); 391extern void tty_buffer_free_all(struct tty_port *port);
392extern void tty_buffer_flush(struct tty_struct *tty); 392extern void tty_buffer_flush(struct tty_struct *tty);
393extern void tty_buffer_init(struct tty_struct *tty); 393extern void tty_buffer_init(struct tty_port *port);
394extern speed_t tty_get_baud_rate(struct tty_struct *tty); 394extern speed_t tty_get_baud_rate(struct tty_struct *tty);
395extern speed_t tty_termios_baud_rate(struct ktermios *termios); 395extern speed_t tty_termios_baud_rate(struct ktermios *termios);
396extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); 396extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index 9239d033a0a..2002344ed36 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -11,7 +11,7 @@ void tty_schedule_flip(struct tty_struct *tty);
11static inline int tty_insert_flip_char(struct tty_struct *tty, 11static inline int tty_insert_flip_char(struct tty_struct *tty,
12 unsigned char ch, char flag) 12 unsigned char ch, char flag)
13{ 13{
14 struct tty_buffer *tb = tty->buf.tail; 14 struct tty_buffer *tb = tty->port->buf.tail;
15 if (tb && tb->used < tb->size) { 15 if (tb && tb->used < tb->size) {
16 tb->flag_buf_ptr[tb->used] = flag; 16 tb->flag_buf_ptr[tb->used] = flag;
17 tb->char_buf_ptr[tb->used++] = ch; 17 tb->char_buf_ptr[tb->used++] = ch;