aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:54:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:47 -0400
commitf34d7a5b7010b82fe97da95496b9971435530062 (patch)
tree87e2abec1e33ed4fe5e63ee2fd000bc2ad745e57 /drivers/char
parent251b8dd7eee30fda089a1dc088abf4fc9a0dee9c (diff)
tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects - Introduce wrappers for some optional functions to get consistent behaviour - Wrap put_char which used to be patched by the tty layer - Document which functions are needed/optional - Make put_char report success/fail - Cache the driver->ops pointer in the tty as tty->ops - Remove various surplus lock calls we no longer need - Remove proc_write method as noted by Alexey Dobriyan - Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present [akpm@linux-foundation.org: fix fs/compat_ioctl.c build] [akpm@linux-foundation.org: fix isicom] [akpm@linux-foundation.org: fix arch/ia64/hp/sim/simserial.c build] [akpm@linux-foundation.org: fix kgdb] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/ip2/ip2main.c12
-rw-r--r--drivers/char/isicom.c15
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/n_hdlc.c11
-rw-r--r--drivers/char/n_r3964.c17
-rw-r--r--drivers/char/n_tty.c103
-rw-r--r--drivers/char/tty_io.c174
-rw-r--r--drivers/char/tty_ioctl.c62
8 files changed, 183 insertions, 213 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index c4f4ca31f7c0..5ef69dcd2588 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -169,7 +169,7 @@ static int Fip_firmware_size;
169static int ip2_open(PTTY, struct file *); 169static int ip2_open(PTTY, struct file *);
170static void ip2_close(PTTY, struct file *); 170static void ip2_close(PTTY, struct file *);
171static int ip2_write(PTTY, const unsigned char *, int); 171static int ip2_write(PTTY, const unsigned char *, int);
172static void ip2_putchar(PTTY, unsigned char); 172static int ip2_putchar(PTTY, unsigned char);
173static void ip2_flush_chars(PTTY); 173static void ip2_flush_chars(PTTY);
174static int ip2_write_room(PTTY); 174static int ip2_write_room(PTTY);
175static int ip2_chars_in_buf(PTTY); 175static int ip2_chars_in_buf(PTTY);
@@ -1616,10 +1616,9 @@ ip2_close( PTTY tty, struct file *pFile )
1616 1616
1617 serviceOutgoingFifo ( pCh->pMyBord ); 1617 serviceOutgoingFifo ( pCh->pMyBord );
1618 1618
1619 if ( tty->driver->flush_buffer ) 1619 if ( tty->driver->ops->flush_buffer )
1620 tty->driver->flush_buffer(tty); 1620 tty->driver->ops->flush_buffer(tty);
1621 if ( tty->ldisc.flush_buffer ) 1621 tty_ldisc_flush(tty);
1622 tty->ldisc.flush_buffer(tty);
1623 tty->closing = 0; 1622 tty->closing = 0;
1624 1623
1625 pCh->pTTY = NULL; 1624 pCh->pTTY = NULL;
@@ -1738,7 +1737,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count)
1738/* */ 1737/* */
1739/* */ 1738/* */
1740/******************************************************************************/ 1739/******************************************************************************/
1741static void 1740static int
1742ip2_putchar( PTTY tty, unsigned char ch ) 1741ip2_putchar( PTTY tty, unsigned char ch )
1743{ 1742{
1744 i2ChanStrPtr pCh = tty->driver_data; 1743 i2ChanStrPtr pCh = tty->driver_data;
@@ -1753,6 +1752,7 @@ ip2_putchar( PTTY tty, unsigned char ch )
1753 ip2_flush_chars( tty ); 1752 ip2_flush_chars( tty );
1754 } else 1753 } else
1755 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); 1754 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1755 return 1;
1756 1756
1757// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); 1757// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1758} 1758}
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 57b115272aaa..9c6be8da220c 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1140,28 +1140,29 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1140} 1140}
1141 1141
1142/* put_char et all */ 1142/* put_char et all */
1143static void isicom_put_char(struct tty_struct *tty, unsigned char ch) 1143static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1144{ 1144{
1145 struct isi_port *port = tty->driver_data; 1145 struct isi_port *port = tty->driver_data;
1146 struct isi_board *card = port->card; 1146 struct isi_board *card = port->card;
1147 unsigned long flags; 1147 unsigned long flags;
1148 1148
1149 if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) 1149 if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1150 return; 1150 return 0;
1151 1151
1152 if (!port->xmit_buf) 1152 if (!port->xmit_buf)
1153 return; 1153 return 0;
1154 1154
1155 spin_lock_irqsave(&card->card_lock, flags); 1155 spin_lock_irqsave(&card->card_lock, flags);
1156 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) 1156 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1157 goto out; 1157 spin_unlock_irqrestore(&card->card_lock, flags);
1158 return 0;
1159 }
1158 1160
1159 port->xmit_buf[port->xmit_head++] = ch; 1161 port->xmit_buf[port->xmit_head++] = ch;
1160 port->xmit_head &= (SERIAL_XMIT_SIZE - 1); 1162 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1161 port->xmit_cnt++; 1163 port->xmit_cnt++;
1162 spin_unlock_irqrestore(&card->card_lock, flags); 1164 spin_unlock_irqrestore(&card->card_lock, flags);
1163out: 1165 return 1;
1164 return;
1165} 1166}
1166 1167
1167/* flush_chars et all */ 1168/* flush_chars et all */
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 60b934adea65..d1c50b3302e5 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1230,7 +1230,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1230 1230
1231 if (rep && 1231 if (rep &&
1232 (!vc_kbd_mode(kbd, VC_REPEAT) || 1232 (!vc_kbd_mode(kbd, VC_REPEAT) ||
1233 (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) { 1233 (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
1234 /* 1234 /*
1235 * Don't repeat a key if the input buffers are not empty and the 1235 * Don't repeat a key if the input buffers are not empty and the
1236 * characters get aren't echoed locally. This makes key repeat 1236 * characters get aren't echoed locally. This makes key repeat
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index a07c0af4819e..a35bfd7ee80e 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -342,12 +342,10 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
342#endif 342#endif
343 343
344 /* Flush any pending characters in the driver and discipline. */ 344 /* Flush any pending characters in the driver and discipline. */
345
346 if (tty->ldisc.flush_buffer) 345 if (tty->ldisc.flush_buffer)
347 tty->ldisc.flush_buffer (tty); 346 tty->ldisc.flush_buffer(tty);
348 347
349 if (tty->driver->flush_buffer) 348 tty_driver_flush_buffer(tty);
350 tty->driver->flush_buffer (tty);
351 349
352 if (debuglevel >= DEBUG_LEVEL_INFO) 350 if (debuglevel >= DEBUG_LEVEL_INFO)
353 printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__); 351 printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
@@ -399,7 +397,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
399 397
400 /* Send the next block of data to device */ 398 /* Send the next block of data to device */
401 tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); 399 tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
402 actual = tty->driver->write(tty, tbuf->buf, tbuf->count); 400 actual = tty->ops->write(tty, tbuf->buf, tbuf->count);
403 401
404 /* rollback was possible and has been done */ 402 /* rollback was possible and has been done */
405 if (actual == -ERESTARTSYS) { 403 if (actual == -ERESTARTSYS) {
@@ -752,8 +750,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
752 750
753 case TIOCOUTQ: 751 case TIOCOUTQ:
754 /* get the pending tx byte count in the driver */ 752 /* get the pending tx byte count in the driver */
755 count = tty->driver->chars_in_buffer ? 753 count = tty_chars_in_buffer(tty);
756 tty->driver->chars_in_buffer(tty) : 0;
757 /* add size of next output frame in queue */ 754 /* add size of next output frame in queue */
758 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); 755 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
759 if (n_hdlc->tx_buf_list.head) 756 if (n_hdlc->tx_buf_list.head)
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 3f6486e9f1ec..902169062332 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -376,8 +376,9 @@ static void put_char(struct r3964_info *pInfo, unsigned char ch)
376 if (tty == NULL) 376 if (tty == NULL)
377 return; 377 return;
378 378
379 if (tty->driver->put_char) { 379 /* FIXME: put_char should not be called from an IRQ */
380 tty->driver->put_char(tty, ch); 380 if (tty->ops->put_char) {
381 tty->ops->put_char(tty, ch);
381 } 382 }
382 pInfo->bcc ^= ch; 383 pInfo->bcc ^= ch;
383} 384}
@@ -386,12 +387,9 @@ static void flush(struct r3964_info *pInfo)
386{ 387{
387 struct tty_struct *tty = pInfo->tty; 388 struct tty_struct *tty = pInfo->tty;
388 389
389 if (tty == NULL) 390 if (tty == NULL || tty->ops->flush_chars == NULL)
390 return; 391 return;
391 392 tty->ops->flush_chars(tty);
392 if (tty->driver->flush_chars) {
393 tty->driver->flush_chars(tty);
394 }
395} 393}
396 394
397static void trigger_transmit(struct r3964_info *pInfo) 395static void trigger_transmit(struct r3964_info *pInfo)
@@ -449,12 +447,11 @@ static void transmit_block(struct r3964_info *pInfo)
449 struct r3964_block_header *pBlock = pInfo->tx_first; 447 struct r3964_block_header *pBlock = pInfo->tx_first;
450 int room = 0; 448 int room = 0;
451 449
452 if ((tty == NULL) || (pBlock == NULL)) { 450 if (tty == NULL || pBlock == NULL) {
453 return; 451 return;
454 } 452 }
455 453
456 if (tty->driver->write_room) 454 room = tty_write_room(tty);
457 room = tty->driver->write_room(tty);
458 455
459 TRACE_PS("transmit_block %p, room %d, length %d", 456 TRACE_PS("transmit_block %p, room %d, length %d",
460 pBlock, room, pBlock->length); 457 pBlock, room, pBlock->length);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index e1518e17e09d..abc93a93dcdd 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -149,8 +149,8 @@ static void check_unthrottle(struct tty_struct *tty)
149{ 149{
150 if (tty->count && 150 if (tty->count &&
151 test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 151 test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
152 tty->driver->unthrottle) 152 tty->ops->unthrottle)
153 tty->driver->unthrottle(tty); 153 tty->ops->unthrottle(tty);
154} 154}
155 155
156/** 156/**
@@ -273,7 +273,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
273{ 273{
274 int space, spaces; 274 int space, spaces;
275 275
276 space = tty->driver->write_room(tty); 276 space = tty_write_room(tty);
277 if (!space) 277 if (!space)
278 return -1; 278 return -1;
279 279
@@ -286,7 +286,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
286 if (O_ONLCR(tty)) { 286 if (O_ONLCR(tty)) {
287 if (space < 2) 287 if (space < 2)
288 return -1; 288 return -1;
289 tty->driver->put_char(tty, '\r'); 289 tty_put_char(tty, '\r');
290 tty->column = 0; 290 tty->column = 0;
291 } 291 }
292 tty->canon_column = tty->column; 292 tty->canon_column = tty->column;
@@ -308,7 +308,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
308 if (space < spaces) 308 if (space < spaces)
309 return -1; 309 return -1;
310 tty->column += spaces; 310 tty->column += spaces;
311 tty->driver->write(tty, " ", spaces); 311 tty->ops->write(tty, " ", spaces);
312 return 0; 312 return 0;
313 } 313 }
314 tty->column += spaces; 314 tty->column += spaces;
@@ -325,7 +325,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
325 break; 325 break;
326 } 326 }
327 } 327 }
328 tty->driver->put_char(tty, c); 328 tty_put_char(tty, c);
329 unlock_kernel(); 329 unlock_kernel();
330 return 0; 330 return 0;
331} 331}
@@ -352,7 +352,7 @@ static ssize_t opost_block(struct tty_struct *tty,
352 int i; 352 int i;
353 const unsigned char *cp; 353 const unsigned char *cp;
354 354
355 space = tty->driver->write_room(tty); 355 space = tty_write_room(tty);
356 if (!space) 356 if (!space)
357 return 0; 357 return 0;
358 if (nr > space) 358 if (nr > space)
@@ -390,28 +390,15 @@ static ssize_t opost_block(struct tty_struct *tty,
390 } 390 }
391 } 391 }
392break_out: 392break_out:
393 if (tty->driver->flush_chars) 393 if (tty->ops->flush_chars)
394 tty->driver->flush_chars(tty); 394 tty->ops->flush_chars(tty);
395 i = tty->driver->write(tty, buf, i); 395 i = tty->ops->write(tty, buf, i);
396 unlock_kernel(); 396 unlock_kernel();
397 return i; 397 return i;
398} 398}
399 399
400 400
401/** 401/**
402 * put_char - write character to driver
403 * @c: character (or part of unicode symbol)
404 * @tty: terminal device
405 *
406 * Queue a byte to the driver layer for output
407 */
408
409static inline void put_char(unsigned char c, struct tty_struct *tty)
410{
411 tty->driver->put_char(tty, c);
412}
413
414/**
415 * echo_char - echo characters 402 * echo_char - echo characters
416 * @c: unicode byte to echo 403 * @c: unicode byte to echo
417 * @tty: terminal device 404 * @tty: terminal device
@@ -423,8 +410,8 @@ static inline void put_char(unsigned char c, struct tty_struct *tty)
423static void echo_char(unsigned char c, struct tty_struct *tty) 410static void echo_char(unsigned char c, struct tty_struct *tty)
424{ 411{
425 if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') { 412 if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') {
426 put_char('^', tty); 413 tty_put_char(tty, '^');
427 put_char(c ^ 0100, tty); 414 tty_put_char(tty, c ^ 0100);
428 tty->column += 2; 415 tty->column += 2;
429 } else 416 } else
430 opost(c, tty); 417 opost(c, tty);
@@ -433,7 +420,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
433static inline void finish_erasing(struct tty_struct *tty) 420static inline void finish_erasing(struct tty_struct *tty)
434{ 421{
435 if (tty->erasing) { 422 if (tty->erasing) {
436 put_char('/', tty); 423 tty_put_char(tty, '/');
437 tty->column++; 424 tty->column++;
438 tty->erasing = 0; 425 tty->erasing = 0;
439 } 426 }
@@ -517,7 +504,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
517 if (L_ECHO(tty)) { 504 if (L_ECHO(tty)) {
518 if (L_ECHOPRT(tty)) { 505 if (L_ECHOPRT(tty)) {
519 if (!tty->erasing) { 506 if (!tty->erasing) {
520 put_char('\\', tty); 507 tty_put_char(tty, '\\');
521 tty->column++; 508 tty->column++;
522 tty->erasing = 1; 509 tty->erasing = 1;
523 } 510 }
@@ -525,7 +512,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
525 echo_char(c, tty); 512 echo_char(c, tty);
526 while (--cnt > 0) { 513 while (--cnt > 0) {
527 head = (head+1) & (N_TTY_BUF_SIZE-1); 514 head = (head+1) & (N_TTY_BUF_SIZE-1);
528 put_char(tty->read_buf[head], tty); 515 tty_put_char(tty, tty->read_buf[head]);
529 } 516 }
530 } else if (kill_type == ERASE && !L_ECHOE(tty)) { 517 } else if (kill_type == ERASE && !L_ECHOE(tty)) {
531 echo_char(ERASE_CHAR(tty), tty); 518 echo_char(ERASE_CHAR(tty), tty);
@@ -553,22 +540,22 @@ static void eraser(unsigned char c, struct tty_struct *tty)
553 /* Now backup to that column. */ 540 /* Now backup to that column. */
554 while (tty->column > col) { 541 while (tty->column > col) {
555 /* Can't use opost here. */ 542 /* Can't use opost here. */
556 put_char('\b', tty); 543 tty_put_char(tty, '\b');
557 if (tty->column > 0) 544 if (tty->column > 0)
558 tty->column--; 545 tty->column--;
559 } 546 }
560 } else { 547 } else {
561 if (iscntrl(c) && L_ECHOCTL(tty)) { 548 if (iscntrl(c) && L_ECHOCTL(tty)) {
562 put_char('\b', tty); 549 tty_put_char(tty, '\b');
563 put_char(' ', tty); 550 tty_put_char(tty, ' ');
564 put_char('\b', tty); 551 tty_put_char(tty, '\b');
565 if (tty->column > 0) 552 if (tty->column > 0)
566 tty->column--; 553 tty->column--;
567 } 554 }
568 if (!iscntrl(c) || L_ECHOCTL(tty)) { 555 if (!iscntrl(c) || L_ECHOCTL(tty)) {
569 put_char('\b', tty); 556 tty_put_char(tty, '\b');
570 put_char(' ', tty); 557 tty_put_char(tty, ' ');
571 put_char('\b', tty); 558 tty_put_char(tty, '\b');
572 if (tty->column > 0) 559 if (tty->column > 0)
573 tty->column--; 560 tty->column--;
574 } 561 }
@@ -599,8 +586,7 @@ static inline void isig(int sig, struct tty_struct *tty, int flush)
599 kill_pgrp(tty->pgrp, sig, 1); 586 kill_pgrp(tty->pgrp, sig, 1);
600 if (flush || !L_NOFLSH(tty)) { 587 if (flush || !L_NOFLSH(tty)) {
601 n_tty_flush_buffer(tty); 588 n_tty_flush_buffer(tty);
602 if (tty->driver->flush_buffer) 589 tty_driver_flush_buffer(tty);
603 tty->driver->flush_buffer(tty);
604 } 590 }
605} 591}
606 592
@@ -732,7 +718,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
732 tty->lnext = 0; 718 tty->lnext = 0;
733 if (L_ECHO(tty)) { 719 if (L_ECHO(tty)) {
734 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { 720 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
735 put_char('\a', tty); /* beep if no space */ 721 tty_put_char(tty, '\a'); /* beep if no space */
736 return; 722 return;
737 } 723 }
738 /* Record the column of first canon char. */ 724 /* Record the column of first canon char. */
@@ -776,8 +762,7 @@ send_signal:
776 */ 762 */
777 if (!L_NOFLSH(tty)) { 763 if (!L_NOFLSH(tty)) {
778 n_tty_flush_buffer(tty); 764 n_tty_flush_buffer(tty);
779 if (tty->driver->flush_buffer) 765 tty_driver_flush_buffer(tty);
780 tty->driver->flush_buffer(tty);
781 } 766 }
782 if (L_ECHO(tty)) 767 if (L_ECHO(tty))
783 echo_char(c, tty); 768 echo_char(c, tty);
@@ -806,8 +791,8 @@ send_signal:
806 if (L_ECHO(tty)) { 791 if (L_ECHO(tty)) {
807 finish_erasing(tty); 792 finish_erasing(tty);
808 if (L_ECHOCTL(tty)) { 793 if (L_ECHOCTL(tty)) {
809 put_char('^', tty); 794 tty_put_char(tty, '^');
810 put_char('\b', tty); 795 tty_put_char(tty, '\b');
811 } 796 }
812 } 797 }
813 return; 798 return;
@@ -828,7 +813,7 @@ send_signal:
828 if (c == '\n') { 813 if (c == '\n') {
829 if (L_ECHO(tty) || L_ECHONL(tty)) { 814 if (L_ECHO(tty) || L_ECHONL(tty)) {
830 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) 815 if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
831 put_char('\a', tty); 816 tty_put_char(tty, '\a');
832 opost('\n', tty); 817 opost('\n', tty);
833 } 818 }
834 goto handle_newline; 819 goto handle_newline;
@@ -846,7 +831,7 @@ send_signal:
846 */ 831 */
847 if (L_ECHO(tty)) { 832 if (L_ECHO(tty)) {
848 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) 833 if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
849 put_char('\a', tty); 834 tty_put_char(tty, '\a');
850 /* Record the column of first canon char. */ 835 /* Record the column of first canon char. */
851 if (tty->canon_head == tty->read_head) 836 if (tty->canon_head == tty->read_head)
852 tty->canon_column = tty->column; 837 tty->canon_column = tty->column;
@@ -876,7 +861,7 @@ handle_newline:
876 finish_erasing(tty); 861 finish_erasing(tty);
877 if (L_ECHO(tty)) { 862 if (L_ECHO(tty)) {
878 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { 863 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
879 put_char('\a', tty); /* beep if no space */ 864 tty_put_char(tty, '\a'); /* beep if no space */
880 return; 865 return;
881 } 866 }
882 if (c == '\n') 867 if (c == '\n')
@@ -980,8 +965,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
980 break; 965 break;
981 } 966 }
982 } 967 }
983 if (tty->driver->flush_chars) 968 if (tty->ops->flush_chars)
984 tty->driver->flush_chars(tty); 969 tty->ops->flush_chars(tty);
985 } 970 }
986 971
987 n_tty_set_room(tty); 972 n_tty_set_room(tty);
@@ -1000,8 +985,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1000 if (tty->receive_room < TTY_THRESHOLD_THROTTLE) { 985 if (tty->receive_room < TTY_THRESHOLD_THROTTLE) {
1001 /* check TTY_THROTTLED first so it indicates our state */ 986 /* check TTY_THROTTLED first so it indicates our state */
1002 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && 987 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
1003 tty->driver->throttle) 988 tty->ops->throttle)
1004 tty->driver->throttle(tty); 989 tty->ops->throttle(tty);
1005 } 990 }
1006} 991}
1007 992
@@ -1086,6 +1071,9 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
1086 tty->real_raw = 0; 1071 tty->real_raw = 0;
1087 } 1072 }
1088 n_tty_set_room(tty); 1073 n_tty_set_room(tty);
1074 /* The termios change make the tty ready for I/O */
1075 wake_up_interruptible(&tty->write_wait);
1076 wake_up_interruptible(&tty->read_wait);
1089} 1077}
1090 1078
1091/** 1079/**
@@ -1513,11 +1501,11 @@ static ssize_t write_chan(struct tty_struct *tty, struct file *file,
1513 break; 1501 break;
1514 b++; nr--; 1502 b++; nr--;
1515 } 1503 }
1516 if (tty->driver->flush_chars) 1504 if (tty->ops->flush_chars)
1517 tty->driver->flush_chars(tty); 1505 tty->ops->flush_chars(tty);
1518 } else { 1506 } else {
1519 while (nr > 0) { 1507 while (nr > 0) {
1520 c = tty->driver->write(tty, b, nr); 1508 c = tty->ops->write(tty, b, nr);
1521 if (c < 0) { 1509 if (c < 0) {
1522 retval = c; 1510 retval = c;
1523 goto break_out; 1511 goto break_out;
@@ -1554,11 +1542,6 @@ break_out:
1554 * 1542 *
1555 * This code must be sure never to sleep through a hangup. 1543 * This code must be sure never to sleep through a hangup.
1556 * Called without the kernel lock held - fine 1544 * Called without the kernel lock held - fine
1557 *
1558 * FIXME: if someone changes the VMIN or discipline settings for the
1559 * terminal while another process is in poll() the poll does not
1560 * recompute the new limits. Possibly set_termios should issue
1561 * a read wakeup to fix this bug.
1562 */ 1545 */
1563 1546
1564static unsigned int normal_poll(struct tty_struct *tty, struct file *file, 1547static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
@@ -1582,9 +1565,9 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
1582 else 1565 else
1583 tty->minimum_to_wake = 1; 1566 tty->minimum_to_wake = 1;
1584 } 1567 }
1585 if (!tty_is_writelocked(tty) && 1568 if (tty->ops->write && !tty_is_writelocked(tty) &&
1586 tty->driver->chars_in_buffer(tty) < WAKEUP_CHARS && 1569 tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
1587 tty->driver->write_room(tty) > 0) 1570 tty_write_room(tty) > 0)
1588 mask |= POLLOUT | POLLWRNORM; 1571 mask |= POLLOUT | POLLWRNORM;
1589 return mask; 1572 return mask;
1590} 1573}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index b1692afd797e..f69fb8d7a680 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1108,8 +1108,8 @@ restart:
1108 a reference to the old ldisc. If we ended up flipping back 1108 a reference to the old ldisc. If we ended up flipping back
1109 to the existing ldisc we have two references to it */ 1109 to the existing ldisc we have two references to it */
1110 1110
1111 if (tty->ldisc.num != o_ldisc.num && tty->driver->set_ldisc) 1111 if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc)
1112 tty->driver->set_ldisc(tty); 1112 tty->ops->set_ldisc(tty);
1113 1113
1114 tty_ldisc_put(o_ldisc.num); 1114 tty_ldisc_put(o_ldisc.num);
1115 1115
@@ -1181,9 +1181,8 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
1181 if (*str == '\0') 1181 if (*str == '\0')
1182 str = NULL; 1182 str = NULL;
1183 1183
1184 if (tty_line >= 0 && tty_line <= p->num && p->poll_init && 1184 if (tty_line >= 0 && tty_line <= p->num && p->ops &&
1185 !p->poll_init(p, tty_line, str)) { 1185 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) {
1186
1187 res = p; 1186 res = p;
1188 *line = tty_line; 1187 *line = tty_line;
1189 break; 1188 break;
@@ -1452,8 +1451,7 @@ static void do_tty_hangup(struct work_struct *work)
1452 /* We may have no line discipline at this point */ 1451 /* We may have no line discipline at this point */
1453 if (ld->flush_buffer) 1452 if (ld->flush_buffer)
1454 ld->flush_buffer(tty); 1453 ld->flush_buffer(tty);
1455 if (tty->driver->flush_buffer) 1454 tty_driver_flush_buffer(tty);
1456 tty->driver->flush_buffer(tty);
1457 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && 1455 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
1458 ld->write_wakeup) 1456 ld->write_wakeup)
1459 ld->write_wakeup(tty); 1457 ld->write_wakeup(tty);
@@ -1516,11 +1514,11 @@ static void do_tty_hangup(struct work_struct *work)
1516 * So we just call close() the right number of times. 1514 * So we just call close() the right number of times.
1517 */ 1515 */
1518 if (cons_filp) { 1516 if (cons_filp) {
1519 if (tty->driver->close) 1517 if (tty->ops->close)
1520 for (n = 0; n < closecount; n++) 1518 for (n = 0; n < closecount; n++)
1521 tty->driver->close(tty, cons_filp); 1519 tty->ops->close(tty, cons_filp);
1522 } else if (tty->driver->hangup) 1520 } else if (tty->ops->hangup)
1523 (tty->driver->hangup)(tty); 1521 (tty->ops->hangup)(tty);
1524 /* 1522 /*
1525 * We don't want to have driver/ldisc interactions beyond 1523 * We don't want to have driver/ldisc interactions beyond
1526 * the ones we did here. The driver layer expects no 1524 * the ones we did here. The driver layer expects no
@@ -1752,8 +1750,8 @@ void stop_tty(struct tty_struct *tty)
1752 wake_up_interruptible(&tty->link->read_wait); 1750 wake_up_interruptible(&tty->link->read_wait);
1753 } 1751 }
1754 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 1752 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1755 if (tty->driver->stop) 1753 if (tty->ops->stop)
1756 (tty->driver->stop)(tty); 1754 (tty->ops->stop)(tty);
1757} 1755}
1758 1756
1759EXPORT_SYMBOL(stop_tty); 1757EXPORT_SYMBOL(stop_tty);
@@ -1786,8 +1784,8 @@ void start_tty(struct tty_struct *tty)
1786 wake_up_interruptible(&tty->link->read_wait); 1784 wake_up_interruptible(&tty->link->read_wait);
1787 } 1785 }
1788 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 1786 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1789 if (tty->driver->start) 1787 if (tty->ops->start)
1790 (tty->driver->start)(tty); 1788 (tty->ops->start)(tty);
1791 /* If we have a running line discipline it may need kicking */ 1789 /* If we have a running line discipline it may need kicking */
1792 tty_wakeup(tty); 1790 tty_wakeup(tty);
1793} 1791}
@@ -1972,10 +1970,13 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
1972 tty = (struct tty_struct *)file->private_data; 1970 tty = (struct tty_struct *)file->private_data;
1973 if (tty_paranoia_check(tty, inode, "tty_write")) 1971 if (tty_paranoia_check(tty, inode, "tty_write"))
1974 return -EIO; 1972 return -EIO;
1975 if (!tty || !tty->driver->write || 1973 if (!tty || !tty->ops->write ||
1976 (test_bit(TTY_IO_ERROR, &tty->flags))) 1974 (test_bit(TTY_IO_ERROR, &tty->flags)))
1977 return -EIO; 1975 return -EIO;
1978 1976 /* Short term debug to catch buggy drivers */
1977 if (tty->ops->write_room == NULL)
1978 printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
1979 tty->driver->name);
1979 ld = tty_ldisc_ref_wait(tty); 1980 ld = tty_ldisc_ref_wait(tty);
1980 if (!ld->write) 1981 if (!ld->write)
1981 ret = -EIO; 1982 ret = -EIO;
@@ -2122,6 +2123,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2122 goto fail_no_mem; 2123 goto fail_no_mem;
2123 initialize_tty_struct(tty); 2124 initialize_tty_struct(tty);
2124 tty->driver = driver; 2125 tty->driver = driver;
2126 tty->ops = driver->ops;
2125 tty->index = idx; 2127 tty->index = idx;
2126 tty_line_name(driver, idx, tty->name); 2128 tty_line_name(driver, idx, tty->name);
2127 2129
@@ -2152,6 +2154,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2152 goto free_mem_out; 2154 goto free_mem_out;
2153 initialize_tty_struct(o_tty); 2155 initialize_tty_struct(o_tty);
2154 o_tty->driver = driver->other; 2156 o_tty->driver = driver->other;
2157 o_tty->ops = driver->ops;
2155 o_tty->index = idx; 2158 o_tty->index = idx;
2156 tty_line_name(driver->other, idx, o_tty->name); 2159 tty_line_name(driver->other, idx, o_tty->name);
2157 2160
@@ -2456,8 +2459,8 @@ static void release_dev(struct file *filp)
2456 } 2459 }
2457 } 2460 }
2458#endif 2461#endif
2459 if (tty->driver->close) 2462 if (tty->ops->close)
2460 tty->driver->close(tty, filp); 2463 tty->ops->close(tty, filp);
2461 2464
2462 /* 2465 /*
2463 * Sanity check: if tty->count is going to zero, there shouldn't be 2466 * Sanity check: if tty->count is going to zero, there shouldn't be
@@ -2740,8 +2743,8 @@ got_driver:
2740 printk(KERN_DEBUG "opening %s...", tty->name); 2743 printk(KERN_DEBUG "opening %s...", tty->name);
2741#endif 2744#endif
2742 if (!retval) { 2745 if (!retval) {
2743 if (tty->driver->open) 2746 if (tty->ops->open)
2744 retval = tty->driver->open(tty, filp); 2747 retval = tty->ops->open(tty, filp);
2745 else 2748 else
2746 retval = -ENODEV; 2749 retval = -ENODEV;
2747 } 2750 }
@@ -2840,7 +2843,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
2840 goto out1; 2843 goto out1;
2841 2844
2842 check_tty_count(tty, "tty_open"); 2845 check_tty_count(tty, "tty_open");
2843 retval = ptm_driver->open(tty, filp); 2846 retval = ptm_driver->ops->open(tty, filp);
2844 if (!retval) 2847 if (!retval)
2845 return 0; 2848 return 0;
2846out1: 2849out1:
@@ -3336,25 +3339,20 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
3336 3339
3337static int send_break(struct tty_struct *tty, unsigned int duration) 3340static int send_break(struct tty_struct *tty, unsigned int duration)
3338{ 3341{
3339 int retval = -EINTR;
3340
3341 lock_kernel();
3342 if (tty_write_lock(tty, 0) < 0) 3342 if (tty_write_lock(tty, 0) < 0)
3343 goto out; 3343 return -EINTR;
3344 tty->driver->break_ctl(tty, -1); 3344 tty->ops->break_ctl(tty, -1);
3345 if (!signal_pending(current)) 3345 if (!signal_pending(current))
3346 msleep_interruptible(duration); 3346 msleep_interruptible(duration);
3347 tty->driver->break_ctl(tty, 0); 3347 tty->ops->break_ctl(tty, 0);
3348 tty_write_unlock(tty); 3348 tty_write_unlock(tty);
3349 if (!signal_pending(current)) 3349 if (!signal_pending(current))
3350 retval = 0; 3350 return -EINTR;
3351out: 3351 return 0;
3352 unlock_kernel();
3353 return retval;
3354} 3352}
3355 3353
3356/** 3354/**
3357 * tiocmget - get modem status 3355 * tty_tiocmget - get modem status
3358 * @tty: tty device 3356 * @tty: tty device
3359 * @file: user file pointer 3357 * @file: user file pointer
3360 * @p: pointer to result 3358 * @p: pointer to result
@@ -3369,10 +3367,8 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
3369{ 3367{
3370 int retval = -EINVAL; 3368 int retval = -EINVAL;
3371 3369
3372 if (tty->driver->tiocmget) { 3370 if (tty->ops->tiocmget) {
3373 lock_kernel(); 3371 retval = tty->ops->tiocmget(tty, file);
3374 retval = tty->driver->tiocmget(tty, file);
3375 unlock_kernel();
3376 3372
3377 if (retval >= 0) 3373 if (retval >= 0)
3378 retval = put_user(retval, p); 3374 retval = put_user(retval, p);
@@ -3381,7 +3377,7 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
3381} 3377}
3382 3378
3383/** 3379/**
3384 * tiocmset - set modem status 3380 * tty_tiocmset - set modem status
3385 * @tty: tty device 3381 * @tty: tty device
3386 * @file: user file pointer 3382 * @file: user file pointer
3387 * @cmd: command - clear bits, set bits or set all 3383 * @cmd: command - clear bits, set bits or set all
@@ -3398,7 +3394,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
3398{ 3394{
3399 int retval = -EINVAL; 3395 int retval = -EINVAL;
3400 3396
3401 if (tty->driver->tiocmset) { 3397 if (tty->ops->tiocmset) {
3402 unsigned int set, clear, val; 3398 unsigned int set, clear, val;
3403 3399
3404 retval = get_user(val, p); 3400 retval = get_user(val, p);
@@ -3422,9 +3418,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
3422 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3418 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3423 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3419 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3424 3420
3425 lock_kernel(); 3421 retval = tty->ops->tiocmset(tty, file, set, clear);
3426 retval = tty->driver->tiocmset(tty, file, set, clear);
3427 unlock_kernel();
3428 } 3422 }
3429 return retval; 3423 return retval;
3430} 3424}
@@ -3455,23 +3449,25 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3455 3449
3456 retval = -EINVAL; 3450 retval = -EINVAL;
3457 3451
3458 if (!tty->driver->break_ctl) { 3452 if (!tty->ops->break_ctl) {
3459 switch (cmd) { 3453 switch (cmd) {
3460 case TIOCSBRK: 3454 case TIOCSBRK:
3461 case TIOCCBRK: 3455 case TIOCCBRK:
3462 if (tty->driver->ioctl) 3456 if (tty->ops->ioctl)
3463 retval = tty->driver->ioctl(tty, file, cmd, arg); 3457 retval = tty->ops->ioctl(tty, file, cmd, arg);
3458 if (retval != -EINVAL && retval != -ENOIOCTLCMD)
3459 printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
3464 return retval; 3460 return retval;
3465 3461
3466 /* These two ioctl's always return success; even if */ 3462 /* These two ioctl's always return success; even if */
3467 /* the driver doesn't support them. */ 3463 /* the driver doesn't support them. */
3468 case TCSBRK: 3464 case TCSBRK:
3469 case TCSBRKP: 3465 case TCSBRKP:
3470 if (!tty->driver->ioctl) 3466 if (!tty->ops->ioctl)
3471 return 0; 3467 return 0;
3472 lock_kernel(); 3468 retval = tty->ops->ioctl(tty, file, cmd, arg);
3473 retval = tty->driver->ioctl(tty, file, cmd, arg); 3469 if (retval != -EINVAL && retval != -ENOIOCTLCMD)
3474 unlock_kernel(); 3470 printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
3475 if (retval == -ENOIOCTLCMD) 3471 if (retval == -ENOIOCTLCMD)
3476 retval = 0; 3472 retval = 0;
3477 return retval; 3473 return retval;
@@ -3491,9 +3487,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3491 if (retval) 3487 if (retval)
3492 return retval; 3488 return retval;
3493 if (cmd != TIOCCBRK) { 3489 if (cmd != TIOCCBRK) {
3494 lock_kernel();
3495 tty_wait_until_sent(tty, 0); 3490 tty_wait_until_sent(tty, 0);
3496 unlock_kernel();
3497 if (signal_pending(current)) 3491 if (signal_pending(current))
3498 return -EINTR; 3492 return -EINTR;
3499 } 3493 }
@@ -3531,7 +3525,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3531 case TIOCGSID: 3525 case TIOCGSID:
3532 return tiocgsid(tty, real_tty, p); 3526 return tiocgsid(tty, real_tty, p);
3533 case TIOCGETD: 3527 case TIOCGETD:
3534 /* FIXME: check this is ok */
3535 return put_user(tty->ldisc.num, (int __user *)p); 3528 return put_user(tty->ldisc.num, (int __user *)p);
3536 case TIOCSETD: 3529 case TIOCSETD:
3537 return tiocsetd(tty, p); 3530 return tiocsetd(tty, p);
@@ -3543,15 +3536,13 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3543 * Break handling 3536 * Break handling
3544 */ 3537 */
3545 case TIOCSBRK: /* Turn break on, unconditionally */ 3538 case TIOCSBRK: /* Turn break on, unconditionally */
3546 lock_kernel(); 3539 if (tty->ops->break_ctl)
3547 tty->driver->break_ctl(tty, -1); 3540 tty->ops->break_ctl(tty, -1);
3548 unlock_kernel();
3549 return 0; 3541 return 0;
3550 3542
3551 case TIOCCBRK: /* Turn break off, unconditionally */ 3543 case TIOCCBRK: /* Turn break off, unconditionally */
3552 lock_kernel(); 3544 if (tty->ops->break_ctl)
3553 tty->driver->break_ctl(tty, 0); 3545 tty->ops->break_ctl(tty, 0);
3554 unlock_kernel();
3555 return 0; 3546 return 0;
3556 case TCSBRK: /* SVID version: non-zero arg --> no break */ 3547 case TCSBRK: /* SVID version: non-zero arg --> no break */
3557 /* non-zero arg means wait for all output data 3548 /* non-zero arg means wait for all output data
@@ -3580,8 +3571,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3580 } 3571 }
3581 break; 3572 break;
3582 } 3573 }
3583 if (tty->driver->ioctl) { 3574 if (tty->ops->ioctl) {
3584 retval = (tty->driver->ioctl)(tty, file, cmd, arg); 3575 retval = (tty->ops->ioctl)(tty, file, cmd, arg);
3585 if (retval != -ENOIOCTLCMD) 3576 if (retval != -ENOIOCTLCMD)
3586 return retval; 3577 return retval;
3587 } 3578 }
@@ -3608,8 +3599,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
3608 if (tty_paranoia_check(tty, inode, "tty_ioctl")) 3599 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
3609 return -EINVAL; 3600 return -EINVAL;
3610 3601
3611 if (tty->driver->compat_ioctl) { 3602 if (tty->ops->compat_ioctl) {
3612 retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg); 3603 retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
3613 if (retval != -ENOIOCTLCMD) 3604 if (retval != -ENOIOCTLCMD)
3614 return retval; 3605 return retval;
3615 } 3606 }
@@ -3659,8 +3650,7 @@ void __do_SAK(struct tty_struct *tty)
3659 3650
3660 tty_ldisc_flush(tty); 3651 tty_ldisc_flush(tty);
3661 3652
3662 if (tty->driver->flush_buffer) 3653 tty_driver_flush_buffer(tty);
3663 tty->driver->flush_buffer(tty);
3664 3654
3665 read_lock(&tasklist_lock); 3655 read_lock(&tasklist_lock);
3666 /* Kill the entire session */ 3656 /* Kill the entire session */
@@ -3871,15 +3861,27 @@ static void initialize_tty_struct(struct tty_struct *tty)
3871 INIT_WORK(&tty->SAK_work, do_SAK_work); 3861 INIT_WORK(&tty->SAK_work, do_SAK_work);
3872} 3862}
3873 3863
3874/* 3864/**
3875 * The default put_char routine if the driver did not define one. 3865 * tty_put_char - write one character to a tty
3866 * @tty: tty
3867 * @ch: character
3868 *
3869 * Write one byte to the tty using the provided put_char method
3870 * if present. Returns the number of characters successfully output.
3871 *
3872 * Note: the specific put_char operation in the driver layer may go
3873 * away soon. Don't call it directly, use this method
3876 */ 3874 */
3877 3875
3878static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) 3876int tty_put_char(struct tty_struct *tty, unsigned char ch)
3879{ 3877{
3880 tty->driver->write(tty, &ch, 1); 3878 if (tty->ops->put_char)
3879 return tty->ops->put_char(tty, ch);
3880 return tty->ops->write(tty, &ch, 1);
3881} 3881}
3882 3882
3883EXPORT_SYMBOL_GPL(tty_put_char);
3884
3883static struct class *tty_class; 3885static struct class *tty_class;
3884 3886
3885/** 3887/**
@@ -3962,37 +3964,8 @@ void put_tty_driver(struct tty_driver *driver)
3962void tty_set_operations(struct tty_driver *driver, 3964void tty_set_operations(struct tty_driver *driver,
3963 const struct tty_operations *op) 3965 const struct tty_operations *op)
3964{ 3966{
3965 driver->open = op->open; 3967 driver->ops = op;
3966 driver->close = op->close; 3968};
3967 driver->write = op->write;
3968 driver->put_char = op->put_char;
3969 driver->flush_chars = op->flush_chars;
3970 driver->write_room = op->write_room;
3971 driver->chars_in_buffer = op->chars_in_buffer;
3972 driver->ioctl = op->ioctl;
3973 driver->compat_ioctl = op->compat_ioctl;
3974 driver->set_termios = op->set_termios;
3975 driver->throttle = op->throttle;
3976 driver->unthrottle = op->unthrottle;
3977 driver->stop = op->stop;
3978 driver->start = op->start;
3979 driver->hangup = op->hangup;
3980 driver->break_ctl = op->break_ctl;
3981 driver->flush_buffer = op->flush_buffer;
3982 driver->set_ldisc = op->set_ldisc;
3983 driver->wait_until_sent = op->wait_until_sent;
3984 driver->send_xchar = op->send_xchar;
3985 driver->read_proc = op->read_proc;
3986 driver->write_proc = op->write_proc;
3987 driver->tiocmget = op->tiocmget;
3988 driver->tiocmset = op->tiocmset;
3989#ifdef CONFIG_CONSOLE_POLL
3990 driver->poll_init = op->poll_init;
3991 driver->poll_get_char = op->poll_get_char;
3992 driver->poll_put_char = op->poll_put_char;
3993#endif
3994}
3995
3996 3969
3997EXPORT_SYMBOL(alloc_tty_driver); 3970EXPORT_SYMBOL(alloc_tty_driver);
3998EXPORT_SYMBOL(put_tty_driver); 3971EXPORT_SYMBOL(put_tty_driver);
@@ -4055,9 +4028,6 @@ int tty_register_driver(struct tty_driver *driver)
4055 return error; 4028 return error;
4056 } 4029 }
4057 4030
4058 if (!driver->put_char)
4059 driver->put_char = tty_default_put_char;
4060
4061 mutex_lock(&tty_mutex); 4031 mutex_lock(&tty_mutex);
4062 list_add(&driver->tty_drivers, &tty_drivers); 4032 list_add(&driver->tty_drivers, &tty_drivers);
4063 mutex_unlock(&tty_mutex); 4033 mutex_unlock(&tty_mutex);
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 8c4bf3e48d5b..c10d40c4c5ca 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -40,6 +40,34 @@
40#define TERMIOS_OLD 8 40#define TERMIOS_OLD 8
41 41
42 42
43int tty_chars_in_buffer(struct tty_struct *tty)
44{
45 if (tty->ops->chars_in_buffer)
46 return tty->ops->chars_in_buffer(tty);
47 else
48 return 0;
49}
50
51EXPORT_SYMBOL(tty_chars_in_buffer);
52
53int tty_write_room(struct tty_struct *tty)
54{
55 if (tty->ops->write_room)
56 return tty->ops->write_room(tty);
57 return 2048;
58}
59
60EXPORT_SYMBOL(tty_write_room);
61
62void tty_driver_flush_buffer(struct tty_struct *tty)
63{
64 if (tty->ops->flush_buffer)
65 tty->ops->flush_buffer(tty);
66}
67
68EXPORT_SYMBOL(tty_driver_flush_buffer);
69
70
43/** 71/**
44 * tty_wait_until_sent - wait for I/O to finish 72 * tty_wait_until_sent - wait for I/O to finish
45 * @tty: tty we are waiting for 73 * @tty: tty we are waiting for
@@ -58,17 +86,13 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
58 86
59 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); 87 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
60#endif 88#endif
61 if (!tty->driver->chars_in_buffer)
62 return;
63 if (!timeout) 89 if (!timeout)
64 timeout = MAX_SCHEDULE_TIMEOUT; 90 timeout = MAX_SCHEDULE_TIMEOUT;
65 lock_kernel();
66 if (wait_event_interruptible_timeout(tty->write_wait, 91 if (wait_event_interruptible_timeout(tty->write_wait,
67 !tty->driver->chars_in_buffer(tty), timeout) >= 0) { 92 !tty_chars_in_buffer(tty), timeout) >= 0) {
68 if (tty->driver->wait_until_sent) 93 if (tty->ops->wait_until_sent)
69 tty->driver->wait_until_sent(tty, timeout); 94 tty->ops->wait_until_sent(tty, timeout);
70 } 95 }
71 unlock_kernel();
72} 96}
73EXPORT_SYMBOL(tty_wait_until_sent); 97EXPORT_SYMBOL(tty_wait_until_sent);
74 98
@@ -444,8 +468,8 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
444 } 468 }
445 } 469 }
446 470
447 if (tty->driver->set_termios) 471 if (tty->ops->set_termios)
448 (*tty->driver->set_termios)(tty, &old_termios); 472 (*tty->ops->set_termios)(tty, &old_termios);
449 else 473 else
450 tty_termios_copy_hw(tty->termios, &old_termios); 474 tty_termios_copy_hw(tty->termios, &old_termios);
451 475
@@ -748,8 +772,8 @@ static int send_prio_char(struct tty_struct *tty, char ch)
748{ 772{
749 int was_stopped = tty->stopped; 773 int was_stopped = tty->stopped;
750 774
751 if (tty->driver->send_xchar) { 775 if (tty->ops->send_xchar) {
752 tty->driver->send_xchar(tty, ch); 776 tty->ops->send_xchar(tty, ch);
753 return 0; 777 return 0;
754 } 778 }
755 779
@@ -758,7 +782,7 @@ static int send_prio_char(struct tty_struct *tty, char ch)
758 782
759 if (was_stopped) 783 if (was_stopped)
760 start_tty(tty); 784 start_tty(tty);
761 tty->driver->write(tty, &ch, 1); 785 tty->ops->write(tty, &ch, 1);
762 if (was_stopped) 786 if (was_stopped)
763 stop_tty(tty); 787 stop_tty(tty);
764 tty_write_unlock(tty); 788 tty_write_unlock(tty);
@@ -778,13 +802,14 @@ static int tty_change_softcar(struct tty_struct *tty, int arg)
778{ 802{
779 int ret = 0; 803 int ret = 0;
780 int bit = arg ? CLOCAL : 0; 804 int bit = arg ? CLOCAL : 0;
781 struct ktermios old = *tty->termios; 805 struct ktermios old;
782 806
783 mutex_lock(&tty->termios_mutex); 807 mutex_lock(&tty->termios_mutex);
808 old = *tty->termios;
784 tty->termios->c_cflag &= ~CLOCAL; 809 tty->termios->c_cflag &= ~CLOCAL;
785 tty->termios->c_cflag |= bit; 810 tty->termios->c_cflag |= bit;
786 if (tty->driver->set_termios) 811 if (tty->ops->set_termios)
787 tty->driver->set_termios(tty, &old); 812 tty->ops->set_termios(tty, &old);
788 if ((tty->termios->c_cflag & CLOCAL) != bit) 813 if ((tty->termios->c_cflag & CLOCAL) != bit)
789 ret = -EINVAL; 814 ret = -EINVAL;
790 mutex_unlock(&tty->termios_mutex); 815 mutex_unlock(&tty->termios_mutex);
@@ -926,8 +951,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
926 ld->flush_buffer(tty); 951 ld->flush_buffer(tty);
927 /* fall through */ 952 /* fall through */
928 case TCOFLUSH: 953 case TCOFLUSH:
929 if (tty->driver->flush_buffer) 954 tty_driver_flush_buffer(tty);
930 tty->driver->flush_buffer(tty);
931 break; 955 break;
932 default: 956 default:
933 tty_ldisc_deref(ld); 957 tty_ldisc_deref(ld);
@@ -984,9 +1008,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
984 case TCFLSH: 1008 case TCFLSH:
985 return tty_perform_flush(tty, arg); 1009 return tty_perform_flush(tty, arg);
986 case TIOCOUTQ: 1010 case TIOCOUTQ:
987 return put_user(tty->driver->chars_in_buffer ? 1011 return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
988 tty->driver->chars_in_buffer(tty) : 0,
989 (int __user *) arg);
990 case TIOCINQ: 1012 case TIOCINQ:
991 retval = tty->read_cnt; 1013 retval = tty->read_cnt;
992 if (L_ICANON(tty)) 1014 if (L_ICANON(tty))