diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-31 17:05:19 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-31 17:05:19 -0500 |
| commit | abfa44b5fd4a2f5d7549005bec465d4823a263ff (patch) | |
| tree | 98376516ae6a314569b589df1f6ac6d49831bde5 | |
| parent | 70d1f365568e0cdbc9f4ab92428e1830fdb09ab0 (diff) | |
| parent | fed7bb324cffd980a4a576514ced3ff52f68f319 (diff) | |
Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6:
tty/serial: fix apbuart build
n_hdlc: fix read and write locking
serial: unbreak billionton CF card
tty: use for_each_console() and WARN() on sysfs failures
vt: fix issue when fbcon wants to takeover a second time.
Fix up trivial conflict in drivers/tty/tty_io.c
| -rw-r--r-- | drivers/tty/n_hdlc.c | 90 | ||||
| -rw-r--r-- | drivers/tty/serial/8250.c | 3 | ||||
| -rw-r--r-- | drivers/tty/serial/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/tty/tty_io.c | 4 | ||||
| -rw-r--r-- | drivers/tty/vt/vt.c | 11 |
5 files changed, 58 insertions, 51 deletions
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 47d32281032c..52fc0c9a6364 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
| @@ -581,8 +581,9 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
| 581 | __u8 __user *buf, size_t nr) | 581 | __u8 __user *buf, size_t nr) |
| 582 | { | 582 | { |
| 583 | struct n_hdlc *n_hdlc = tty2n_hdlc(tty); | 583 | struct n_hdlc *n_hdlc = tty2n_hdlc(tty); |
| 584 | int ret; | 584 | int ret = 0; |
| 585 | struct n_hdlc_buf *rbuf; | 585 | struct n_hdlc_buf *rbuf; |
| 586 | DECLARE_WAITQUEUE(wait, current); | ||
| 586 | 587 | ||
| 587 | if (debuglevel >= DEBUG_LEVEL_INFO) | 588 | if (debuglevel >= DEBUG_LEVEL_INFO) |
| 588 | printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__); | 589 | printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__); |
| @@ -598,57 +599,55 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
| 598 | return -EFAULT; | 599 | return -EFAULT; |
| 599 | } | 600 | } |
| 600 | 601 | ||
| 601 | tty_lock(); | 602 | add_wait_queue(&tty->read_wait, &wait); |
| 602 | 603 | ||
| 603 | for (;;) { | 604 | for (;;) { |
| 604 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { | 605 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
| 605 | tty_unlock(); | 606 | ret = -EIO; |
| 606 | return -EIO; | 607 | break; |
| 607 | } | 608 | } |
| 609 | if (tty_hung_up_p(file)) | ||
| 610 | break; | ||
| 608 | 611 | ||
| 609 | n_hdlc = tty2n_hdlc (tty); | 612 | set_current_state(TASK_INTERRUPTIBLE); |
| 610 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || | ||
| 611 | tty != n_hdlc->tty) { | ||
| 612 | tty_unlock(); | ||
| 613 | return 0; | ||
| 614 | } | ||
| 615 | 613 | ||
| 616 | rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); | 614 | rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); |
| 617 | if (rbuf) | 615 | if (rbuf) { |
| 616 | if (rbuf->count > nr) { | ||
| 617 | /* too large for caller's buffer */ | ||
| 618 | ret = -EOVERFLOW; | ||
| 619 | } else { | ||
| 620 | if (copy_to_user(buf, rbuf->buf, rbuf->count)) | ||
| 621 | ret = -EFAULT; | ||
| 622 | else | ||
| 623 | ret = rbuf->count; | ||
| 624 | } | ||
| 625 | |||
| 626 | if (n_hdlc->rx_free_buf_list.count > | ||
| 627 | DEFAULT_RX_BUF_COUNT) | ||
| 628 | kfree(rbuf); | ||
| 629 | else | ||
| 630 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf); | ||
| 618 | break; | 631 | break; |
| 632 | } | ||
| 619 | 633 | ||
| 620 | /* no data */ | 634 | /* no data */ |
| 621 | if (file->f_flags & O_NONBLOCK) { | 635 | if (file->f_flags & O_NONBLOCK) { |
| 622 | tty_unlock(); | 636 | ret = -EAGAIN; |
| 623 | return -EAGAIN; | 637 | break; |
| 624 | } | 638 | } |
| 625 | 639 | ||
| 626 | interruptible_sleep_on (&tty->read_wait); | 640 | schedule(); |
| 641 | |||
| 627 | if (signal_pending(current)) { | 642 | if (signal_pending(current)) { |
| 628 | tty_unlock(); | 643 | ret = -EINTR; |
| 629 | return -EINTR; | 644 | break; |
| 630 | } | 645 | } |
| 631 | } | 646 | } |
| 632 | 647 | ||
| 633 | if (rbuf->count > nr) | 648 | remove_wait_queue(&tty->read_wait, &wait); |
| 634 | /* frame too large for caller's buffer (discard frame) */ | 649 | __set_current_state(TASK_RUNNING); |
| 635 | ret = -EOVERFLOW; | 650 | |
| 636 | else { | ||
| 637 | /* Copy the data to the caller's buffer */ | ||
| 638 | if (copy_to_user(buf, rbuf->buf, rbuf->count)) | ||
| 639 | ret = -EFAULT; | ||
| 640 | else | ||
| 641 | ret = rbuf->count; | ||
| 642 | } | ||
| 643 | |||
| 644 | /* return HDLC buffer to free list unless the free list */ | ||
| 645 | /* count has exceeded the default value, in which case the */ | ||
| 646 | /* buffer is freed back to the OS to conserve memory */ | ||
| 647 | if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT) | ||
| 648 | kfree(rbuf); | ||
| 649 | else | ||
| 650 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); | ||
| 651 | tty_unlock(); | ||
| 652 | return ret; | 651 | return ret; |
| 653 | 652 | ||
| 654 | } /* end of n_hdlc_tty_read() */ | 653 | } /* end of n_hdlc_tty_read() */ |
| @@ -691,14 +690,15 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
| 691 | count = maxframe; | 690 | count = maxframe; |
| 692 | } | 691 | } |
| 693 | 692 | ||
| 694 | tty_lock(); | ||
| 695 | |||
| 696 | add_wait_queue(&tty->write_wait, &wait); | 693 | add_wait_queue(&tty->write_wait, &wait); |
| 697 | set_current_state(TASK_INTERRUPTIBLE); | 694 | |
| 695 | for (;;) { | ||
| 696 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 698 | 697 | ||
| 699 | /* Allocate transmit buffer */ | 698 | tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list); |
| 700 | /* sleep until transmit buffer available */ | 699 | if (tbuf) |
| 701 | while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) { | 700 | break; |
| 701 | |||
| 702 | if (file->f_flags & O_NONBLOCK) { | 702 | if (file->f_flags & O_NONBLOCK) { |
| 703 | error = -EAGAIN; | 703 | error = -EAGAIN; |
| 704 | break; | 704 | break; |
| @@ -719,7 +719,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
| 719 | } | 719 | } |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | set_current_state(TASK_RUNNING); | 722 | __set_current_state(TASK_RUNNING); |
| 723 | remove_wait_queue(&tty->write_wait, &wait); | 723 | remove_wait_queue(&tty->write_wait, &wait); |
| 724 | 724 | ||
| 725 | if (!error) { | 725 | if (!error) { |
| @@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
| 731 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); | 731 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); |
| 732 | n_hdlc_send_frames(n_hdlc,tty); | 732 | n_hdlc_send_frames(n_hdlc,tty); |
| 733 | } | 733 | } |
| 734 | tty_unlock(); | 734 | |
| 735 | return error; | 735 | return error; |
| 736 | 736 | ||
| 737 | } /* end of n_hdlc_tty_write() */ | 737 | } /* end of n_hdlc_tty_write() */ |
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index b25e6e490530..3975df6f7fdb 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c | |||
| @@ -236,7 +236,8 @@ static const struct serial8250_config uart_config[] = { | |||
| 236 | .fifo_size = 128, | 236 | .fifo_size = 128, |
| 237 | .tx_loadsz = 128, | 237 | .tx_loadsz = 128, |
| 238 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 238 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
| 239 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, | 239 | /* UART_CAP_EFR breaks billionon CF bluetooth card. */ |
| 240 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP, | ||
| 240 | }, | 241 | }, |
| 241 | [PORT_16654] = { | 242 | [PORT_16654] = { |
| 242 | .name = "ST16654", | 243 | .name = "ST16654", |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index b1682d7f1d8a..2b8334601c8b 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
| @@ -1518,6 +1518,7 @@ config SERIAL_BCM63XX_CONSOLE | |||
| 1518 | config SERIAL_GRLIB_GAISLER_APBUART | 1518 | config SERIAL_GRLIB_GAISLER_APBUART |
| 1519 | tristate "GRLIB APBUART serial support" | 1519 | tristate "GRLIB APBUART serial support" |
| 1520 | depends on OF | 1520 | depends on OF |
| 1521 | select SERIAL_CORE | ||
| 1521 | ---help--- | 1522 | ---help--- |
| 1522 | Add support for the GRLIB APBUART serial port. | 1523 | Add support for the GRLIB APBUART serial port. |
| 1523 | 1524 | ||
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6158eae0f64a..0065da4b11c1 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
| @@ -3257,7 +3257,7 @@ static ssize_t show_cons_active(struct device *dev, | |||
| 3257 | ssize_t count = 0; | 3257 | ssize_t count = 0; |
| 3258 | 3258 | ||
| 3259 | console_lock(); | 3259 | console_lock(); |
| 3260 | for (c = console_drivers; c; c = c->next) { | 3260 | for_each_console(c) { |
| 3261 | if (!c->device) | 3261 | if (!c->device) |
| 3262 | continue; | 3262 | continue; |
| 3263 | if (!c->write) | 3263 | if (!c->write) |
| @@ -3306,7 +3306,7 @@ int __init tty_init(void) | |||
| 3306 | if (IS_ERR(consdev)) | 3306 | if (IS_ERR(consdev)) |
| 3307 | consdev = NULL; | 3307 | consdev = NULL; |
| 3308 | else | 3308 | else |
| 3309 | device_create_file(consdev, &dev_attr_active); | 3309 | WARN_ON(device_create_file(consdev, &dev_attr_active) < 0); |
| 3310 | 3310 | ||
| 3311 | #ifdef CONFIG_VT | 3311 | #ifdef CONFIG_VT |
| 3312 | vty_init(&console_fops); | 3312 | vty_init(&console_fops); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index b230bd3f056f..147ede3423df 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -2994,7 +2994,7 @@ int __init vty_init(const struct file_operations *console_fops) | |||
| 2994 | if (IS_ERR(tty0dev)) | 2994 | if (IS_ERR(tty0dev)) |
| 2995 | tty0dev = NULL; | 2995 | tty0dev = NULL; |
| 2996 | else | 2996 | else |
| 2997 | device_create_file(tty0dev, &dev_attr_active); | 2997 | WARN_ON(device_create_file(tty0dev, &dev_attr_active) < 0); |
| 2998 | 2998 | ||
| 2999 | vcs_init(); | 2999 | vcs_init(); |
| 3000 | 3000 | ||
| @@ -3545,7 +3545,7 @@ int register_con_driver(const struct consw *csw, int first, int last) | |||
| 3545 | 3545 | ||
| 3546 | /* already registered */ | 3546 | /* already registered */ |
| 3547 | if (con_driver->con == csw) | 3547 | if (con_driver->con == csw) |
| 3548 | retval = -EINVAL; | 3548 | retval = -EBUSY; |
| 3549 | } | 3549 | } |
| 3550 | 3550 | ||
| 3551 | if (retval) | 3551 | if (retval) |
| @@ -3656,7 +3656,12 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt) | |||
| 3656 | int err; | 3656 | int err; |
| 3657 | 3657 | ||
| 3658 | err = register_con_driver(csw, first, last); | 3658 | err = register_con_driver(csw, first, last); |
| 3659 | 3659 | /* if we get an busy error we still want to bind the console driver | |
| 3660 | * and return success, as we may have unbound the console driver | ||
| 3661 | * but not unregistered it. | ||
| 3662 | */ | ||
| 3663 | if (err == -EBUSY) | ||
| 3664 | err = 0; | ||
| 3660 | if (!err) | 3665 | if (!err) |
| 3661 | bind_con_driver(csw, first, last, deflt); | 3666 | bind_con_driver(csw, first, last, deflt); |
| 3662 | 3667 | ||
