aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-15 06:02:23 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-15 06:02:23 -0400
commit9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (patch)
tree8d104ec2a459346b99413b0b77421ca7b9936c1a /drivers/char/tty_io.c
parentca44d6e60f9de26281fda203f58b570e1748c015 (diff)
parent45e3e1935e2857c54783291107d33323b3ef33c8 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: Documentation/feature-removal-schedule.txt drivers/scsi/fcoe/fcoe.c net/core/drop_monitor.c net/core/net-traces.c
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c122
1 files changed, 34 insertions, 88 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 66b99a2049e3..939e198d7670 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -295,7 +295,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
295 struct tty_driver *p, *res = NULL; 295 struct tty_driver *p, *res = NULL;
296 int tty_line = 0; 296 int tty_line = 0;
297 int len; 297 int len;
298 char *str; 298 char *str, *stp;
299 299
300 for (str = name; *str; str++) 300 for (str = name; *str; str++)
301 if ((*str >= '0' && *str <= '9') || *str == ',') 301 if ((*str >= '0' && *str <= '9') || *str == ',')
@@ -311,13 +311,14 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
311 list_for_each_entry(p, &tty_drivers, tty_drivers) { 311 list_for_each_entry(p, &tty_drivers, tty_drivers) {
312 if (strncmp(name, p->name, len) != 0) 312 if (strncmp(name, p->name, len) != 0)
313 continue; 313 continue;
314 if (*str == ',') 314 stp = str;
315 str++; 315 if (*stp == ',')
316 if (*str == '\0') 316 stp++;
317 str = NULL; 317 if (*stp == '\0')
318 stp = NULL;
318 319
319 if (tty_line >= 0 && tty_line <= p->num && p->ops && 320 if (tty_line >= 0 && tty_line <= p->num && p->ops &&
320 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { 321 p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
321 res = tty_driver_kref_get(p); 322 res = tty_driver_kref_get(p);
322 *line = tty_line; 323 *line = tty_line;
323 break; 324 break;
@@ -470,43 +471,6 @@ void tty_wakeup(struct tty_struct *tty)
470EXPORT_SYMBOL_GPL(tty_wakeup); 471EXPORT_SYMBOL_GPL(tty_wakeup);
471 472
472/** 473/**
473 * tty_ldisc_flush - flush line discipline queue
474 * @tty: tty
475 *
476 * Flush the line discipline queue (if any) for this tty. If there
477 * is no line discipline active this is a no-op.
478 */
479
480void tty_ldisc_flush(struct tty_struct *tty)
481{
482 struct tty_ldisc *ld = tty_ldisc_ref(tty);
483 if (ld) {
484 if (ld->ops->flush_buffer)
485 ld->ops->flush_buffer(tty);
486 tty_ldisc_deref(ld);
487 }
488 tty_buffer_flush(tty);
489}
490
491EXPORT_SYMBOL_GPL(tty_ldisc_flush);
492
493/**
494 * tty_reset_termios - reset terminal state
495 * @tty: tty to reset
496 *
497 * Restore a terminal to the driver default state
498 */
499
500static void tty_reset_termios(struct tty_struct *tty)
501{
502 mutex_lock(&tty->termios_mutex);
503 *tty->termios = tty->driver->init_termios;
504 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
505 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
506 mutex_unlock(&tty->termios_mutex);
507}
508
509/**
510 * do_tty_hangup - actual handler for hangup events 474 * do_tty_hangup - actual handler for hangup events
511 * @work: tty device 475 * @work: tty device
512 * 476 *
@@ -535,7 +499,6 @@ static void do_tty_hangup(struct work_struct *work)
535 struct file *cons_filp = NULL; 499 struct file *cons_filp = NULL;
536 struct file *filp, *f = NULL; 500 struct file *filp, *f = NULL;
537 struct task_struct *p; 501 struct task_struct *p;
538 struct tty_ldisc *ld;
539 int closecount = 0, n; 502 int closecount = 0, n;
540 unsigned long flags; 503 unsigned long flags;
541 int refs = 0; 504 int refs = 0;
@@ -566,40 +529,8 @@ static void do_tty_hangup(struct work_struct *work)
566 filp->f_op = &hung_up_tty_fops; 529 filp->f_op = &hung_up_tty_fops;
567 } 530 }
568 file_list_unlock(); 531 file_list_unlock();
569 /*
570 * FIXME! What are the locking issues here? This may me overdoing
571 * things... This question is especially important now that we've
572 * removed the irqlock.
573 */
574 ld = tty_ldisc_ref(tty);
575 if (ld != NULL) {
576 /* We may have no line discipline at this point */
577 if (ld->ops->flush_buffer)
578 ld->ops->flush_buffer(tty);
579 tty_driver_flush_buffer(tty);
580 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
581 ld->ops->write_wakeup)
582 ld->ops->write_wakeup(tty);
583 if (ld->ops->hangup)
584 ld->ops->hangup(tty);
585 }
586 /*
587 * FIXME: Once we trust the LDISC code better we can wait here for
588 * ldisc completion and fix the driver call race
589 */
590 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
591 wake_up_interruptible_poll(&tty->read_wait, POLLIN);
592 /*
593 * Shutdown the current line discipline, and reset it to
594 * N_TTY.
595 */
596 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
597 tty_reset_termios(tty);
598 /* Defer ldisc switch */
599 /* tty_deferred_ldisc_switch(N_TTY);
600 532
601 This should get done automatically when the port closes and 533 tty_ldisc_hangup(tty);
602 tty_release is called */
603 534
604 read_lock(&tasklist_lock); 535 read_lock(&tasklist_lock);
605 if (tty->session) { 536 if (tty->session) {
@@ -628,12 +559,15 @@ static void do_tty_hangup(struct work_struct *work)
628 read_unlock(&tasklist_lock); 559 read_unlock(&tasklist_lock);
629 560
630 spin_lock_irqsave(&tty->ctrl_lock, flags); 561 spin_lock_irqsave(&tty->ctrl_lock, flags);
631 tty->flags = 0; 562 clear_bit(TTY_THROTTLED, &tty->flags);
563 clear_bit(TTY_PUSH, &tty->flags);
564 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
632 put_pid(tty->session); 565 put_pid(tty->session);
633 put_pid(tty->pgrp); 566 put_pid(tty->pgrp);
634 tty->session = NULL; 567 tty->session = NULL;
635 tty->pgrp = NULL; 568 tty->pgrp = NULL;
636 tty->ctrl_status = 0; 569 tty->ctrl_status = 0;
570 set_bit(TTY_HUPPED, &tty->flags);
637 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 571 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
638 572
639 /* Account for the p->signal references we killed */ 573 /* Account for the p->signal references we killed */
@@ -659,10 +593,7 @@ static void do_tty_hangup(struct work_struct *work)
659 * can't yet guarantee all that. 593 * can't yet guarantee all that.
660 */ 594 */
661 set_bit(TTY_HUPPED, &tty->flags); 595 set_bit(TTY_HUPPED, &tty->flags);
662 if (ld) { 596 tty_ldisc_enable(tty);
663 tty_ldisc_enable(tty);
664 tty_ldisc_deref(ld);
665 }
666 unlock_kernel(); 597 unlock_kernel();
667 if (f) 598 if (f)
668 fput(f); 599 fput(f);
@@ -2480,6 +2411,24 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
2480 return tty->ops->tiocmset(tty, file, set, clear); 2411 return tty->ops->tiocmset(tty, file, set, clear);
2481} 2412}
2482 2413
2414struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
2415{
2416 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2417 tty->driver->subtype == PTY_TYPE_MASTER)
2418 tty = tty->link;
2419 return tty;
2420}
2421EXPORT_SYMBOL(tty_pair_get_tty);
2422
2423struct tty_struct *tty_pair_get_pty(struct tty_struct *tty)
2424{
2425 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2426 tty->driver->subtype == PTY_TYPE_MASTER)
2427 return tty;
2428 return tty->link;
2429}
2430EXPORT_SYMBOL(tty_pair_get_pty);
2431
2483/* 2432/*
2484 * Split this up, as gcc can choke on it otherwise.. 2433 * Split this up, as gcc can choke on it otherwise..
2485 */ 2434 */
@@ -2495,11 +2444,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2495 if (tty_paranoia_check(tty, inode, "tty_ioctl")) 2444 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2496 return -EINVAL; 2445 return -EINVAL;
2497 2446
2498 real_tty = tty; 2447 real_tty = tty_pair_get_tty(tty);
2499 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2500 tty->driver->subtype == PTY_TYPE_MASTER)
2501 real_tty = tty->link;
2502
2503 2448
2504 /* 2449 /*
2505 * Factor out some common prep work 2450 * Factor out some common prep work
@@ -2555,7 +2500,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2555 case TIOCGSID: 2500 case TIOCGSID:
2556 return tiocgsid(tty, real_tty, p); 2501 return tiocgsid(tty, real_tty, p);
2557 case TIOCGETD: 2502 case TIOCGETD:
2558 return put_user(tty->ldisc.ops->num, (int __user *)p); 2503 return put_user(tty->ldisc->ops->num, (int __user *)p);
2559 case TIOCSETD: 2504 case TIOCSETD:
2560 return tiocsetd(tty, p); 2505 return tiocsetd(tty, p);
2561 /* 2506 /*
@@ -2770,6 +2715,7 @@ void initialize_tty_struct(struct tty_struct *tty,
2770 tty->buf.head = tty->buf.tail = NULL; 2715 tty->buf.head = tty->buf.tail = NULL;
2771 tty_buffer_init(tty); 2716 tty_buffer_init(tty);
2772 mutex_init(&tty->termios_mutex); 2717 mutex_init(&tty->termios_mutex);
2718 mutex_init(&tty->ldisc_mutex);
2773 init_waitqueue_head(&tty->write_wait); 2719 init_waitqueue_head(&tty->write_wait);
2774 init_waitqueue_head(&tty->read_wait); 2720 init_waitqueue_head(&tty->read_wait);
2775 INIT_WORK(&tty->hangup_work, do_tty_hangup); 2721 INIT_WORK(&tty->hangup_work, do_tty_hangup);