diff options
| -rw-r--r-- | drivers/staging/speakup/selection.c | 5 | ||||
| -rw-r--r-- | drivers/tty/n_tty.c | 7 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 29 | ||||
| -rw-r--r-- | drivers/tty/tty_io.c | 44 | ||||
| -rw-r--r-- | drivers/tty/tty_mutex.c | 8 | ||||
| -rw-r--r-- | include/linux/tty.h | 1 |
6 files changed, 82 insertions, 12 deletions
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index aa5ab6c80ed4..41ef099b7aa6 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c | |||
| @@ -142,7 +142,9 @@ static void __speakup_paste_selection(struct work_struct *work) | |||
| 142 | struct tty_ldisc *ld; | 142 | struct tty_ldisc *ld; |
| 143 | DECLARE_WAITQUEUE(wait, current); | 143 | DECLARE_WAITQUEUE(wait, current); |
| 144 | 144 | ||
| 145 | ld = tty_ldisc_ref_wait(tty); | 145 | ld = tty_ldisc_ref(tty); |
| 146 | if (!ld) | ||
| 147 | goto tty_unref; | ||
| 146 | tty_buffer_lock_exclusive(&vc->port); | 148 | tty_buffer_lock_exclusive(&vc->port); |
| 147 | 149 | ||
| 148 | add_wait_queue(&vc->paste_wait, &wait); | 150 | add_wait_queue(&vc->paste_wait, &wait); |
| @@ -162,6 +164,7 @@ static void __speakup_paste_selection(struct work_struct *work) | |||
| 162 | 164 | ||
| 163 | tty_buffer_unlock_exclusive(&vc->port); | 165 | tty_buffer_unlock_exclusive(&vc->port); |
| 164 | tty_ldisc_deref(ld); | 166 | tty_ldisc_deref(ld); |
| 167 | tty_unref: | ||
| 165 | tty_kref_put(tty); | 168 | tty_kref_put(tty); |
| 166 | } | 169 | } |
| 167 | 170 | ||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d9a5fc28fef4..b280abaad91b 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
| @@ -269,16 +269,13 @@ static void n_tty_check_throttle(struct tty_struct *tty) | |||
| 269 | 269 | ||
| 270 | static void n_tty_check_unthrottle(struct tty_struct *tty) | 270 | static void n_tty_check_unthrottle(struct tty_struct *tty) |
| 271 | { | 271 | { |
| 272 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 272 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY) { |
| 273 | tty->link->ldisc->ops->write_wakeup == n_tty_write_wakeup) { | ||
| 274 | if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) | 273 | if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) |
| 275 | return; | 274 | return; |
| 276 | if (!tty->count) | 275 | if (!tty->count) |
| 277 | return; | 276 | return; |
| 278 | n_tty_kick_worker(tty); | 277 | n_tty_kick_worker(tty); |
| 279 | n_tty_write_wakeup(tty->link); | 278 | tty_wakeup(tty->link); |
| 280 | if (waitqueue_active(&tty->link->write_wait)) | ||
| 281 | wake_up_interruptible_poll(&tty->link->write_wait, POLLOUT); | ||
| 282 | return; | 279 | return; |
| 283 | } | 280 | } |
| 284 | 281 | ||
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 4097f3f65b3b..e71ec78fc11e 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
| @@ -1379,6 +1379,9 @@ ce4100_serial_setup(struct serial_private *priv, | |||
| 1379 | #define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a | 1379 | #define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a |
| 1380 | #define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c | 1380 | #define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c |
| 1381 | 1381 | ||
| 1382 | #define PCI_DEVICE_ID_INTEL_BDW_UART1 0x9ce3 | ||
| 1383 | #define PCI_DEVICE_ID_INTEL_BDW_UART2 0x9ce4 | ||
| 1384 | |||
| 1382 | #define BYT_PRV_CLK 0x800 | 1385 | #define BYT_PRV_CLK 0x800 |
| 1383 | #define BYT_PRV_CLK_EN (1 << 0) | 1386 | #define BYT_PRV_CLK_EN (1 << 0) |
| 1384 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 | 1387 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 |
| @@ -1461,11 +1464,13 @@ byt_serial_setup(struct serial_private *priv, | |||
| 1461 | switch (pdev->device) { | 1464 | switch (pdev->device) { |
| 1462 | case PCI_DEVICE_ID_INTEL_BYT_UART1: | 1465 | case PCI_DEVICE_ID_INTEL_BYT_UART1: |
| 1463 | case PCI_DEVICE_ID_INTEL_BSW_UART1: | 1466 | case PCI_DEVICE_ID_INTEL_BSW_UART1: |
| 1467 | case PCI_DEVICE_ID_INTEL_BDW_UART1: | ||
| 1464 | rx_param->src_id = 3; | 1468 | rx_param->src_id = 3; |
| 1465 | tx_param->dst_id = 2; | 1469 | tx_param->dst_id = 2; |
| 1466 | break; | 1470 | break; |
| 1467 | case PCI_DEVICE_ID_INTEL_BYT_UART2: | 1471 | case PCI_DEVICE_ID_INTEL_BYT_UART2: |
| 1468 | case PCI_DEVICE_ID_INTEL_BSW_UART2: | 1472 | case PCI_DEVICE_ID_INTEL_BSW_UART2: |
| 1473 | case PCI_DEVICE_ID_INTEL_BDW_UART2: | ||
| 1469 | rx_param->src_id = 5; | 1474 | rx_param->src_id = 5; |
| 1470 | tx_param->dst_id = 4; | 1475 | tx_param->dst_id = 4; |
| 1471 | break; | 1476 | break; |
| @@ -2062,6 +2067,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
| 2062 | .subdevice = PCI_ANY_ID, | 2067 | .subdevice = PCI_ANY_ID, |
| 2063 | .setup = byt_serial_setup, | 2068 | .setup = byt_serial_setup, |
| 2064 | }, | 2069 | }, |
| 2070 | { | ||
| 2071 | .vendor = PCI_VENDOR_ID_INTEL, | ||
| 2072 | .device = PCI_DEVICE_ID_INTEL_BDW_UART1, | ||
| 2073 | .subvendor = PCI_ANY_ID, | ||
| 2074 | .subdevice = PCI_ANY_ID, | ||
| 2075 | .setup = byt_serial_setup, | ||
| 2076 | }, | ||
| 2077 | { | ||
| 2078 | .vendor = PCI_VENDOR_ID_INTEL, | ||
| 2079 | .device = PCI_DEVICE_ID_INTEL_BDW_UART2, | ||
| 2080 | .subvendor = PCI_ANY_ID, | ||
| 2081 | .subdevice = PCI_ANY_ID, | ||
| 2082 | .setup = byt_serial_setup, | ||
| 2083 | }, | ||
| 2065 | /* | 2084 | /* |
| 2066 | * ITE | 2085 | * ITE |
| 2067 | */ | 2086 | */ |
| @@ -5506,6 +5525,16 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 5506 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | 5525 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, |
| 5507 | pbn_byt }, | 5526 | pbn_byt }, |
| 5508 | 5527 | ||
| 5528 | /* Intel Broadwell */ | ||
| 5529 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_UART1, | ||
| 5530 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 5531 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | ||
| 5532 | pbn_byt }, | ||
| 5533 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_UART2, | ||
| 5534 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 5535 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | ||
| 5536 | pbn_byt }, | ||
| 5537 | |||
| 5509 | /* | 5538 | /* |
| 5510 | * Intel Quark x1000 | 5539 | * Intel Quark x1000 |
| 5511 | */ | 5540 | */ |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 892c92354745..5cec01c75691 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
| @@ -1463,13 +1463,13 @@ static int tty_reopen(struct tty_struct *tty) | |||
| 1463 | { | 1463 | { |
| 1464 | struct tty_driver *driver = tty->driver; | 1464 | struct tty_driver *driver = tty->driver; |
| 1465 | 1465 | ||
| 1466 | if (!tty->count) | ||
| 1467 | return -EIO; | ||
| 1468 | |||
| 1469 | if (driver->type == TTY_DRIVER_TYPE_PTY && | 1466 | if (driver->type == TTY_DRIVER_TYPE_PTY && |
| 1470 | driver->subtype == PTY_TYPE_MASTER) | 1467 | driver->subtype == PTY_TYPE_MASTER) |
| 1471 | return -EIO; | 1468 | return -EIO; |
| 1472 | 1469 | ||
| 1470 | if (!tty->count) | ||
| 1471 | return -EAGAIN; | ||
| 1472 | |||
| 1473 | if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) | 1473 | if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) |
| 1474 | return -EBUSY; | 1474 | return -EBUSY; |
| 1475 | 1475 | ||
| @@ -2065,7 +2065,12 @@ retry_open: | |||
| 2065 | 2065 | ||
| 2066 | if (tty) { | 2066 | if (tty) { |
| 2067 | mutex_unlock(&tty_mutex); | 2067 | mutex_unlock(&tty_mutex); |
| 2068 | tty_lock(tty); | 2068 | retval = tty_lock_interruptible(tty); |
| 2069 | if (retval) { | ||
| 2070 | if (retval == -EINTR) | ||
| 2071 | retval = -ERESTARTSYS; | ||
| 2072 | goto err_unref; | ||
| 2073 | } | ||
| 2069 | /* safe to drop the kref from tty_driver_lookup_tty() */ | 2074 | /* safe to drop the kref from tty_driver_lookup_tty() */ |
| 2070 | tty_kref_put(tty); | 2075 | tty_kref_put(tty); |
| 2071 | retval = tty_reopen(tty); | 2076 | retval = tty_reopen(tty); |
| @@ -2083,7 +2088,11 @@ retry_open: | |||
| 2083 | 2088 | ||
| 2084 | if (IS_ERR(tty)) { | 2089 | if (IS_ERR(tty)) { |
| 2085 | retval = PTR_ERR(tty); | 2090 | retval = PTR_ERR(tty); |
| 2086 | goto err_file; | 2091 | if (retval != -EAGAIN || signal_pending(current)) |
| 2092 | goto err_file; | ||
| 2093 | tty_free_file(filp); | ||
| 2094 | schedule(); | ||
| 2095 | goto retry_open; | ||
| 2087 | } | 2096 | } |
| 2088 | 2097 | ||
| 2089 | tty_add_file(tty, filp); | 2098 | tty_add_file(tty, filp); |
| @@ -2152,6 +2161,7 @@ retry_open: | |||
| 2152 | return 0; | 2161 | return 0; |
| 2153 | err_unlock: | 2162 | err_unlock: |
| 2154 | mutex_unlock(&tty_mutex); | 2163 | mutex_unlock(&tty_mutex); |
| 2164 | err_unref: | ||
| 2155 | /* after locks to avoid deadlock */ | 2165 | /* after locks to avoid deadlock */ |
| 2156 | if (!IS_ERR_OR_NULL(driver)) | 2166 | if (!IS_ERR_OR_NULL(driver)) |
| 2157 | tty_driver_kref_put(driver); | 2167 | tty_driver_kref_put(driver); |
| @@ -2649,6 +2659,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) | |||
| 2649 | } | 2659 | } |
| 2650 | 2660 | ||
| 2651 | /** | 2661 | /** |
| 2662 | * tiocgetd - get line discipline | ||
| 2663 | * @tty: tty device | ||
| 2664 | * @p: pointer to user data | ||
| 2665 | * | ||
| 2666 | * Retrieves the line discipline id directly from the ldisc. | ||
| 2667 | * | ||
| 2668 | * Locking: waits for ldisc reference (in case the line discipline | ||
| 2669 | * is changing or the tty is being hungup) | ||
| 2670 | */ | ||
| 2671 | |||
| 2672 | static int tiocgetd(struct tty_struct *tty, int __user *p) | ||
| 2673 | { | ||
| 2674 | struct tty_ldisc *ld; | ||
| 2675 | int ret; | ||
| 2676 | |||
| 2677 | ld = tty_ldisc_ref_wait(tty); | ||
| 2678 | ret = put_user(ld->ops->num, p); | ||
| 2679 | tty_ldisc_deref(ld); | ||
| 2680 | return ret; | ||
| 2681 | } | ||
| 2682 | |||
| 2683 | /** | ||
| 2652 | * send_break - performed time break | 2684 | * send_break - performed time break |
| 2653 | * @tty: device to break on | 2685 | * @tty: device to break on |
| 2654 | * @duration: timeout in mS | 2686 | * @duration: timeout in mS |
| @@ -2874,7 +2906,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 2874 | case TIOCGSID: | 2906 | case TIOCGSID: |
| 2875 | return tiocgsid(tty, real_tty, p); | 2907 | return tiocgsid(tty, real_tty, p); |
| 2876 | case TIOCGETD: | 2908 | case TIOCGETD: |
| 2877 | return put_user(tty->ldisc->ops->num, (int __user *)p); | 2909 | return tiocgetd(tty, p); |
| 2878 | case TIOCSETD: | 2910 | case TIOCSETD: |
| 2879 | return tiocsetd(tty, p); | 2911 | return tiocsetd(tty, p); |
| 2880 | case TIOCVHANGUP: | 2912 | case TIOCVHANGUP: |
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 77703a391207..d2f3c4cd697f 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
| @@ -19,6 +19,14 @@ void __lockfunc tty_lock(struct tty_struct *tty) | |||
| 19 | } | 19 | } |
| 20 | EXPORT_SYMBOL(tty_lock); | 20 | EXPORT_SYMBOL(tty_lock); |
| 21 | 21 | ||
| 22 | int tty_lock_interruptible(struct tty_struct *tty) | ||
| 23 | { | ||
| 24 | if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty)) | ||
| 25 | return -EIO; | ||
| 26 | tty_kref_get(tty); | ||
| 27 | return mutex_lock_interruptible(&tty->legacy_mutex); | ||
| 28 | } | ||
| 29 | |||
| 22 | void __lockfunc tty_unlock(struct tty_struct *tty) | 30 | void __lockfunc tty_unlock(struct tty_struct *tty) |
| 23 | { | 31 | { |
| 24 | if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty)) | 32 | if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty)) |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 2fd8708ea888..d9fb4b043f56 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -649,6 +649,7 @@ extern long vt_compat_ioctl(struct tty_struct *tty, | |||
| 649 | /* tty_mutex.c */ | 649 | /* tty_mutex.c */ |
| 650 | /* functions for preparation of BKL removal */ | 650 | /* functions for preparation of BKL removal */ |
| 651 | extern void __lockfunc tty_lock(struct tty_struct *tty); | 651 | extern void __lockfunc tty_lock(struct tty_struct *tty); |
| 652 | extern int tty_lock_interruptible(struct tty_struct *tty); | ||
| 652 | extern void __lockfunc tty_unlock(struct tty_struct *tty); | 653 | extern void __lockfunc tty_unlock(struct tty_struct *tty); |
| 653 | extern void __lockfunc tty_lock_slave(struct tty_struct *tty); | 654 | extern void __lockfunc tty_lock_slave(struct tty_struct *tty); |
| 654 | extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); | 655 | extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); |
