diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
commit | 6396fc3b3ff3f6b942992b653a62df11dcef9bea (patch) | |
tree | db3c7cbe833b43c653adc99f70941431c5ff7c4e /drivers/char | |
parent | 4785879e4d340e24e54f6de2ccfc42728b912808 (diff) | |
parent | 3d30701b58970425e1d45994d6cb82f828924fdd (diff) |
Merge branch 'master' into for-next
Conflicts:
fs/exofs/inode.c
Diffstat (limited to 'drivers/char')
34 files changed, 506 insertions, 328 deletions
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 273cee1cc77b..dc9641660605 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -9,6 +9,7 @@ FONTMAPFILE = cp437.uni | |||
9 | 9 | ||
10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o | 10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o |
11 | 11 | ||
12 | obj-y += tty_mutex.o | ||
12 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 13 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
13 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 14 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
14 | obj-y += misc.o | 15 | obj-y += misc.o |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 4f8d60c25a98..a11c8c9ca3d4 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1072,7 +1072,7 @@ static int get_serial_info(struct async_struct * info, | |||
1072 | if (!retinfo) | 1072 | if (!retinfo) |
1073 | return -EFAULT; | 1073 | return -EFAULT; |
1074 | memset(&tmp, 0, sizeof(tmp)); | 1074 | memset(&tmp, 0, sizeof(tmp)); |
1075 | lock_kernel(); | 1075 | tty_lock(); |
1076 | tmp.type = state->type; | 1076 | tmp.type = state->type; |
1077 | tmp.line = state->line; | 1077 | tmp.line = state->line; |
1078 | tmp.port = state->port; | 1078 | tmp.port = state->port; |
@@ -1083,7 +1083,7 @@ static int get_serial_info(struct async_struct * info, | |||
1083 | tmp.close_delay = state->close_delay; | 1083 | tmp.close_delay = state->close_delay; |
1084 | tmp.closing_wait = state->closing_wait; | 1084 | tmp.closing_wait = state->closing_wait; |
1085 | tmp.custom_divisor = state->custom_divisor; | 1085 | tmp.custom_divisor = state->custom_divisor; |
1086 | unlock_kernel(); | 1086 | tty_unlock(); |
1087 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1087 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
1088 | return -EFAULT; | 1088 | return -EFAULT; |
1089 | return 0; | 1089 | return 0; |
@@ -1100,14 +1100,14 @@ static int set_serial_info(struct async_struct * info, | |||
1100 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1100 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
1101 | return -EFAULT; | 1101 | return -EFAULT; |
1102 | 1102 | ||
1103 | lock_kernel(); | 1103 | tty_lock(); |
1104 | state = info->state; | 1104 | state = info->state; |
1105 | old_state = *state; | 1105 | old_state = *state; |
1106 | 1106 | ||
1107 | change_irq = new_serial.irq != state->irq; | 1107 | change_irq = new_serial.irq != state->irq; |
1108 | change_port = (new_serial.port != state->port); | 1108 | change_port = (new_serial.port != state->port); |
1109 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { | 1109 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { |
1110 | unlock_kernel(); | 1110 | tty_unlock(); |
1111 | return -EINVAL; | 1111 | return -EINVAL; |
1112 | } | 1112 | } |
1113 | 1113 | ||
@@ -1127,7 +1127,7 @@ static int set_serial_info(struct async_struct * info, | |||
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | if (new_serial.baud_base < 9600) { | 1129 | if (new_serial.baud_base < 9600) { |
1130 | unlock_kernel(); | 1130 | tty_unlock(); |
1131 | return -EINVAL; | 1131 | return -EINVAL; |
1132 | } | 1132 | } |
1133 | 1133 | ||
@@ -1163,7 +1163,7 @@ check_and_exit: | |||
1163 | } | 1163 | } |
1164 | } else | 1164 | } else |
1165 | retval = startup(info); | 1165 | retval = startup(info); |
1166 | unlock_kernel(); | 1166 | tty_unlock(); |
1167 | return retval; | 1167 | return retval; |
1168 | } | 1168 | } |
1169 | 1169 | ||
@@ -1528,6 +1528,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1528 | { | 1528 | { |
1529 | struct async_struct * info = tty->driver_data; | 1529 | struct async_struct * info = tty->driver_data; |
1530 | unsigned long orig_jiffies, char_time; | 1530 | unsigned long orig_jiffies, char_time; |
1531 | int tty_was_locked = tty_locked(); | ||
1531 | int lsr; | 1532 | int lsr; |
1532 | 1533 | ||
1533 | if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) | 1534 | if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) |
@@ -1538,7 +1539,12 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1538 | 1539 | ||
1539 | orig_jiffies = jiffies; | 1540 | orig_jiffies = jiffies; |
1540 | 1541 | ||
1541 | lock_kernel(); | 1542 | /* |
1543 | * tty_wait_until_sent is called from lots of places, | ||
1544 | * with or without the BTM. | ||
1545 | */ | ||
1546 | if (!tty_was_locked) | ||
1547 | tty_lock(); | ||
1542 | /* | 1548 | /* |
1543 | * Set the check interval to be 1/5 of the estimated time to | 1549 | * Set the check interval to be 1/5 of the estimated time to |
1544 | * send a single character, and make it at least 1. The check | 1550 | * send a single character, and make it at least 1. The check |
@@ -1579,7 +1585,8 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1579 | break; | 1585 | break; |
1580 | } | 1586 | } |
1581 | __set_current_state(TASK_RUNNING); | 1587 | __set_current_state(TASK_RUNNING); |
1582 | unlock_kernel(); | 1588 | if (!tty_was_locked) |
1589 | tty_unlock(); | ||
1583 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1590 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1584 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1591 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1585 | #endif | 1592 | #endif |
@@ -1703,7 +1710,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1703 | printk("block_til_ready blocking: ttys%d, count = %d\n", | 1710 | printk("block_til_ready blocking: ttys%d, count = %d\n", |
1704 | info->line, state->count); | 1711 | info->line, state->count); |
1705 | #endif | 1712 | #endif |
1713 | tty_unlock(); | ||
1706 | schedule(); | 1714 | schedule(); |
1715 | tty_lock(); | ||
1707 | } | 1716 | } |
1708 | __set_current_state(TASK_RUNNING); | 1717 | __set_current_state(TASK_RUNNING); |
1709 | remove_wait_queue(&info->open_wait, &wait); | 1718 | remove_wait_queue(&info->open_wait, &wait); |
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c index 555cd93c2ee5..d5fa113afe37 100644 --- a/drivers/char/briq_panel.c +++ b/drivers/char/briq_panel.c | |||
@@ -67,15 +67,15 @@ static void set_led(char state) | |||
67 | 67 | ||
68 | static int briq_panel_open(struct inode *ino, struct file *filep) | 68 | static int briq_panel_open(struct inode *ino, struct file *filep) |
69 | { | 69 | { |
70 | lock_kernel(); | 70 | tty_lock(); |
71 | /* enforce single access, vfd_is_open is protected by BKL */ | 71 | /* enforce single access, vfd_is_open is protected by BKL */ |
72 | if (vfd_is_open) { | 72 | if (vfd_is_open) { |
73 | unlock_kernel(); | 73 | tty_unlock(); |
74 | return -EBUSY; | 74 | return -EBUSY; |
75 | } | 75 | } |
76 | vfd_is_open = 1; | 76 | vfd_is_open = 1; |
77 | 77 | ||
78 | unlock_kernel(); | 78 | tty_unlock(); |
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
81 | 81 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 9824b4162904..27aad9422332 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -65,7 +65,6 @@ | |||
65 | #include <linux/tty.h> | 65 | #include <linux/tty.h> |
66 | #include <linux/tty_flip.h> | 66 | #include <linux/tty_flip.h> |
67 | #include <linux/serial.h> | 67 | #include <linux/serial.h> |
68 | #include <linux/smp_lock.h> | ||
69 | #include <linux/major.h> | 68 | #include <linux/major.h> |
70 | #include <linux/string.h> | 69 | #include <linux/string.h> |
71 | #include <linux/fcntl.h> | 70 | #include <linux/fcntl.h> |
@@ -1608,7 +1607,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
1608 | * If the port is the middle of closing, bail out now | 1607 | * If the port is the middle of closing, bail out now |
1609 | */ | 1608 | */ |
1610 | if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { | 1609 | if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { |
1611 | wait_event_interruptible(info->port.close_wait, | 1610 | wait_event_interruptible_tty(info->port.close_wait, |
1612 | !(info->port.flags & ASYNC_CLOSING)); | 1611 | !(info->port.flags & ASYNC_CLOSING)); |
1613 | return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 1612 | return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
1614 | } | 1613 | } |
@@ -1655,7 +1654,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1655 | return; /* Just in case.... */ | 1654 | return; /* Just in case.... */ |
1656 | 1655 | ||
1657 | orig_jiffies = jiffies; | 1656 | orig_jiffies = jiffies; |
1658 | lock_kernel(); | ||
1659 | /* | 1657 | /* |
1660 | * Set the check interval to be 1/5 of the estimated time to | 1658 | * Set the check interval to be 1/5 of the estimated time to |
1661 | * send a single character, and make it at least 1. The check | 1659 | * send a single character, and make it at least 1. The check |
@@ -1702,7 +1700,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1702 | } | 1700 | } |
1703 | /* Run one more char cycle */ | 1701 | /* Run one more char cycle */ |
1704 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | 1702 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
1705 | unlock_kernel(); | ||
1706 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 1703 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
1707 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); | 1704 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); |
1708 | #endif | 1705 | #endif |
@@ -1959,7 +1956,6 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
1959 | int char_count; | 1956 | int char_count; |
1960 | __u32 tx_put, tx_get, tx_bufsize; | 1957 | __u32 tx_put, tx_get, tx_bufsize; |
1961 | 1958 | ||
1962 | lock_kernel(); | ||
1963 | tx_get = readl(&buf_ctrl->tx_get); | 1959 | tx_get = readl(&buf_ctrl->tx_get); |
1964 | tx_put = readl(&buf_ctrl->tx_put); | 1960 | tx_put = readl(&buf_ctrl->tx_put); |
1965 | tx_bufsize = readl(&buf_ctrl->tx_bufsize); | 1961 | tx_bufsize = readl(&buf_ctrl->tx_bufsize); |
@@ -1971,7 +1967,6 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
1971 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", | 1967 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
1972 | info->line, info->xmit_cnt + char_count); | 1968 | info->line, info->xmit_cnt + char_count); |
1973 | #endif | 1969 | #endif |
1974 | unlock_kernel(); | ||
1975 | return info->xmit_cnt + char_count; | 1970 | return info->xmit_cnt + char_count; |
1976 | } | 1971 | } |
1977 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 1972 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
@@ -2359,17 +2354,22 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, | |||
2359 | struct serial_struct __user *new_info) | 2354 | struct serial_struct __user *new_info) |
2360 | { | 2355 | { |
2361 | struct serial_struct new_serial; | 2356 | struct serial_struct new_serial; |
2357 | int ret; | ||
2362 | 2358 | ||
2363 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) | 2359 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
2364 | return -EFAULT; | 2360 | return -EFAULT; |
2365 | 2361 | ||
2362 | mutex_lock(&info->port.mutex); | ||
2366 | if (!capable(CAP_SYS_ADMIN)) { | 2363 | if (!capable(CAP_SYS_ADMIN)) { |
2367 | if (new_serial.close_delay != info->port.close_delay || | 2364 | if (new_serial.close_delay != info->port.close_delay || |
2368 | new_serial.baud_base != info->baud || | 2365 | new_serial.baud_base != info->baud || |
2369 | (new_serial.flags & ASYNC_FLAGS & | 2366 | (new_serial.flags & ASYNC_FLAGS & |
2370 | ~ASYNC_USR_MASK) != | 2367 | ~ASYNC_USR_MASK) != |
2371 | (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) | 2368 | (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) |
2369 | { | ||
2370 | mutex_unlock(&info->port.mutex); | ||
2372 | return -EPERM; | 2371 | return -EPERM; |
2372 | } | ||
2373 | info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) | | 2373 | info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) | |
2374 | (new_serial.flags & ASYNC_USR_MASK); | 2374 | (new_serial.flags & ASYNC_USR_MASK); |
2375 | info->baud = new_serial.baud_base; | 2375 | info->baud = new_serial.baud_base; |
@@ -2392,10 +2392,12 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, | |||
2392 | check_and_exit: | 2392 | check_and_exit: |
2393 | if (info->port.flags & ASYNC_INITIALIZED) { | 2393 | if (info->port.flags & ASYNC_INITIALIZED) { |
2394 | cy_set_line_char(info, tty); | 2394 | cy_set_line_char(info, tty); |
2395 | return 0; | 2395 | ret = 0; |
2396 | } else { | 2396 | } else { |
2397 | return cy_startup(info, tty); | 2397 | ret = cy_startup(info, tty); |
2398 | } | 2398 | } |
2399 | mutex_unlock(&info->port.mutex); | ||
2400 | return ret; | ||
2399 | } /* set_serial_info */ | 2401 | } /* set_serial_info */ |
2400 | 2402 | ||
2401 | /* | 2403 | /* |
@@ -2438,7 +2440,6 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
2438 | 2440 | ||
2439 | card = info->card; | 2441 | card = info->card; |
2440 | 2442 | ||
2441 | lock_kernel(); | ||
2442 | if (!cy_is_Z(card)) { | 2443 | if (!cy_is_Z(card)) { |
2443 | unsigned long flags; | 2444 | unsigned long flags; |
2444 | int channel = info->line - card->first_line; | 2445 | int channel = info->line - card->first_line; |
@@ -2478,7 +2479,6 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
2478 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); | 2479 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); |
2479 | } | 2480 | } |
2480 | end: | 2481 | end: |
2481 | unlock_kernel(); | ||
2482 | return result; | 2482 | return result; |
2483 | } /* cy_tiomget */ | 2483 | } /* cy_tiomget */ |
2484 | 2484 | ||
@@ -2696,7 +2696,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
2696 | printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", | 2696 | printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", |
2697 | info->line, cmd, arg); | 2697 | info->line, cmd, arg); |
2698 | #endif | 2698 | #endif |
2699 | lock_kernel(); | ||
2700 | 2699 | ||
2701 | switch (cmd) { | 2700 | switch (cmd) { |
2702 | case CYGETMON: | 2701 | case CYGETMON: |
@@ -2817,7 +2816,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
2817 | default: | 2816 | default: |
2818 | ret_val = -ENOIOCTLCMD; | 2817 | ret_val = -ENOIOCTLCMD; |
2819 | } | 2818 | } |
2820 | unlock_kernel(); | ||
2821 | 2819 | ||
2822 | #ifdef CY_DEBUG_OTHER | 2820 | #ifdef CY_DEBUG_OTHER |
2823 | printk(KERN_DEBUG "cyc:cy_ioctl done\n"); | 2821 | printk(KERN_DEBUG "cyc:cy_ioctl done\n"); |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 6f5ffe1320f7..d9df46aa0fba 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/ctype.h> | 36 | #include <linux/ctype.h> |
37 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
38 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
39 | #include <linux/smp_lock.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
@@ -2105,7 +2105,6 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file, | |||
2105 | break; | 2105 | break; |
2106 | case DIGI_SETAW: | 2106 | case DIGI_SETAW: |
2107 | case DIGI_SETAF: | 2107 | case DIGI_SETAF: |
2108 | lock_kernel(); | ||
2109 | if (cmd == DIGI_SETAW) { | 2108 | if (cmd == DIGI_SETAW) { |
2110 | /* Setup an event to indicate when the transmit | 2109 | /* Setup an event to indicate when the transmit |
2111 | buffer empties */ | 2110 | buffer empties */ |
@@ -2118,7 +2117,6 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file, | |||
2118 | if (tty->ldisc->ops->flush_buffer) | 2117 | if (tty->ldisc->ops->flush_buffer) |
2119 | tty->ldisc->ops->flush_buffer(tty); | 2118 | tty->ldisc->ops->flush_buffer(tty); |
2120 | } | 2119 | } |
2121 | unlock_kernel(); | ||
2122 | /* Fall Thru */ | 2120 | /* Fall Thru */ |
2123 | case DIGI_SETA: | 2121 | case DIGI_SETA: |
2124 | if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) | 2122 | if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 911e1da6def2..07f3ea38b582 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -1486,7 +1486,9 @@ ip2_open( PTTY tty, struct file *pFile ) | |||
1486 | 1486 | ||
1487 | if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) { | 1487 | if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) { |
1488 | if ( pCh->flags & ASYNC_CLOSING ) { | 1488 | if ( pCh->flags & ASYNC_CLOSING ) { |
1489 | tty_unlock(); | ||
1489 | schedule(); | 1490 | schedule(); |
1491 | tty_lock(); | ||
1490 | } | 1492 | } |
1491 | if ( tty_hung_up_p(pFile) ) { | 1493 | if ( tty_hung_up_p(pFile) ) { |
1492 | set_current_state( TASK_RUNNING ); | 1494 | set_current_state( TASK_RUNNING ); |
@@ -1548,7 +1550,9 @@ ip2_open( PTTY tty, struct file *pFile ) | |||
1548 | rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); | 1550 | rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); |
1549 | break; | 1551 | break; |
1550 | } | 1552 | } |
1553 | tty_unlock(); | ||
1551 | schedule(); | 1554 | schedule(); |
1555 | tty_lock(); | ||
1552 | } | 1556 | } |
1553 | set_current_state( TASK_RUNNING ); | 1557 | set_current_state( TASK_RUNNING ); |
1554 | remove_wait_queue(&pCh->open_wait, &wait); | 1558 | remove_wait_queue(&pCh->open_wait, &wait); |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 98310e1aae30..c27e9d21fea9 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -124,7 +124,6 @@ | |||
124 | #include <linux/fs.h> | 124 | #include <linux/fs.h> |
125 | #include <linux/sched.h> | 125 | #include <linux/sched.h> |
126 | #include <linux/serial.h> | 126 | #include <linux/serial.h> |
127 | #include <linux/smp_lock.h> | ||
128 | #include <linux/mm.h> | 127 | #include <linux/mm.h> |
129 | #include <linux/interrupt.h> | 128 | #include <linux/interrupt.h> |
130 | #include <linux/timer.h> | 129 | #include <linux/timer.h> |
@@ -872,7 +871,6 @@ static struct tty_port *isicom_find_port(struct tty_struct *tty) | |||
872 | static int isicom_open(struct tty_struct *tty, struct file *filp) | 871 | static int isicom_open(struct tty_struct *tty, struct file *filp) |
873 | { | 872 | { |
874 | struct isi_port *port; | 873 | struct isi_port *port; |
875 | struct isi_board *card; | ||
876 | struct tty_port *tport; | 874 | struct tty_port *tport; |
877 | 875 | ||
878 | tport = isicom_find_port(tty); | 876 | tport = isicom_find_port(tty); |
@@ -1118,8 +1116,7 @@ static int isicom_set_serial_info(struct tty_struct *tty, | |||
1118 | if (copy_from_user(&newinfo, info, sizeof(newinfo))) | 1116 | if (copy_from_user(&newinfo, info, sizeof(newinfo))) |
1119 | return -EFAULT; | 1117 | return -EFAULT; |
1120 | 1118 | ||
1121 | lock_kernel(); | 1119 | mutex_lock(&port->port.mutex); |
1122 | |||
1123 | reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != | 1120 | reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != |
1124 | (newinfo.flags & ASYNC_SPD_MASK)); | 1121 | (newinfo.flags & ASYNC_SPD_MASK)); |
1125 | 1122 | ||
@@ -1128,7 +1125,7 @@ static int isicom_set_serial_info(struct tty_struct *tty, | |||
1128 | (newinfo.closing_wait != port->port.closing_wait) || | 1125 | (newinfo.closing_wait != port->port.closing_wait) || |
1129 | ((newinfo.flags & ~ASYNC_USR_MASK) != | 1126 | ((newinfo.flags & ~ASYNC_USR_MASK) != |
1130 | (port->port.flags & ~ASYNC_USR_MASK))) { | 1127 | (port->port.flags & ~ASYNC_USR_MASK))) { |
1131 | unlock_kernel(); | 1128 | mutex_unlock(&port->port.mutex); |
1132 | return -EPERM; | 1129 | return -EPERM; |
1133 | } | 1130 | } |
1134 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | | 1131 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | |
@@ -1145,7 +1142,7 @@ static int isicom_set_serial_info(struct tty_struct *tty, | |||
1145 | isicom_config_port(tty); | 1142 | isicom_config_port(tty); |
1146 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1143 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1147 | } | 1144 | } |
1148 | unlock_kernel(); | 1145 | mutex_unlock(&port->port.mutex); |
1149 | return 0; | 1146 | return 0; |
1150 | } | 1147 | } |
1151 | 1148 | ||
@@ -1154,7 +1151,7 @@ static int isicom_get_serial_info(struct isi_port *port, | |||
1154 | { | 1151 | { |
1155 | struct serial_struct out_info; | 1152 | struct serial_struct out_info; |
1156 | 1153 | ||
1157 | lock_kernel(); | 1154 | mutex_lock(&port->port.mutex); |
1158 | memset(&out_info, 0, sizeof(out_info)); | 1155 | memset(&out_info, 0, sizeof(out_info)); |
1159 | /* out_info.type = ? */ | 1156 | /* out_info.type = ? */ |
1160 | out_info.line = port - isi_ports; | 1157 | out_info.line = port - isi_ports; |
@@ -1164,7 +1161,7 @@ static int isicom_get_serial_info(struct isi_port *port, | |||
1164 | /* out_info.baud_base = ? */ | 1161 | /* out_info.baud_base = ? */ |
1165 | out_info.close_delay = port->port.close_delay; | 1162 | out_info.close_delay = port->port.close_delay; |
1166 | out_info.closing_wait = port->port.closing_wait; | 1163 | out_info.closing_wait = port->port.closing_wait; |
1167 | unlock_kernel(); | 1164 | mutex_unlock(&port->port.mutex); |
1168 | if (copy_to_user(info, &out_info, sizeof(out_info))) | 1165 | if (copy_to_user(info, &out_info, sizeof(out_info))) |
1169 | return -EFAULT; | 1166 | return -EFAULT; |
1170 | return 0; | 1167 | return 0; |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 4e395c956a09..be28391adb79 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -203,9 +203,9 @@ static int stli_shared; | |||
203 | * the board has been detected, and whether it is actually running a slave | 203 | * the board has been detected, and whether it is actually running a slave |
204 | * or not. | 204 | * or not. |
205 | */ | 205 | */ |
206 | #define BST_FOUND 0x1 | 206 | #define BST_FOUND 0 |
207 | #define BST_STARTED 0x2 | 207 | #define BST_STARTED 1 |
208 | #define BST_PROBED 0x4 | 208 | #define BST_PROBED 2 |
209 | 209 | ||
210 | /* | 210 | /* |
211 | * Define the set of port state flags. These are marked for internal | 211 | * Define the set of port state flags. These are marked for internal |
@@ -816,7 +816,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
816 | brdp = stli_brds[brdnr]; | 816 | brdp = stli_brds[brdnr]; |
817 | if (brdp == NULL) | 817 | if (brdp == NULL) |
818 | return -ENODEV; | 818 | return -ENODEV; |
819 | if ((brdp->state & BST_STARTED) == 0) | 819 | if (!test_bit(BST_STARTED, &brdp->state)) |
820 | return -ENODEV; | 820 | return -ENODEV; |
821 | portnr = MINOR2PORT(minordev); | 821 | portnr = MINOR2PORT(minordev); |
822 | if (portnr > brdp->nrports) | 822 | if (portnr > brdp->nrports) |
@@ -954,7 +954,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l | |||
954 | * order of opens and closes may not be preserved across shared | 954 | * order of opens and closes may not be preserved across shared |
955 | * memory, so we must wait until it is complete. | 955 | * memory, so we must wait until it is complete. |
956 | */ | 956 | */ |
957 | wait_event_interruptible(portp->raw_wait, | 957 | wait_event_interruptible_tty(portp->raw_wait, |
958 | !test_bit(ST_CLOSING, &portp->state)); | 958 | !test_bit(ST_CLOSING, &portp->state)); |
959 | if (signal_pending(current)) { | 959 | if (signal_pending(current)) { |
960 | return -ERESTARTSYS; | 960 | return -ERESTARTSYS; |
@@ -989,7 +989,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l | |||
989 | set_bit(ST_OPENING, &portp->state); | 989 | set_bit(ST_OPENING, &portp->state); |
990 | spin_unlock_irqrestore(&brd_lock, flags); | 990 | spin_unlock_irqrestore(&brd_lock, flags); |
991 | 991 | ||
992 | wait_event_interruptible(portp->raw_wait, | 992 | wait_event_interruptible_tty(portp->raw_wait, |
993 | !test_bit(ST_OPENING, &portp->state)); | 993 | !test_bit(ST_OPENING, &portp->state)); |
994 | if (signal_pending(current)) | 994 | if (signal_pending(current)) |
995 | rc = -ERESTARTSYS; | 995 | rc = -ERESTARTSYS; |
@@ -1020,7 +1020,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned | |||
1020 | * occurs on this port. | 1020 | * occurs on this port. |
1021 | */ | 1021 | */ |
1022 | if (wait) { | 1022 | if (wait) { |
1023 | wait_event_interruptible(portp->raw_wait, | 1023 | wait_event_interruptible_tty(portp->raw_wait, |
1024 | !test_bit(ST_CLOSING, &portp->state)); | 1024 | !test_bit(ST_CLOSING, &portp->state)); |
1025 | if (signal_pending(current)) { | 1025 | if (signal_pending(current)) { |
1026 | return -ERESTARTSYS; | 1026 | return -ERESTARTSYS; |
@@ -1052,7 +1052,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned | |||
1052 | * to come back. | 1052 | * to come back. |
1053 | */ | 1053 | */ |
1054 | rc = 0; | 1054 | rc = 0; |
1055 | wait_event_interruptible(portp->raw_wait, | 1055 | wait_event_interruptible_tty(portp->raw_wait, |
1056 | !test_bit(ST_CLOSING, &portp->state)); | 1056 | !test_bit(ST_CLOSING, &portp->state)); |
1057 | if (signal_pending(current)) | 1057 | if (signal_pending(current)) |
1058 | rc = -ERESTARTSYS; | 1058 | rc = -ERESTARTSYS; |
@@ -1073,6 +1073,10 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned | |||
1073 | 1073 | ||
1074 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) | 1074 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) |
1075 | { | 1075 | { |
1076 | /* | ||
1077 | * no need for wait_event_tty because clearing ST_CMDING cannot block | ||
1078 | * on BTM | ||
1079 | */ | ||
1076 | wait_event_interruptible(portp->raw_wait, | 1080 | wait_event_interruptible(portp->raw_wait, |
1077 | !test_bit(ST_CMDING, &portp->state)); | 1081 | !test_bit(ST_CMDING, &portp->state)); |
1078 | if (signal_pending(current)) | 1082 | if (signal_pending(current)) |
@@ -1846,7 +1850,7 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip | |||
1846 | rc = stli_portcmdstats(NULL, portp); | 1850 | rc = stli_portcmdstats(NULL, portp); |
1847 | 1851 | ||
1848 | uart = "UNKNOWN"; | 1852 | uart = "UNKNOWN"; |
1849 | if (brdp->state & BST_STARTED) { | 1853 | if (test_bit(BST_STARTED, &brdp->state)) { |
1850 | switch (stli_comstats.hwid) { | 1854 | switch (stli_comstats.hwid) { |
1851 | case 0: uart = "2681"; break; | 1855 | case 0: uart = "2681"; break; |
1852 | case 1: uart = "SC26198"; break; | 1856 | case 1: uart = "SC26198"; break; |
@@ -1855,7 +1859,7 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip | |||
1855 | } | 1859 | } |
1856 | seq_printf(m, "%d: uart:%s ", portnr, uart); | 1860 | seq_printf(m, "%d: uart:%s ", portnr, uart); |
1857 | 1861 | ||
1858 | if ((brdp->state & BST_STARTED) && (rc >= 0)) { | 1862 | if (test_bit(BST_STARTED, &brdp->state) && rc >= 0) { |
1859 | char sep; | 1863 | char sep; |
1860 | 1864 | ||
1861 | seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, | 1865 | seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, |
@@ -2355,7 +2359,7 @@ static void stli_poll(unsigned long arg) | |||
2355 | brdp = stli_brds[brdnr]; | 2359 | brdp = stli_brds[brdnr]; |
2356 | if (brdp == NULL) | 2360 | if (brdp == NULL) |
2357 | continue; | 2361 | continue; |
2358 | if ((brdp->state & BST_STARTED) == 0) | 2362 | if (!test_bit(BST_STARTED, &brdp->state)) |
2359 | continue; | 2363 | continue; |
2360 | 2364 | ||
2361 | spin_lock(&brd_lock); | 2365 | spin_lock(&brd_lock); |
@@ -3140,7 +3144,7 @@ static int stli_initecp(struct stlibrd *brdp) | |||
3140 | } | 3144 | } |
3141 | 3145 | ||
3142 | 3146 | ||
3143 | brdp->state |= BST_FOUND; | 3147 | set_bit(BST_FOUND, &brdp->state); |
3144 | return 0; | 3148 | return 0; |
3145 | err_unmap: | 3149 | err_unmap: |
3146 | iounmap(brdp->membase); | 3150 | iounmap(brdp->membase); |
@@ -3297,7 +3301,7 @@ static int stli_initonb(struct stlibrd *brdp) | |||
3297 | brdp->panels[0] = brdp->nrports; | 3301 | brdp->panels[0] = brdp->nrports; |
3298 | 3302 | ||
3299 | 3303 | ||
3300 | brdp->state |= BST_FOUND; | 3304 | set_bit(BST_FOUND, &brdp->state); |
3301 | return 0; | 3305 | return 0; |
3302 | err_unmap: | 3306 | err_unmap: |
3303 | iounmap(brdp->membase); | 3307 | iounmap(brdp->membase); |
@@ -3407,7 +3411,7 @@ stli_donestartup: | |||
3407 | spin_unlock_irqrestore(&brd_lock, flags); | 3411 | spin_unlock_irqrestore(&brd_lock, flags); |
3408 | 3412 | ||
3409 | if (rc == 0) | 3413 | if (rc == 0) |
3410 | brdp->state |= BST_STARTED; | 3414 | set_bit(BST_STARTED, &brdp->state); |
3411 | 3415 | ||
3412 | if (! stli_timeron) { | 3416 | if (! stli_timeron) { |
3413 | stli_timeron++; | 3417 | stli_timeron++; |
@@ -3710,7 +3714,7 @@ static int __devinit stli_pciprobe(struct pci_dev *pdev, | |||
3710 | if (retval) | 3714 | if (retval) |
3711 | goto err_null; | 3715 | goto err_null; |
3712 | 3716 | ||
3713 | brdp->state |= BST_PROBED; | 3717 | set_bit(BST_PROBED, &brdp->state); |
3714 | pci_set_drvdata(pdev, brdp); | 3718 | pci_set_drvdata(pdev, brdp); |
3715 | 3719 | ||
3716 | EBRDENABLE(brdp); | 3720 | EBRDENABLE(brdp); |
@@ -3841,7 +3845,7 @@ static int __init stli_initbrds(void) | |||
3841 | brdp = stli_brds[i]; | 3845 | brdp = stli_brds[i]; |
3842 | if (brdp == NULL) | 3846 | if (brdp == NULL) |
3843 | continue; | 3847 | continue; |
3844 | if (brdp->state & BST_FOUND) { | 3848 | if (test_bit(BST_FOUND, &brdp->state)) { |
3845 | EBRDENABLE(brdp); | 3849 | EBRDENABLE(brdp); |
3846 | brdp->enable = NULL; | 3850 | brdp->enable = NULL; |
3847 | brdp->disable = NULL; | 3851 | brdp->disable = NULL; |
@@ -4011,6 +4015,7 @@ static int stli_getbrdstats(combrd_t __user *bp) | |||
4011 | return -ENODEV; | 4015 | return -ENODEV; |
4012 | 4016 | ||
4013 | memset(&stli_brdstats, 0, sizeof(combrd_t)); | 4017 | memset(&stli_brdstats, 0, sizeof(combrd_t)); |
4018 | |||
4014 | stli_brdstats.brd = brdp->brdnr; | 4019 | stli_brdstats.brd = brdp->brdnr; |
4015 | stli_brdstats.type = brdp->brdtype; | 4020 | stli_brdstats.type = brdp->brdtype; |
4016 | stli_brdstats.hwid = 0; | 4021 | stli_brdstats.hwid = 0; |
@@ -4076,10 +4081,13 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) | |||
4076 | if (brdp == NULL) | 4081 | if (brdp == NULL) |
4077 | return -ENODEV; | 4082 | return -ENODEV; |
4078 | 4083 | ||
4079 | if (brdp->state & BST_STARTED) { | 4084 | mutex_lock(&portp->port.mutex); |
4085 | if (test_bit(BST_STARTED, &brdp->state)) { | ||
4080 | if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, | 4086 | if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, |
4081 | &stli_cdkstats, sizeof(asystats_t), 1)) < 0) | 4087 | &stli_cdkstats, sizeof(asystats_t), 1)) < 0) { |
4088 | mutex_unlock(&portp->port.mutex); | ||
4082 | return rc; | 4089 | return rc; |
4090 | } | ||
4083 | } else { | 4091 | } else { |
4084 | memset(&stli_cdkstats, 0, sizeof(asystats_t)); | 4092 | memset(&stli_cdkstats, 0, sizeof(asystats_t)); |
4085 | } | 4093 | } |
@@ -4124,6 +4132,7 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) | |||
4124 | stli_comstats.modem = stli_cdkstats.dcdcnt; | 4132 | stli_comstats.modem = stli_cdkstats.dcdcnt; |
4125 | stli_comstats.hwid = stli_cdkstats.hwid; | 4133 | stli_comstats.hwid = stli_cdkstats.hwid; |
4126 | stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); | 4134 | stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); |
4135 | mutex_unlock(&portp->port.mutex); | ||
4127 | 4136 | ||
4128 | return 0; | 4137 | return 0; |
4129 | } | 4138 | } |
@@ -4186,15 +4195,20 @@ static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) | |||
4186 | if (!brdp) | 4195 | if (!brdp) |
4187 | return -ENODEV; | 4196 | return -ENODEV; |
4188 | 4197 | ||
4189 | if (brdp->state & BST_STARTED) { | 4198 | mutex_lock(&portp->port.mutex); |
4190 | if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) | 4199 | |
4200 | if (test_bit(BST_STARTED, &brdp->state)) { | ||
4201 | if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) { | ||
4202 | mutex_unlock(&portp->port.mutex); | ||
4191 | return rc; | 4203 | return rc; |
4204 | } | ||
4192 | } | 4205 | } |
4193 | 4206 | ||
4194 | memset(&stli_comstats, 0, sizeof(comstats_t)); | 4207 | memset(&stli_comstats, 0, sizeof(comstats_t)); |
4195 | stli_comstats.brd = portp->brdnr; | 4208 | stli_comstats.brd = portp->brdnr; |
4196 | stli_comstats.panel = portp->panelnr; | 4209 | stli_comstats.panel = portp->panelnr; |
4197 | stli_comstats.port = portp->portnr; | 4210 | stli_comstats.port = portp->portnr; |
4211 | mutex_unlock(&portp->port.mutex); | ||
4198 | 4212 | ||
4199 | if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t))) | 4213 | if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t))) |
4200 | return -EFAULT; | 4214 | return -EFAULT; |
@@ -4266,8 +4280,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
4266 | done = 0; | 4280 | done = 0; |
4267 | rc = 0; | 4281 | rc = 0; |
4268 | 4282 | ||
4269 | lock_kernel(); | ||
4270 | |||
4271 | switch (cmd) { | 4283 | switch (cmd) { |
4272 | case COM_GETPORTSTATS: | 4284 | case COM_GETPORTSTATS: |
4273 | rc = stli_getportstats(NULL, NULL, argp); | 4285 | rc = stli_getportstats(NULL, NULL, argp); |
@@ -4290,8 +4302,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
4290 | done++; | 4302 | done++; |
4291 | break; | 4303 | break; |
4292 | } | 4304 | } |
4293 | unlock_kernel(); | ||
4294 | |||
4295 | if (done) | 4305 | if (done) |
4296 | return rc; | 4306 | return rc; |
4297 | 4307 | ||
@@ -4308,8 +4318,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
4308 | if (brdp->state == 0) | 4318 | if (brdp->state == 0) |
4309 | return -ENODEV; | 4319 | return -ENODEV; |
4310 | 4320 | ||
4311 | lock_kernel(); | ||
4312 | |||
4313 | switch (cmd) { | 4321 | switch (cmd) { |
4314 | case STL_BINTR: | 4322 | case STL_BINTR: |
4315 | EBRDINTR(brdp); | 4323 | EBRDINTR(brdp); |
@@ -4318,10 +4326,10 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
4318 | rc = stli_startbrd(brdp); | 4326 | rc = stli_startbrd(brdp); |
4319 | break; | 4327 | break; |
4320 | case STL_BSTOP: | 4328 | case STL_BSTOP: |
4321 | brdp->state &= ~BST_STARTED; | 4329 | clear_bit(BST_STARTED, &brdp->state); |
4322 | break; | 4330 | break; |
4323 | case STL_BRESET: | 4331 | case STL_BRESET: |
4324 | brdp->state &= ~BST_STARTED; | 4332 | clear_bit(BST_STARTED, &brdp->state); |
4325 | EBRDRESET(brdp); | 4333 | EBRDRESET(brdp); |
4326 | if (stli_shared == 0) { | 4334 | if (stli_shared == 0) { |
4327 | if (brdp->reenable != NULL) | 4335 | if (brdp->reenable != NULL) |
@@ -4332,7 +4340,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
4332 | rc = -ENOIOCTLCMD; | 4340 | rc = -ENOIOCTLCMD; |
4333 | break; | 4341 | break; |
4334 | } | 4342 | } |
4335 | unlock_kernel(); | ||
4336 | return rc; | 4343 | return rc; |
4337 | } | 4344 | } |
4338 | 4345 | ||
@@ -4378,7 +4385,8 @@ static void istallion_cleanup_isa(void) | |||
4378 | unsigned int j; | 4385 | unsigned int j; |
4379 | 4386 | ||
4380 | for (j = 0; (j < stli_nrbrds); j++) { | 4387 | for (j = 0; (j < stli_nrbrds); j++) { |
4381 | if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED)) | 4388 | if ((brdp = stli_brds[j]) == NULL || |
4389 | test_bit(BST_PROBED, &brdp->state)) | ||
4382 | continue; | 4390 | continue; |
4383 | 4391 | ||
4384 | stli_cleanup_ports(brdp); | 4392 | stli_cleanup_ports(brdp); |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 25be2102a60a..a7ca75212bfe 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -299,7 +299,7 @@ int kbd_rate(struct kbd_repeat *rep) | |||
299 | */ | 299 | */ |
300 | static void put_queue(struct vc_data *vc, int ch) | 300 | static void put_queue(struct vc_data *vc, int ch) |
301 | { | 301 | { |
302 | struct tty_struct *tty = vc->vc_tty; | 302 | struct tty_struct *tty = vc->port.tty; |
303 | 303 | ||
304 | if (tty) { | 304 | if (tty) { |
305 | tty_insert_flip_char(tty, ch, 0); | 305 | tty_insert_flip_char(tty, ch, 0); |
@@ -309,7 +309,7 @@ static void put_queue(struct vc_data *vc, int ch) | |||
309 | 309 | ||
310 | static void puts_queue(struct vc_data *vc, char *cp) | 310 | static void puts_queue(struct vc_data *vc, char *cp) |
311 | { | 311 | { |
312 | struct tty_struct *tty = vc->vc_tty; | 312 | struct tty_struct *tty = vc->port.tty; |
313 | 313 | ||
314 | if (!tty) | 314 | if (!tty) |
315 | return; | 315 | return; |
@@ -485,7 +485,7 @@ static void fn_show_ptregs(struct vc_data *vc) | |||
485 | 485 | ||
486 | static void fn_hold(struct vc_data *vc) | 486 | static void fn_hold(struct vc_data *vc) |
487 | { | 487 | { |
488 | struct tty_struct *tty = vc->vc_tty; | 488 | struct tty_struct *tty = vc->port.tty; |
489 | 489 | ||
490 | if (rep || !tty) | 490 | if (rep || !tty) |
491 | return; | 491 | return; |
@@ -563,7 +563,7 @@ static void fn_inc_console(struct vc_data *vc) | |||
563 | 563 | ||
564 | static void fn_send_intr(struct vc_data *vc) | 564 | static void fn_send_intr(struct vc_data *vc) |
565 | { | 565 | { |
566 | struct tty_struct *tty = vc->vc_tty; | 566 | struct tty_struct *tty = vc->port.tty; |
567 | 567 | ||
568 | if (!tty) | 568 | if (!tty) |
569 | return; | 569 | return; |
@@ -1162,7 +1162,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1162 | struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; | 1162 | struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; |
1163 | int rc; | 1163 | int rc; |
1164 | 1164 | ||
1165 | tty = vc->vc_tty; | 1165 | tty = vc->port.tty; |
1166 | 1166 | ||
1167 | if (tty && (!tty->driver_data)) { | 1167 | if (tty && (!tty->driver_data)) { |
1168 | /* No driver data? Strange. Okay we fix it then. */ | 1168 | /* No driver data? Strange. Okay we fix it then. */ |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index d2692d443f7b..3fc89da856ae 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -2193,7 +2193,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port | |||
2193 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | 2193 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); |
2194 | port->icount.tx += (cnt - port->xmit_cnt); | 2194 | port->icount.tx += (cnt - port->xmit_cnt); |
2195 | 2195 | ||
2196 | if (port->xmit_cnt < WAKEUP_CHARS && tty) | 2196 | if (port->xmit_cnt < WAKEUP_CHARS) |
2197 | tty_wakeup(tty); | 2197 | tty_wakeup(tty); |
2198 | 2198 | ||
2199 | if (port->xmit_cnt <= 0) { | 2199 | if (port->xmit_cnt <= 0) { |
diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c index e4089c432f15..099105e0894e 100644 --- a/drivers/char/n_gsm.c +++ b/drivers/char/n_gsm.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
44 | #include <linux/interrupt.h> | 44 | #include <linux/interrupt.h> |
45 | #include <linux/tty.h> | 45 | #include <linux/tty.h> |
46 | #include <linux/timer.h> | ||
47 | #include <linux/ctype.h> | 46 | #include <linux/ctype.h> |
48 | #include <linux/mm.h> | 47 | #include <linux/mm.h> |
49 | #include <linux/string.h> | 48 | #include <linux/string.h> |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index c68118efad84..47d32281032c 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -598,18 +598,18 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
598 | return -EFAULT; | 598 | return -EFAULT; |
599 | } | 599 | } |
600 | 600 | ||
601 | lock_kernel(); | 601 | tty_lock(); |
602 | 602 | ||
603 | for (;;) { | 603 | for (;;) { |
604 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { | 604 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
605 | unlock_kernel(); | 605 | tty_unlock(); |
606 | return -EIO; | 606 | return -EIO; |
607 | } | 607 | } |
608 | 608 | ||
609 | n_hdlc = tty2n_hdlc (tty); | 609 | n_hdlc = tty2n_hdlc (tty); |
610 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || | 610 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || |
611 | tty != n_hdlc->tty) { | 611 | tty != n_hdlc->tty) { |
612 | unlock_kernel(); | 612 | tty_unlock(); |
613 | return 0; | 613 | return 0; |
614 | } | 614 | } |
615 | 615 | ||
@@ -619,13 +619,13 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
619 | 619 | ||
620 | /* no data */ | 620 | /* no data */ |
621 | if (file->f_flags & O_NONBLOCK) { | 621 | if (file->f_flags & O_NONBLOCK) { |
622 | unlock_kernel(); | 622 | tty_unlock(); |
623 | return -EAGAIN; | 623 | return -EAGAIN; |
624 | } | 624 | } |
625 | 625 | ||
626 | interruptible_sleep_on (&tty->read_wait); | 626 | interruptible_sleep_on (&tty->read_wait); |
627 | if (signal_pending(current)) { | 627 | if (signal_pending(current)) { |
628 | unlock_kernel(); | 628 | tty_unlock(); |
629 | return -EINTR; | 629 | return -EINTR; |
630 | } | 630 | } |
631 | } | 631 | } |
@@ -648,7 +648,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
648 | kfree(rbuf); | 648 | kfree(rbuf); |
649 | else | 649 | else |
650 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); | 650 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); |
651 | unlock_kernel(); | 651 | tty_unlock(); |
652 | return ret; | 652 | return ret; |
653 | 653 | ||
654 | } /* end of n_hdlc_tty_read() */ | 654 | } /* end of n_hdlc_tty_read() */ |
@@ -691,7 +691,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
691 | count = maxframe; | 691 | count = maxframe; |
692 | } | 692 | } |
693 | 693 | ||
694 | lock_kernel(); | 694 | tty_lock(); |
695 | 695 | ||
696 | add_wait_queue(&tty->write_wait, &wait); | 696 | add_wait_queue(&tty->write_wait, &wait); |
697 | set_current_state(TASK_INTERRUPTIBLE); | 697 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -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 | unlock_kernel(); | 734 | tty_unlock(); |
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/char/n_r3964.c b/drivers/char/n_r3964.c index c1d8b54c816d..a98290d7a2c5 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -1067,7 +1067,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1067 | 1067 | ||
1068 | TRACE_L("read()"); | 1068 | TRACE_L("read()"); |
1069 | 1069 | ||
1070 | lock_kernel(); | 1070 | tty_lock(); |
1071 | 1071 | ||
1072 | pClient = findClient(pInfo, task_pid(current)); | 1072 | pClient = findClient(pInfo, task_pid(current)); |
1073 | if (pClient) { | 1073 | if (pClient) { |
@@ -1079,7 +1079,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1079 | goto unlock; | 1079 | goto unlock; |
1080 | } | 1080 | } |
1081 | /* block until there is a message: */ | 1081 | /* block until there is a message: */ |
1082 | wait_event_interruptible(pInfo->read_wait, | 1082 | wait_event_interruptible_tty(pInfo->read_wait, |
1083 | (pMsg = remove_msg(pInfo, pClient))); | 1083 | (pMsg = remove_msg(pInfo, pClient))); |
1084 | } | 1084 | } |
1085 | 1085 | ||
@@ -1109,7 +1109,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1109 | } | 1109 | } |
1110 | ret = -EPERM; | 1110 | ret = -EPERM; |
1111 | unlock: | 1111 | unlock: |
1112 | unlock_kernel(); | 1112 | tty_unlock(); |
1113 | return ret; | 1113 | return ret; |
1114 | } | 1114 | } |
1115 | 1115 | ||
@@ -1158,7 +1158,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1158 | pHeader->locks = 0; | 1158 | pHeader->locks = 0; |
1159 | pHeader->owner = NULL; | 1159 | pHeader->owner = NULL; |
1160 | 1160 | ||
1161 | lock_kernel(); | 1161 | tty_lock(); |
1162 | 1162 | ||
1163 | pClient = findClient(pInfo, task_pid(current)); | 1163 | pClient = findClient(pInfo, task_pid(current)); |
1164 | if (pClient) { | 1164 | if (pClient) { |
@@ -1177,7 +1177,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1177 | add_tx_queue(pInfo, pHeader); | 1177 | add_tx_queue(pInfo, pHeader); |
1178 | trigger_transmit(pInfo); | 1178 | trigger_transmit(pInfo); |
1179 | 1179 | ||
1180 | unlock_kernel(); | 1180 | tty_unlock(); |
1181 | 1181 | ||
1182 | return 0; | 1182 | return 0; |
1183 | } | 1183 | } |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index bdae8327143c..428f4fe0b5f7 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -1102,6 +1102,11 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
1102 | if (I_IUCLC(tty) && L_IEXTEN(tty)) | 1102 | if (I_IUCLC(tty) && L_IEXTEN(tty)) |
1103 | c = tolower(c); | 1103 | c = tolower(c); |
1104 | 1104 | ||
1105 | if (L_EXTPROC(tty)) { | ||
1106 | put_tty_queue(c, tty); | ||
1107 | return; | ||
1108 | } | ||
1109 | |||
1105 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && | 1110 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && |
1106 | I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && | 1111 | I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && |
1107 | c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { | 1112 | c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { |
@@ -1409,7 +1414,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1409 | 1414 | ||
1410 | n_tty_set_room(tty); | 1415 | n_tty_set_room(tty); |
1411 | 1416 | ||
1412 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { | 1417 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || |
1418 | L_EXTPROC(tty)) { | ||
1413 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1419 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1414 | if (waitqueue_active(&tty->read_wait)) | 1420 | if (waitqueue_active(&tty->read_wait)) |
1415 | wake_up_interruptible(&tty->read_wait); | 1421 | wake_up_interruptible(&tty->read_wait); |
@@ -1585,7 +1591,7 @@ static int n_tty_open(struct tty_struct *tty) | |||
1585 | static inline int input_available_p(struct tty_struct *tty, int amt) | 1591 | static inline int input_available_p(struct tty_struct *tty, int amt) |
1586 | { | 1592 | { |
1587 | tty_flush_to_ldisc(tty); | 1593 | tty_flush_to_ldisc(tty); |
1588 | if (tty->icanon) { | 1594 | if (tty->icanon && !L_EXTPROC(tty)) { |
1589 | if (tty->canon_data) | 1595 | if (tty->canon_data) |
1590 | return 1; | 1596 | return 1; |
1591 | } else if (tty->read_cnt >= (amt ? amt : 1)) | 1597 | } else if (tty->read_cnt >= (amt ? amt : 1)) |
@@ -1632,6 +1638,11 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1632 | spin_lock_irqsave(&tty->read_lock, flags); | 1638 | spin_lock_irqsave(&tty->read_lock, flags); |
1633 | tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); | 1639 | tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); |
1634 | tty->read_cnt -= n; | 1640 | tty->read_cnt -= n; |
1641 | /* Turn single EOF into zero-length read */ | ||
1642 | if (L_EXTPROC(tty) && tty->icanon && n == 1) { | ||
1643 | if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty)) | ||
1644 | n--; | ||
1645 | } | ||
1635 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1646 | spin_unlock_irqrestore(&tty->read_lock, flags); |
1636 | *b += n; | 1647 | *b += n; |
1637 | *nr -= n; | 1648 | *nr -= n; |
@@ -1812,7 +1823,7 @@ do_it_again: | |||
1812 | nr--; | 1823 | nr--; |
1813 | } | 1824 | } |
1814 | 1825 | ||
1815 | if (tty->icanon) { | 1826 | if (tty->icanon && !L_EXTPROC(tty)) { |
1816 | /* N.B. avoid overrun if nr == 0 */ | 1827 | /* N.B. avoid overrun if nr == 0 */ |
1817 | while (nr && tty->read_cnt) { | 1828 | while (nr && tty->read_cnt) { |
1818 | int eol; | 1829 | int eol; |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index a6638003f530..18af923093c3 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -1611,6 +1611,8 @@ static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
1611 | ret = tty_init_termios(tty); | 1611 | ret = tty_init_termios(tty); |
1612 | if (ret == 0) { | 1612 | if (ret == 0) { |
1613 | tty_driver_kref_get(driver); | 1613 | tty_driver_kref_get(driver); |
1614 | tty->count++; | ||
1615 | tty->driver_data = port; | ||
1614 | driver->ttys[tty->index] = tty; | 1616 | driver->ttys[tty->index] = tty; |
1615 | } | 1617 | } |
1616 | return ret; | 1618 | return ret; |
@@ -1639,7 +1641,7 @@ static int ntty_activate(struct tty_port *tport, struct tty_struct *tty) | |||
1639 | 1641 | ||
1640 | static int ntty_open(struct tty_struct *tty, struct file *filp) | 1642 | static int ntty_open(struct tty_struct *tty, struct file *filp) |
1641 | { | 1643 | { |
1642 | struct port *port = get_port_by_tty(tty); | 1644 | struct port *port = tty->driver_data; |
1643 | return tty_port_open(&port->port, tty, filp); | 1645 | return tty_port_open(&port->port, tty, filp); |
1644 | } | 1646 | } |
1645 | 1647 | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index d83a43130df4..ad46eae1f9bb 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -62,7 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
62 | if (tty->driver == ptm_driver) | 62 | if (tty->driver == ptm_driver) |
63 | devpts_pty_kill(tty->link); | 63 | devpts_pty_kill(tty->link); |
64 | #endif | 64 | #endif |
65 | tty_unlock(); | ||
65 | tty_vhangup(tty->link); | 66 | tty_vhangup(tty->link); |
67 | tty_lock(); | ||
66 | } | 68 | } |
67 | } | 69 | } |
68 | 70 | ||
@@ -171,6 +173,23 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg) | |||
171 | return 0; | 173 | return 0; |
172 | } | 174 | } |
173 | 175 | ||
176 | /* Send a signal to the slave */ | ||
177 | static int pty_signal(struct tty_struct *tty, int sig) | ||
178 | { | ||
179 | unsigned long flags; | ||
180 | struct pid *pgrp; | ||
181 | |||
182 | if (tty->link) { | ||
183 | spin_lock_irqsave(&tty->link->ctrl_lock, flags); | ||
184 | pgrp = get_pid(tty->link->pgrp); | ||
185 | spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); | ||
186 | |||
187 | kill_pgrp(pgrp, sig, 1); | ||
188 | put_pid(pgrp); | ||
189 | } | ||
190 | return 0; | ||
191 | } | ||
192 | |||
174 | static void pty_flush_buffer(struct tty_struct *tty) | 193 | static void pty_flush_buffer(struct tty_struct *tty) |
175 | { | 194 | { |
176 | struct tty_struct *to = tty->link; | 195 | struct tty_struct *to = tty->link; |
@@ -321,6 +340,8 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, | |||
321 | switch (cmd) { | 340 | switch (cmd) { |
322 | case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ | 341 | case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ |
323 | return pty_set_lock(tty, (int __user *) arg); | 342 | return pty_set_lock(tty, (int __user *) arg); |
343 | case TIOCSIG: /* Send signal to other side of pty */ | ||
344 | return pty_signal(tty, (int) arg); | ||
324 | } | 345 | } |
325 | return -ENOIOCTLCMD; | 346 | return -ENOIOCTLCMD; |
326 | } | 347 | } |
@@ -476,6 +497,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | |||
476 | return pty_set_lock(tty, (int __user *)arg); | 497 | return pty_set_lock(tty, (int __user *)arg); |
477 | case TIOCGPTN: /* Get PT Number */ | 498 | case TIOCGPTN: /* Get PT Number */ |
478 | return put_user(tty->index, (unsigned int __user *)arg); | 499 | return put_user(tty->index, (unsigned int __user *)arg); |
500 | case TIOCSIG: /* Send signal to other side of pty */ | ||
501 | return pty_signal(tty, (int) arg); | ||
479 | } | 502 | } |
480 | 503 | ||
481 | return -ENOIOCTLCMD; | 504 | return -ENOIOCTLCMD; |
@@ -626,7 +649,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
626 | * allocated_ptys_lock handles the list of free pty numbers | 649 | * allocated_ptys_lock handles the list of free pty numbers |
627 | */ | 650 | */ |
628 | 651 | ||
629 | static int __ptmx_open(struct inode *inode, struct file *filp) | 652 | static int ptmx_open(struct inode *inode, struct file *filp) |
630 | { | 653 | { |
631 | struct tty_struct *tty; | 654 | struct tty_struct *tty; |
632 | int retval; | 655 | int retval; |
@@ -635,11 +658,14 @@ static int __ptmx_open(struct inode *inode, struct file *filp) | |||
635 | nonseekable_open(inode, filp); | 658 | nonseekable_open(inode, filp); |
636 | 659 | ||
637 | /* find a device that is not in use. */ | 660 | /* find a device that is not in use. */ |
661 | tty_lock(); | ||
638 | index = devpts_new_index(inode); | 662 | index = devpts_new_index(inode); |
663 | tty_unlock(); | ||
639 | if (index < 0) | 664 | if (index < 0) |
640 | return index; | 665 | return index; |
641 | 666 | ||
642 | mutex_lock(&tty_mutex); | 667 | mutex_lock(&tty_mutex); |
668 | tty_lock(); | ||
643 | tty = tty_init_dev(ptm_driver, index, 1); | 669 | tty = tty_init_dev(ptm_driver, index, 1); |
644 | mutex_unlock(&tty_mutex); | 670 | mutex_unlock(&tty_mutex); |
645 | 671 | ||
@@ -657,26 +683,21 @@ static int __ptmx_open(struct inode *inode, struct file *filp) | |||
657 | goto out1; | 683 | goto out1; |
658 | 684 | ||
659 | retval = ptm_driver->ops->open(tty, filp); | 685 | retval = ptm_driver->ops->open(tty, filp); |
660 | if (!retval) | 686 | if (retval) |
661 | return 0; | 687 | goto out2; |
662 | out1: | 688 | out1: |
689 | tty_unlock(); | ||
690 | return retval; | ||
691 | out2: | ||
692 | tty_unlock(); | ||
663 | tty_release(inode, filp); | 693 | tty_release(inode, filp); |
664 | return retval; | 694 | return retval; |
665 | out: | 695 | out: |
666 | devpts_kill_index(inode, index); | 696 | devpts_kill_index(inode, index); |
697 | tty_unlock(); | ||
667 | return retval; | 698 | return retval; |
668 | } | 699 | } |
669 | 700 | ||
670 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
671 | { | ||
672 | int ret; | ||
673 | |||
674 | lock_kernel(); | ||
675 | ret = __ptmx_open(inode, filp); | ||
676 | unlock_kernel(); | ||
677 | return ret; | ||
678 | } | ||
679 | |||
680 | static struct file_operations ptmx_fops; | 701 | static struct file_operations ptmx_fops; |
681 | 702 | ||
682 | static void __init unix98_pty_init(void) | 703 | static void __init unix98_pty_init(void) |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index b02332a5412f..af4de1fe8445 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/tty_flip.h> | 49 | #include <linux/tty_flip.h> |
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
52 | #include <linux/device.h> | 51 | #include <linux/device.h> |
53 | 52 | ||
@@ -1184,6 +1183,7 @@ static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, | |||
1184 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) | 1183 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) |
1185 | return -EFAULT; | 1184 | return -EFAULT; |
1186 | 1185 | ||
1186 | mutex_lock(&port->port.mutex); | ||
1187 | change_speed = ((port->port.flags & ASYNC_SPD_MASK) != | 1187 | change_speed = ((port->port.flags & ASYNC_SPD_MASK) != |
1188 | (tmp.flags & ASYNC_SPD_MASK)); | 1188 | (tmp.flags & ASYNC_SPD_MASK)); |
1189 | 1189 | ||
@@ -1191,8 +1191,10 @@ static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, | |||
1191 | if ((tmp.close_delay != port->port.close_delay) || | 1191 | if ((tmp.close_delay != port->port.close_delay) || |
1192 | (tmp.closing_wait != port->port.closing_wait) || | 1192 | (tmp.closing_wait != port->port.closing_wait) || |
1193 | ((tmp.flags & ~ASYNC_USR_MASK) != | 1193 | ((tmp.flags & ~ASYNC_USR_MASK) != |
1194 | (port->port.flags & ~ASYNC_USR_MASK))) | 1194 | (port->port.flags & ~ASYNC_USR_MASK))) { |
1195 | mutex_unlock(&port->port.mutex); | ||
1195 | return -EPERM; | 1196 | return -EPERM; |
1197 | } | ||
1196 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | | 1198 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | |
1197 | (tmp.flags & ASYNC_USR_MASK)); | 1199 | (tmp.flags & ASYNC_USR_MASK)); |
1198 | } else { | 1200 | } else { |
@@ -1208,6 +1210,7 @@ static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, | |||
1208 | rc_change_speed(tty, bp, port); | 1210 | rc_change_speed(tty, bp, port); |
1209 | spin_unlock_irqrestore(&riscom_lock, flags); | 1211 | spin_unlock_irqrestore(&riscom_lock, flags); |
1210 | } | 1212 | } |
1213 | mutex_unlock(&port->port.mutex); | ||
1211 | return 0; | 1214 | return 0; |
1212 | } | 1215 | } |
1213 | 1216 | ||
@@ -1220,12 +1223,15 @@ static int rc_get_serial_info(struct riscom_port *port, | |||
1220 | memset(&tmp, 0, sizeof(tmp)); | 1223 | memset(&tmp, 0, sizeof(tmp)); |
1221 | tmp.type = PORT_CIRRUS; | 1224 | tmp.type = PORT_CIRRUS; |
1222 | tmp.line = port - rc_port; | 1225 | tmp.line = port - rc_port; |
1226 | |||
1227 | mutex_lock(&port->port.mutex); | ||
1223 | tmp.port = bp->base; | 1228 | tmp.port = bp->base; |
1224 | tmp.irq = bp->irq; | 1229 | tmp.irq = bp->irq; |
1225 | tmp.flags = port->port.flags; | 1230 | tmp.flags = port->port.flags; |
1226 | tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; | 1231 | tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; |
1227 | tmp.close_delay = port->port.close_delay * HZ/100; | 1232 | tmp.close_delay = port->port.close_delay * HZ/100; |
1228 | tmp.closing_wait = port->port.closing_wait * HZ/100; | 1233 | tmp.closing_wait = port->port.closing_wait * HZ/100; |
1234 | mutex_unlock(&port->port.mutex); | ||
1229 | tmp.xmit_fifo_size = CD180_NFIFO; | 1235 | tmp.xmit_fifo_size = CD180_NFIFO; |
1230 | return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 1236 | return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
1231 | } | 1237 | } |
@@ -1242,14 +1248,10 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp, | |||
1242 | 1248 | ||
1243 | switch (cmd) { | 1249 | switch (cmd) { |
1244 | case TIOCGSERIAL: | 1250 | case TIOCGSERIAL: |
1245 | lock_kernel(); | ||
1246 | retval = rc_get_serial_info(port, argp); | 1251 | retval = rc_get_serial_info(port, argp); |
1247 | unlock_kernel(); | ||
1248 | break; | 1252 | break; |
1249 | case TIOCSSERIAL: | 1253 | case TIOCSSERIAL: |
1250 | lock_kernel(); | ||
1251 | retval = rc_set_serial_info(tty, port, argp); | 1254 | retval = rc_set_serial_info(tty, port, argp); |
1252 | unlock_kernel(); | ||
1253 | break; | 1255 | break; |
1254 | default: | 1256 | default: |
1255 | retval = -ENOIOCTLCMD; | 1257 | retval = -ENOIOCTLCMD; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 0e29a23ec4c5..79c3bc69165a 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -73,7 +73,6 @@ | |||
73 | #include <linux/tty_driver.h> | 73 | #include <linux/tty_driver.h> |
74 | #include <linux/tty_flip.h> | 74 | #include <linux/tty_flip.h> |
75 | #include <linux/serial.h> | 75 | #include <linux/serial.h> |
76 | #include <linux/smp_lock.h> | ||
77 | #include <linux/string.h> | 76 | #include <linux/string.h> |
78 | #include <linux/fcntl.h> | 77 | #include <linux/fcntl.h> |
79 | #include <linux/ptrace.h> | 78 | #include <linux/ptrace.h> |
@@ -1017,6 +1016,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1017 | if (tty_port_close_start(port, tty, filp) == 0) | 1016 | if (tty_port_close_start(port, tty, filp) == 0) |
1018 | return; | 1017 | return; |
1019 | 1018 | ||
1019 | mutex_lock(&port->mutex); | ||
1020 | cp = &info->channel; | 1020 | cp = &info->channel; |
1021 | /* | 1021 | /* |
1022 | * Before we drop DTR, make sure the UART transmitter | 1022 | * Before we drop DTR, make sure the UART transmitter |
@@ -1060,9 +1060,13 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1060 | info->xmit_buf = NULL; | 1060 | info->xmit_buf = NULL; |
1061 | } | 1061 | } |
1062 | } | 1062 | } |
1063 | spin_lock_irq(&port->lock); | ||
1063 | info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); | 1064 | info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); |
1064 | tty->closing = 0; | 1065 | tty->closing = 0; |
1066 | spin_unlock_irq(&port->lock); | ||
1067 | mutex_unlock(&port->mutex); | ||
1065 | tty_port_tty_set(port, NULL); | 1068 | tty_port_tty_set(port, NULL); |
1069 | |||
1066 | wake_up_interruptible(&port->close_wait); | 1070 | wake_up_interruptible(&port->close_wait); |
1067 | complete_all(&info->close_wait); | 1071 | complete_all(&info->close_wait); |
1068 | atomic_dec(&rp_num_ports_open); | 1072 | atomic_dec(&rp_num_ports_open); |
@@ -1210,11 +1214,13 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo) | |||
1210 | if (!retinfo) | 1214 | if (!retinfo) |
1211 | return -EFAULT; | 1215 | return -EFAULT; |
1212 | memset(&tmp, 0, sizeof (tmp)); | 1216 | memset(&tmp, 0, sizeof (tmp)); |
1217 | mutex_lock(&info->port.mutex); | ||
1213 | tmp.line = info->line; | 1218 | tmp.line = info->line; |
1214 | tmp.flags = info->flags; | 1219 | tmp.flags = info->flags; |
1215 | tmp.close_delay = info->port.close_delay; | 1220 | tmp.close_delay = info->port.close_delay; |
1216 | tmp.closing_wait = info->port.closing_wait; | 1221 | tmp.closing_wait = info->port.closing_wait; |
1217 | tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; | 1222 | tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; |
1223 | mutex_unlock(&info->port.mutex); | ||
1218 | 1224 | ||
1219 | if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) | 1225 | if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) |
1220 | return -EFAULT; | 1226 | return -EFAULT; |
@@ -1229,10 +1235,13 @@ static int set_config(struct tty_struct *tty, struct r_port *info, | |||
1229 | if (copy_from_user(&new_serial, new_info, sizeof (new_serial))) | 1235 | if (copy_from_user(&new_serial, new_info, sizeof (new_serial))) |
1230 | return -EFAULT; | 1236 | return -EFAULT; |
1231 | 1237 | ||
1238 | mutex_lock(&info->port.mutex); | ||
1232 | if (!capable(CAP_SYS_ADMIN)) | 1239 | if (!capable(CAP_SYS_ADMIN)) |
1233 | { | 1240 | { |
1234 | if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) | 1241 | if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) { |
1242 | mutex_unlock(&info->port.mutex); | ||
1235 | return -EPERM; | 1243 | return -EPERM; |
1244 | } | ||
1236 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); | 1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); |
1237 | configure_r_port(tty, info, NULL); | 1246 | configure_r_port(tty, info, NULL); |
1238 | return 0; | 1247 | return 0; |
@@ -1250,6 +1259,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info, | |||
1250 | tty->alt_speed = 230400; | 1259 | tty->alt_speed = 230400; |
1251 | if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) | 1260 | if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) |
1252 | tty->alt_speed = 460800; | 1261 | tty->alt_speed = 460800; |
1262 | mutex_unlock(&info->port.mutex); | ||
1253 | 1263 | ||
1254 | configure_r_port(tty, info, NULL); | 1264 | configure_r_port(tty, info, NULL); |
1255 | return 0; | 1265 | return 0; |
@@ -1325,8 +1335,6 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file, | |||
1325 | if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) | 1335 | if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) |
1326 | return -ENXIO; | 1336 | return -ENXIO; |
1327 | 1337 | ||
1328 | lock_kernel(); | ||
1329 | |||
1330 | switch (cmd) { | 1338 | switch (cmd) { |
1331 | case RCKP_GET_STRUCT: | 1339 | case RCKP_GET_STRUCT: |
1332 | if (copy_to_user(argp, info, sizeof (struct r_port))) | 1340 | if (copy_to_user(argp, info, sizeof (struct r_port))) |
@@ -1350,7 +1358,6 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file, | |||
1350 | default: | 1358 | default: |
1351 | ret = -ENOIOCTLCMD; | 1359 | ret = -ENOIOCTLCMD; |
1352 | } | 1360 | } |
1353 | unlock_kernel(); | ||
1354 | return ret; | 1361 | return ret; |
1355 | } | 1362 | } |
1356 | 1363 | ||
@@ -1471,7 +1478,6 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1471 | jiffies); | 1478 | jiffies); |
1472 | printk(KERN_INFO "cps=%d...\n", info->cps); | 1479 | printk(KERN_INFO "cps=%d...\n", info->cps); |
1473 | #endif | 1480 | #endif |
1474 | lock_kernel(); | ||
1475 | while (1) { | 1481 | while (1) { |
1476 | txcnt = sGetTxCnt(cp); | 1482 | txcnt = sGetTxCnt(cp); |
1477 | if (!txcnt) { | 1483 | if (!txcnt) { |
@@ -1499,7 +1505,6 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1499 | break; | 1505 | break; |
1500 | } | 1506 | } |
1501 | __set_current_state(TASK_RUNNING); | 1507 | __set_current_state(TASK_RUNNING); |
1502 | unlock_kernel(); | ||
1503 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT | 1508 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT |
1504 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); | 1509 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); |
1505 | #endif | 1510 | #endif |
@@ -1512,6 +1517,7 @@ static void rp_hangup(struct tty_struct *tty) | |||
1512 | { | 1517 | { |
1513 | CHANNEL_t *cp; | 1518 | CHANNEL_t *cp; |
1514 | struct r_port *info = tty->driver_data; | 1519 | struct r_port *info = tty->driver_data; |
1520 | unsigned long flags; | ||
1515 | 1521 | ||
1516 | if (rocket_paranoia_check(info, "rp_hangup")) | 1522 | if (rocket_paranoia_check(info, "rp_hangup")) |
1517 | return; | 1523 | return; |
@@ -1520,11 +1526,15 @@ static void rp_hangup(struct tty_struct *tty) | |||
1520 | printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line); | 1526 | printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line); |
1521 | #endif | 1527 | #endif |
1522 | rp_flush_buffer(tty); | 1528 | rp_flush_buffer(tty); |
1523 | if (info->port.flags & ASYNC_CLOSING) | 1529 | spin_lock_irqsave(&info->port.lock, flags); |
1530 | if (info->port.flags & ASYNC_CLOSING) { | ||
1531 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
1524 | return; | 1532 | return; |
1533 | } | ||
1525 | if (info->port.count) | 1534 | if (info->port.count) |
1526 | atomic_dec(&rp_num_ports_open); | 1535 | atomic_dec(&rp_num_ports_open); |
1527 | clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); | 1536 | clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); |
1537 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
1528 | 1538 | ||
1529 | tty_port_hangup(&info->port); | 1539 | tty_port_hangup(&info->port); |
1530 | 1540 | ||
@@ -1535,7 +1545,7 @@ static void rp_hangup(struct tty_struct *tty) | |||
1535 | sDisCTSFlowCtl(cp); | 1545 | sDisCTSFlowCtl(cp); |
1536 | sDisTxSoftFlowCtl(cp); | 1546 | sDisTxSoftFlowCtl(cp); |
1537 | sClrTxXOFF(cp); | 1547 | sClrTxXOFF(cp); |
1538 | info->port.flags &= ~ASYNC_INITIALIZED; | 1548 | clear_bit(ASYNCB_INITIALIZED, &info->port.flags); |
1539 | 1549 | ||
1540 | wake_up_interruptible(&info->port.open_wait); | 1550 | wake_up_interruptible(&info->port.open_wait); |
1541 | } | 1551 | } |
diff --git a/drivers/char/selection.c b/drivers/char/selection.c index f97b9e848064..ebae344ce910 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/selection.h> | 26 | #include <linux/selection.h> |
27 | #include <linux/tiocl.h> | 27 | #include <linux/tiocl.h> |
28 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/smp_lock.h> | ||
29 | 30 | ||
30 | /* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */ | 31 | /* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */ |
31 | #define isspace(c) ((c) == ' ') | 32 | #define isspace(c) ((c) == ' ') |
@@ -312,12 +313,20 @@ int paste_selection(struct tty_struct *tty) | |||
312 | struct tty_ldisc *ld; | 313 | struct tty_ldisc *ld; |
313 | DECLARE_WAITQUEUE(wait, current); | 314 | DECLARE_WAITQUEUE(wait, current); |
314 | 315 | ||
316 | /* always called with BTM from vt_ioctl */ | ||
317 | WARN_ON(!tty_locked()); | ||
318 | |||
315 | acquire_console_sem(); | 319 | acquire_console_sem(); |
316 | poke_blanked_console(); | 320 | poke_blanked_console(); |
317 | release_console_sem(); | 321 | release_console_sem(); |
318 | 322 | ||
319 | ld = tty_ldisc_ref_wait(tty); | 323 | ld = tty_ldisc_ref(tty); |
320 | 324 | if (!ld) { | |
325 | tty_unlock(); | ||
326 | ld = tty_ldisc_ref_wait(tty); | ||
327 | tty_lock(); | ||
328 | } | ||
329 | |||
321 | add_wait_queue(&vc->paste_wait, &wait); | 330 | add_wait_queue(&vc->paste_wait, &wait); |
322 | while (sel_buffer && sel_buffer_lth > pasted) { | 331 | while (sel_buffer && sel_buffer_lth > pasted) { |
323 | set_current_state(TASK_INTERRUPTIBLE); | 332 | set_current_state(TASK_INTERRUPTIBLE); |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index ecbe479c7d68..f646725bd567 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1505,7 +1505,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1505 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ | 1505 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ |
1506 | #endif | 1506 | #endif |
1507 | 1507 | ||
1508 | lock_kernel(); | 1508 | tty_lock(); |
1509 | 1509 | ||
1510 | switch (cmd) { | 1510 | switch (cmd) { |
1511 | case CYGETMON: | 1511 | case CYGETMON: |
@@ -1561,7 +1561,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1561 | default: | 1561 | default: |
1562 | ret_val = -ENOIOCTLCMD; | 1562 | ret_val = -ENOIOCTLCMD; |
1563 | } | 1563 | } |
1564 | unlock_kernel(); | 1564 | tty_unlock(); |
1565 | 1565 | ||
1566 | #ifdef SERIAL_DEBUG_OTHER | 1566 | #ifdef SERIAL_DEBUG_OTHER |
1567 | printk("cy_ioctl done\n"); | 1567 | printk("cy_ioctl done\n"); |
@@ -1786,7 +1786,9 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
1786 | tty->name, info->count); | 1786 | tty->name, info->count); |
1787 | /**/ | 1787 | /**/ |
1788 | #endif | 1788 | #endif |
1789 | schedule(); | 1789 | tty_unlock(); |
1790 | schedule(); | ||
1791 | tty_lock(); | ||
1790 | } | 1792 | } |
1791 | __set_current_state(TASK_RUNNING); | 1793 | __set_current_state(TASK_RUNNING); |
1792 | remove_wait_queue(&info->open_wait, &wait); | 1794 | remove_wait_queue(&info->open_wait, &wait); |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 2c24fcdc722a..9f8495b4fc8f 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -1365,7 +1365,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
1365 | retval = -ERESTARTSYS; | 1365 | retval = -ERESTARTSYS; |
1366 | break; | 1366 | break; |
1367 | } | 1367 | } |
1368 | tty_unlock(); | ||
1368 | schedule(); | 1369 | schedule(); |
1370 | tty_lock(); | ||
1369 | } | 1371 | } |
1370 | 1372 | ||
1371 | set_current_state(TASK_RUNNING); | 1373 | set_current_state(TASK_RUNNING); |
@@ -1863,8 +1865,7 @@ static int sx_set_serial_info(struct specialix_port *port, | |||
1863 | return -EFAULT; | 1865 | return -EFAULT; |
1864 | } | 1866 | } |
1865 | 1867 | ||
1866 | lock_kernel(); | 1868 | mutex_lock(&port->port.mutex); |
1867 | |||
1868 | change_speed = ((port->port.flags & ASYNC_SPD_MASK) != | 1869 | change_speed = ((port->port.flags & ASYNC_SPD_MASK) != |
1869 | (tmp.flags & ASYNC_SPD_MASK)); | 1870 | (tmp.flags & ASYNC_SPD_MASK)); |
1870 | change_speed |= (tmp.custom_divisor != port->custom_divisor); | 1871 | change_speed |= (tmp.custom_divisor != port->custom_divisor); |
@@ -1875,7 +1876,7 @@ static int sx_set_serial_info(struct specialix_port *port, | |||
1875 | ((tmp.flags & ~ASYNC_USR_MASK) != | 1876 | ((tmp.flags & ~ASYNC_USR_MASK) != |
1876 | (port->port.flags & ~ASYNC_USR_MASK))) { | 1877 | (port->port.flags & ~ASYNC_USR_MASK))) { |
1877 | func_exit(); | 1878 | func_exit(); |
1878 | unlock_kernel(); | 1879 | mutex_unlock(&port->port.mutex); |
1879 | return -EPERM; | 1880 | return -EPERM; |
1880 | } | 1881 | } |
1881 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | | 1882 | port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | |
@@ -1892,7 +1893,7 @@ static int sx_set_serial_info(struct specialix_port *port, | |||
1892 | sx_change_speed(bp, port); | 1893 | sx_change_speed(bp, port); |
1893 | 1894 | ||
1894 | func_exit(); | 1895 | func_exit(); |
1895 | unlock_kernel(); | 1896 | mutex_unlock(&port->port.mutex); |
1896 | return 0; | 1897 | return 0; |
1897 | } | 1898 | } |
1898 | 1899 | ||
@@ -1906,7 +1907,7 @@ static int sx_get_serial_info(struct specialix_port *port, | |||
1906 | func_enter(); | 1907 | func_enter(); |
1907 | 1908 | ||
1908 | memset(&tmp, 0, sizeof(tmp)); | 1909 | memset(&tmp, 0, sizeof(tmp)); |
1909 | lock_kernel(); | 1910 | mutex_lock(&port->port.mutex); |
1910 | tmp.type = PORT_CIRRUS; | 1911 | tmp.type = PORT_CIRRUS; |
1911 | tmp.line = port - sx_port; | 1912 | tmp.line = port - sx_port; |
1912 | tmp.port = bp->base; | 1913 | tmp.port = bp->base; |
@@ -1917,7 +1918,7 @@ static int sx_get_serial_info(struct specialix_port *port, | |||
1917 | tmp.closing_wait = port->port.closing_wait * HZ/100; | 1918 | tmp.closing_wait = port->port.closing_wait * HZ/100; |
1918 | tmp.custom_divisor = port->custom_divisor; | 1919 | tmp.custom_divisor = port->custom_divisor; |
1919 | tmp.xmit_fifo_size = CD186x_NFIFO; | 1920 | tmp.xmit_fifo_size = CD186x_NFIFO; |
1920 | unlock_kernel(); | 1921 | mutex_unlock(&port->port.mutex); |
1921 | if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { | 1922 | if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { |
1922 | func_exit(); | 1923 | func_exit(); |
1923 | return -EFAULT; | 1924 | return -EFAULT; |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 6049fd731924..f2167f8e5aab 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -807,7 +807,6 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
807 | timeout = HZ; | 807 | timeout = HZ; |
808 | tend = jiffies + timeout; | 808 | tend = jiffies + timeout; |
809 | 809 | ||
810 | lock_kernel(); | ||
811 | while (stl_datastate(portp)) { | 810 | while (stl_datastate(portp)) { |
812 | if (signal_pending(current)) | 811 | if (signal_pending(current)) |
813 | break; | 812 | break; |
@@ -815,7 +814,6 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
815 | if (time_after_eq(jiffies, tend)) | 814 | if (time_after_eq(jiffies, tend)) |
816 | break; | 815 | break; |
817 | } | 816 | } |
818 | unlock_kernel(); | ||
819 | } | 817 | } |
820 | 818 | ||
821 | /*****************************************************************************/ | 819 | /*****************************************************************************/ |
@@ -1029,6 +1027,8 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) | |||
1029 | pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); | 1027 | pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); |
1030 | 1028 | ||
1031 | memset(&sio, 0, sizeof(struct serial_struct)); | 1029 | memset(&sio, 0, sizeof(struct serial_struct)); |
1030 | |||
1031 | mutex_lock(&portp->port.mutex); | ||
1032 | sio.line = portp->portnr; | 1032 | sio.line = portp->portnr; |
1033 | sio.port = portp->ioaddr; | 1033 | sio.port = portp->ioaddr; |
1034 | sio.flags = portp->port.flags; | 1034 | sio.flags = portp->port.flags; |
@@ -1048,6 +1048,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) | |||
1048 | brdp = stl_brds[portp->brdnr]; | 1048 | brdp = stl_brds[portp->brdnr]; |
1049 | if (brdp != NULL) | 1049 | if (brdp != NULL) |
1050 | sio.irq = brdp->irq; | 1050 | sio.irq = brdp->irq; |
1051 | mutex_unlock(&portp->port.mutex); | ||
1051 | 1052 | ||
1052 | return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; | 1053 | return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; |
1053 | } | 1054 | } |
@@ -1069,12 +1070,15 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp | |||
1069 | 1070 | ||
1070 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) | 1071 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) |
1071 | return -EFAULT; | 1072 | return -EFAULT; |
1073 | mutex_lock(&portp->port.mutex); | ||
1072 | if (!capable(CAP_SYS_ADMIN)) { | 1074 | if (!capable(CAP_SYS_ADMIN)) { |
1073 | if ((sio.baud_base != portp->baud_base) || | 1075 | if ((sio.baud_base != portp->baud_base) || |
1074 | (sio.close_delay != portp->close_delay) || | 1076 | (sio.close_delay != portp->close_delay) || |
1075 | ((sio.flags & ~ASYNC_USR_MASK) != | 1077 | ((sio.flags & ~ASYNC_USR_MASK) != |
1076 | (portp->port.flags & ~ASYNC_USR_MASK))) | 1078 | (portp->port.flags & ~ASYNC_USR_MASK))) { |
1079 | mutex_unlock(&portp->port.mutex); | ||
1077 | return -EPERM; | 1080 | return -EPERM; |
1081 | } | ||
1078 | } | 1082 | } |
1079 | 1083 | ||
1080 | portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | | 1084 | portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | |
@@ -1083,6 +1087,7 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp | |||
1083 | portp->close_delay = sio.close_delay; | 1087 | portp->close_delay = sio.close_delay; |
1084 | portp->closing_wait = sio.closing_wait; | 1088 | portp->closing_wait = sio.closing_wait; |
1085 | portp->custom_divisor = sio.custom_divisor; | 1089 | portp->custom_divisor = sio.custom_divisor; |
1090 | mutex_unlock(&portp->port.mutex); | ||
1086 | stl_setport(portp, tty->termios); | 1091 | stl_setport(portp, tty->termios); |
1087 | return 0; | 1092 | return 0; |
1088 | } | 1093 | } |
@@ -1147,8 +1152,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1147 | 1152 | ||
1148 | rc = 0; | 1153 | rc = 0; |
1149 | 1154 | ||
1150 | lock_kernel(); | ||
1151 | |||
1152 | switch (cmd) { | 1155 | switch (cmd) { |
1153 | case TIOCGSERIAL: | 1156 | case TIOCGSERIAL: |
1154 | rc = stl_getserial(portp, argp); | 1157 | rc = stl_getserial(portp, argp); |
@@ -1173,7 +1176,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1173 | rc = -ENOIOCTLCMD; | 1176 | rc = -ENOIOCTLCMD; |
1174 | break; | 1177 | break; |
1175 | } | 1178 | } |
1176 | unlock_kernel(); | ||
1177 | return rc; | 1179 | return rc; |
1178 | } | 1180 | } |
1179 | 1181 | ||
@@ -2327,6 +2329,7 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst | |||
2327 | return -ENODEV; | 2329 | return -ENODEV; |
2328 | } | 2330 | } |
2329 | 2331 | ||
2332 | mutex_lock(&portp->port.mutex); | ||
2330 | portp->stats.state = portp->istate; | 2333 | portp->stats.state = portp->istate; |
2331 | portp->stats.flags = portp->port.flags; | 2334 | portp->stats.flags = portp->port.flags; |
2332 | portp->stats.hwid = portp->hwid; | 2335 | portp->stats.hwid = portp->hwid; |
@@ -2358,6 +2361,7 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst | |||
2358 | (STL_TXBUFSIZE - (tail - head)); | 2361 | (STL_TXBUFSIZE - (tail - head)); |
2359 | 2362 | ||
2360 | portp->stats.signals = (unsigned long) stl_getsignals(portp); | 2363 | portp->stats.signals = (unsigned long) stl_getsignals(portp); |
2364 | mutex_unlock(&portp->port.mutex); | ||
2361 | 2365 | ||
2362 | return copy_to_user(cp, &portp->stats, | 2366 | return copy_to_user(cp, &portp->stats, |
2363 | sizeof(comstats_t)) ? -EFAULT : 0; | 2367 | sizeof(comstats_t)) ? -EFAULT : 0; |
@@ -2382,10 +2386,12 @@ static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) | |||
2382 | return -ENODEV; | 2386 | return -ENODEV; |
2383 | } | 2387 | } |
2384 | 2388 | ||
2389 | mutex_lock(&portp->port.mutex); | ||
2385 | memset(&portp->stats, 0, sizeof(comstats_t)); | 2390 | memset(&portp->stats, 0, sizeof(comstats_t)); |
2386 | portp->stats.brd = portp->brdnr; | 2391 | portp->stats.brd = portp->brdnr; |
2387 | portp->stats.panel = portp->panelnr; | 2392 | portp->stats.panel = portp->panelnr; |
2388 | portp->stats.port = portp->portnr; | 2393 | portp->stats.port = portp->portnr; |
2394 | mutex_unlock(&portp->port.mutex); | ||
2389 | return copy_to_user(cp, &portp->stats, | 2395 | return copy_to_user(cp, &portp->stats, |
2390 | sizeof(comstats_t)) ? -EFAULT : 0; | 2396 | sizeof(comstats_t)) ? -EFAULT : 0; |
2391 | } | 2397 | } |
@@ -2451,7 +2457,6 @@ static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
2451 | return -ENODEV; | 2457 | return -ENODEV; |
2452 | rc = 0; | 2458 | rc = 0; |
2453 | 2459 | ||
2454 | lock_kernel(); | ||
2455 | switch (cmd) { | 2460 | switch (cmd) { |
2456 | case COM_GETPORTSTATS: | 2461 | case COM_GETPORTSTATS: |
2457 | rc = stl_getportstats(NULL, NULL, argp); | 2462 | rc = stl_getportstats(NULL, NULL, argp); |
@@ -2472,7 +2477,6 @@ static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
2472 | rc = -ENOIOCTLCMD; | 2477 | rc = -ENOIOCTLCMD; |
2473 | break; | 2478 | break; |
2474 | } | 2479 | } |
2475 | unlock_kernel(); | ||
2476 | return rc; | 2480 | return rc; |
2477 | } | 2481 | } |
2478 | 2482 | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index a81ec4fcf6ff..5b24db4ff7f1 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -1699,7 +1699,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
1699 | if (!capable(CAP_SYS_RAWIO)) | 1699 | if (!capable(CAP_SYS_RAWIO)) |
1700 | return -EPERM; | 1700 | return -EPERM; |
1701 | 1701 | ||
1702 | lock_kernel(); | 1702 | tty_lock(); |
1703 | 1703 | ||
1704 | sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); | 1704 | sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); |
1705 | 1705 | ||
@@ -1848,7 +1848,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
1848 | break; | 1848 | break; |
1849 | } | 1849 | } |
1850 | out: | 1850 | out: |
1851 | unlock_kernel(); | 1851 | tty_unlock(); |
1852 | func_exit(); | 1852 | func_exit(); |
1853 | return rc; | 1853 | return rc; |
1854 | } | 1854 | } |
@@ -1859,7 +1859,7 @@ static int sx_break(struct tty_struct *tty, int flag) | |||
1859 | int rv; | 1859 | int rv; |
1860 | 1860 | ||
1861 | func_enter(); | 1861 | func_enter(); |
1862 | lock_kernel(); | 1862 | tty_lock(); |
1863 | 1863 | ||
1864 | if (flag) | 1864 | if (flag) |
1865 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); | 1865 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); |
@@ -1868,7 +1868,7 @@ static int sx_break(struct tty_struct *tty, int flag) | |||
1868 | if (rv != 1) | 1868 | if (rv != 1) |
1869 | printk(KERN_ERR "sx: couldn't send break (%x).\n", | 1869 | printk(KERN_ERR "sx: couldn't send break (%x).\n", |
1870 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); | 1870 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); |
1871 | unlock_kernel(); | 1871 | tty_unlock(); |
1872 | func_exit(); | 1872 | func_exit(); |
1873 | return 0; | 1873 | return 0; |
1874 | } | 1874 | } |
@@ -1909,7 +1909,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, | |||
1909 | /* func_enter2(); */ | 1909 | /* func_enter2(); */ |
1910 | 1910 | ||
1911 | rc = 0; | 1911 | rc = 0; |
1912 | lock_kernel(); | 1912 | tty_lock(); |
1913 | switch (cmd) { | 1913 | switch (cmd) { |
1914 | case TIOCGSERIAL: | 1914 | case TIOCGSERIAL: |
1915 | rc = gs_getserial(&port->gs, argp); | 1915 | rc = gs_getserial(&port->gs, argp); |
@@ -1921,7 +1921,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, | |||
1921 | rc = -ENOIOCTLCMD; | 1921 | rc = -ENOIOCTLCMD; |
1922 | break; | 1922 | break; |
1923 | } | 1923 | } |
1924 | unlock_kernel(); | 1924 | tty_unlock(); |
1925 | 1925 | ||
1926 | /* func_exit(); */ | 1926 | /* func_exit(); */ |
1927 | return rc; | 1927 | return rc; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 0658fc548222..a2a58004e188 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -81,7 +81,6 @@ | |||
81 | #include <linux/mm.h> | 81 | #include <linux/mm.h> |
82 | #include <linux/seq_file.h> | 82 | #include <linux/seq_file.h> |
83 | #include <linux/slab.h> | 83 | #include <linux/slab.h> |
84 | #include <linux/smp_lock.h> | ||
85 | #include <linux/delay.h> | 84 | #include <linux/delay.h> |
86 | #include <linux/netdevice.h> | 85 | #include <linux/netdevice.h> |
87 | #include <linux/vmalloc.h> | 86 | #include <linux/vmalloc.h> |
@@ -2436,7 +2435,9 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user * | |||
2436 | if (!user_icount) { | 2435 | if (!user_icount) { |
2437 | memset(&info->icount, 0, sizeof(info->icount)); | 2436 | memset(&info->icount, 0, sizeof(info->icount)); |
2438 | } else { | 2437 | } else { |
2438 | mutex_lock(&info->port.mutex); | ||
2439 | COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); | 2439 | COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); |
2440 | mutex_unlock(&info->port.mutex); | ||
2440 | if (err) | 2441 | if (err) |
2441 | return -EFAULT; | 2442 | return -EFAULT; |
2442 | } | 2443 | } |
@@ -2461,7 +2462,9 @@ static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_p | |||
2461 | printk("%s(%d):mgsl_get_params(%s)\n", | 2462 | printk("%s(%d):mgsl_get_params(%s)\n", |
2462 | __FILE__,__LINE__, info->device_name); | 2463 | __FILE__,__LINE__, info->device_name); |
2463 | 2464 | ||
2465 | mutex_lock(&info->port.mutex); | ||
2464 | COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); | 2466 | COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); |
2467 | mutex_unlock(&info->port.mutex); | ||
2465 | if (err) { | 2468 | if (err) { |
2466 | if ( debug_level >= DEBUG_LEVEL_INFO ) | 2469 | if ( debug_level >= DEBUG_LEVEL_INFO ) |
2467 | printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n", | 2470 | printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n", |
@@ -2501,11 +2504,13 @@ static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_pa | |||
2501 | return -EFAULT; | 2504 | return -EFAULT; |
2502 | } | 2505 | } |
2503 | 2506 | ||
2507 | mutex_lock(&info->port.mutex); | ||
2504 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2508 | spin_lock_irqsave(&info->irq_spinlock,flags); |
2505 | memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); | 2509 | memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); |
2506 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 2510 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
2507 | 2511 | ||
2508 | mgsl_change_params(info); | 2512 | mgsl_change_params(info); |
2513 | mutex_unlock(&info->port.mutex); | ||
2509 | 2514 | ||
2510 | return 0; | 2515 | return 0; |
2511 | 2516 | ||
@@ -2935,7 +2940,6 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, | |||
2935 | unsigned int cmd, unsigned long arg) | 2940 | unsigned int cmd, unsigned long arg) |
2936 | { | 2941 | { |
2937 | struct mgsl_struct * info = tty->driver_data; | 2942 | struct mgsl_struct * info = tty->driver_data; |
2938 | int ret; | ||
2939 | 2943 | ||
2940 | if (debug_level >= DEBUG_LEVEL_INFO) | 2944 | if (debug_level >= DEBUG_LEVEL_INFO) |
2941 | printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, | 2945 | printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, |
@@ -2950,10 +2954,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, | |||
2950 | return -EIO; | 2954 | return -EIO; |
2951 | } | 2955 | } |
2952 | 2956 | ||
2953 | lock_kernel(); | 2957 | return mgsl_ioctl_common(info, cmd, arg); |
2954 | ret = mgsl_ioctl_common(info, cmd, arg); | ||
2955 | unlock_kernel(); | ||
2956 | return ret; | ||
2957 | } | 2958 | } |
2958 | 2959 | ||
2959 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) | 2960 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) |
@@ -3109,12 +3110,14 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp) | |||
3109 | 3110 | ||
3110 | if (tty_port_close_start(&info->port, tty, filp) == 0) | 3111 | if (tty_port_close_start(&info->port, tty, filp) == 0) |
3111 | goto cleanup; | 3112 | goto cleanup; |
3112 | 3113 | ||
3114 | mutex_lock(&info->port.mutex); | ||
3113 | if (info->port.flags & ASYNC_INITIALIZED) | 3115 | if (info->port.flags & ASYNC_INITIALIZED) |
3114 | mgsl_wait_until_sent(tty, info->timeout); | 3116 | mgsl_wait_until_sent(tty, info->timeout); |
3115 | mgsl_flush_buffer(tty); | 3117 | mgsl_flush_buffer(tty); |
3116 | tty_ldisc_flush(tty); | 3118 | tty_ldisc_flush(tty); |
3117 | shutdown(info); | 3119 | shutdown(info); |
3120 | mutex_unlock(&info->port.mutex); | ||
3118 | 3121 | ||
3119 | tty_port_close_end(&info->port, tty); | 3122 | tty_port_close_end(&info->port, tty); |
3120 | info->port.tty = NULL; | 3123 | info->port.tty = NULL; |
@@ -3162,7 +3165,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3162 | * Note: use tight timings here to satisfy the NIST-PCTS. | 3165 | * Note: use tight timings here to satisfy the NIST-PCTS. |
3163 | */ | 3166 | */ |
3164 | 3167 | ||
3165 | lock_kernel(); | ||
3166 | if ( info->params.data_rate ) { | 3168 | if ( info->params.data_rate ) { |
3167 | char_time = info->timeout/(32 * 5); | 3169 | char_time = info->timeout/(32 * 5); |
3168 | if (!char_time) | 3170 | if (!char_time) |
@@ -3192,7 +3194,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3192 | break; | 3194 | break; |
3193 | } | 3195 | } |
3194 | } | 3196 | } |
3195 | unlock_kernel(); | ||
3196 | 3197 | ||
3197 | exit: | 3198 | exit: |
3198 | if (debug_level >= DEBUG_LEVEL_INFO) | 3199 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -3348,7 +3349,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3348 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", | 3349 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", |
3349 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3350 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3350 | 3351 | ||
3352 | tty_unlock(); | ||
3351 | schedule(); | 3353 | schedule(); |
3354 | tty_lock(); | ||
3352 | } | 3355 | } |
3353 | 3356 | ||
3354 | set_current_state(TASK_RUNNING); | 3357 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 334cf5c8c8b6..fef80cfcab5c 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -40,8 +40,8 @@ | |||
40 | #define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt | 40 | #define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt |
41 | #define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt | 41 | #define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt |
42 | #define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) | 42 | #define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) |
43 | //#define DBGTBUF(info) dump_tbufs(info) | 43 | /*#define DBGTBUF(info) dump_tbufs(info)*/ |
44 | //#define DBGRBUF(info) dump_rbufs(info) | 44 | /*#define DBGRBUF(info) dump_rbufs(info)*/ |
45 | 45 | ||
46 | 46 | ||
47 | #include <linux/module.h> | 47 | #include <linux/module.h> |
@@ -62,7 +62,6 @@ | |||
62 | #include <linux/mm.h> | 62 | #include <linux/mm.h> |
63 | #include <linux/seq_file.h> | 63 | #include <linux/seq_file.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
66 | #include <linux/netdevice.h> | 65 | #include <linux/netdevice.h> |
67 | #include <linux/vmalloc.h> | 66 | #include <linux/vmalloc.h> |
68 | #include <linux/init.h> | 67 | #include <linux/init.h> |
@@ -676,12 +675,14 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
676 | goto cleanup; | 675 | goto cleanup; |
677 | } | 676 | } |
678 | 677 | ||
678 | mutex_lock(&info->port.mutex); | ||
679 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 679 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
680 | 680 | ||
681 | spin_lock_irqsave(&info->netlock, flags); | 681 | spin_lock_irqsave(&info->netlock, flags); |
682 | if (info->netcount) { | 682 | if (info->netcount) { |
683 | retval = -EBUSY; | 683 | retval = -EBUSY; |
684 | spin_unlock_irqrestore(&info->netlock, flags); | 684 | spin_unlock_irqrestore(&info->netlock, flags); |
685 | mutex_unlock(&info->port.mutex); | ||
685 | goto cleanup; | 686 | goto cleanup; |
686 | } | 687 | } |
687 | info->port.count++; | 688 | info->port.count++; |
@@ -693,7 +694,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
693 | if (retval < 0) | 694 | if (retval < 0) |
694 | goto cleanup; | 695 | goto cleanup; |
695 | } | 696 | } |
696 | 697 | mutex_unlock(&info->port.mutex); | |
697 | retval = block_til_ready(tty, filp, info); | 698 | retval = block_til_ready(tty, filp, info); |
698 | if (retval) { | 699 | if (retval) { |
699 | DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); | 700 | DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); |
@@ -725,12 +726,14 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
725 | if (tty_port_close_start(&info->port, tty, filp) == 0) | 726 | if (tty_port_close_start(&info->port, tty, filp) == 0) |
726 | goto cleanup; | 727 | goto cleanup; |
727 | 728 | ||
729 | mutex_lock(&info->port.mutex); | ||
728 | if (info->port.flags & ASYNC_INITIALIZED) | 730 | if (info->port.flags & ASYNC_INITIALIZED) |
729 | wait_until_sent(tty, info->timeout); | 731 | wait_until_sent(tty, info->timeout); |
730 | flush_buffer(tty); | 732 | flush_buffer(tty); |
731 | tty_ldisc_flush(tty); | 733 | tty_ldisc_flush(tty); |
732 | 734 | ||
733 | shutdown(info); | 735 | shutdown(info); |
736 | mutex_unlock(&info->port.mutex); | ||
734 | 737 | ||
735 | tty_port_close_end(&info->port, tty); | 738 | tty_port_close_end(&info->port, tty); |
736 | info->port.tty = NULL; | 739 | info->port.tty = NULL; |
@@ -741,17 +744,23 @@ cleanup: | |||
741 | static void hangup(struct tty_struct *tty) | 744 | static void hangup(struct tty_struct *tty) |
742 | { | 745 | { |
743 | struct slgt_info *info = tty->driver_data; | 746 | struct slgt_info *info = tty->driver_data; |
747 | unsigned long flags; | ||
744 | 748 | ||
745 | if (sanity_check(info, tty->name, "hangup")) | 749 | if (sanity_check(info, tty->name, "hangup")) |
746 | return; | 750 | return; |
747 | DBGINFO(("%s hangup\n", info->device_name)); | 751 | DBGINFO(("%s hangup\n", info->device_name)); |
748 | 752 | ||
749 | flush_buffer(tty); | 753 | flush_buffer(tty); |
754 | |||
755 | mutex_lock(&info->port.mutex); | ||
750 | shutdown(info); | 756 | shutdown(info); |
751 | 757 | ||
758 | spin_lock_irqsave(&info->port.lock, flags); | ||
752 | info->port.count = 0; | 759 | info->port.count = 0; |
753 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 760 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
754 | info->port.tty = NULL; | 761 | info->port.tty = NULL; |
762 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
763 | mutex_unlock(&info->port.mutex); | ||
755 | 764 | ||
756 | wake_up_interruptible(&info->port.open_wait); | 765 | wake_up_interruptible(&info->port.open_wait); |
757 | } | 766 | } |
@@ -901,8 +910,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
901 | * Note: use tight timings here to satisfy the NIST-PCTS. | 910 | * Note: use tight timings here to satisfy the NIST-PCTS. |
902 | */ | 911 | */ |
903 | 912 | ||
904 | lock_kernel(); | ||
905 | |||
906 | if (info->params.data_rate) { | 913 | if (info->params.data_rate) { |
907 | char_time = info->timeout/(32 * 5); | 914 | char_time = info->timeout/(32 * 5); |
908 | if (!char_time) | 915 | if (!char_time) |
@@ -920,8 +927,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
920 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 927 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
921 | break; | 928 | break; |
922 | } | 929 | } |
923 | unlock_kernel(); | ||
924 | |||
925 | exit: | 930 | exit: |
926 | DBGINFO(("%s wait_until_sent exit\n", info->device_name)); | 931 | DBGINFO(("%s wait_until_sent exit\n", info->device_name)); |
927 | } | 932 | } |
@@ -1041,8 +1046,37 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1041 | return -EIO; | 1046 | return -EIO; |
1042 | } | 1047 | } |
1043 | 1048 | ||
1044 | lock_kernel(); | 1049 | switch (cmd) { |
1045 | 1050 | case MGSL_IOCWAITEVENT: | |
1051 | return wait_mgsl_event(info, argp); | ||
1052 | case TIOCMIWAIT: | ||
1053 | return modem_input_wait(info,(int)arg); | ||
1054 | case TIOCGICOUNT: | ||
1055 | spin_lock_irqsave(&info->lock,flags); | ||
1056 | cnow = info->icount; | ||
1057 | spin_unlock_irqrestore(&info->lock,flags); | ||
1058 | p_cuser = argp; | ||
1059 | if (put_user(cnow.cts, &p_cuser->cts) || | ||
1060 | put_user(cnow.dsr, &p_cuser->dsr) || | ||
1061 | put_user(cnow.rng, &p_cuser->rng) || | ||
1062 | put_user(cnow.dcd, &p_cuser->dcd) || | ||
1063 | put_user(cnow.rx, &p_cuser->rx) || | ||
1064 | put_user(cnow.tx, &p_cuser->tx) || | ||
1065 | put_user(cnow.frame, &p_cuser->frame) || | ||
1066 | put_user(cnow.overrun, &p_cuser->overrun) || | ||
1067 | put_user(cnow.parity, &p_cuser->parity) || | ||
1068 | put_user(cnow.brk, &p_cuser->brk) || | ||
1069 | put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | ||
1070 | return -EFAULT; | ||
1071 | return 0; | ||
1072 | case MGSL_IOCSGPIO: | ||
1073 | return set_gpio(info, argp); | ||
1074 | case MGSL_IOCGGPIO: | ||
1075 | return get_gpio(info, argp); | ||
1076 | case MGSL_IOCWAITGPIO: | ||
1077 | return wait_gpio(info, argp); | ||
1078 | } | ||
1079 | mutex_lock(&info->port.mutex); | ||
1046 | switch (cmd) { | 1080 | switch (cmd) { |
1047 | case MGSL_IOCGPARAMS: | 1081 | case MGSL_IOCGPARAMS: |
1048 | ret = get_params(info, argp); | 1082 | ret = get_params(info, argp); |
@@ -1068,50 +1102,16 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1068 | case MGSL_IOCGSTATS: | 1102 | case MGSL_IOCGSTATS: |
1069 | ret = get_stats(info, argp); | 1103 | ret = get_stats(info, argp); |
1070 | break; | 1104 | break; |
1071 | case MGSL_IOCWAITEVENT: | ||
1072 | ret = wait_mgsl_event(info, argp); | ||
1073 | break; | ||
1074 | case TIOCMIWAIT: | ||
1075 | ret = modem_input_wait(info,(int)arg); | ||
1076 | break; | ||
1077 | case MGSL_IOCGIF: | 1105 | case MGSL_IOCGIF: |
1078 | ret = get_interface(info, argp); | 1106 | ret = get_interface(info, argp); |
1079 | break; | 1107 | break; |
1080 | case MGSL_IOCSIF: | 1108 | case MGSL_IOCSIF: |
1081 | ret = set_interface(info,(int)arg); | 1109 | ret = set_interface(info,(int)arg); |
1082 | break; | 1110 | break; |
1083 | case MGSL_IOCSGPIO: | ||
1084 | ret = set_gpio(info, argp); | ||
1085 | break; | ||
1086 | case MGSL_IOCGGPIO: | ||
1087 | ret = get_gpio(info, argp); | ||
1088 | break; | ||
1089 | case MGSL_IOCWAITGPIO: | ||
1090 | ret = wait_gpio(info, argp); | ||
1091 | break; | ||
1092 | case TIOCGICOUNT: | ||
1093 | spin_lock_irqsave(&info->lock,flags); | ||
1094 | cnow = info->icount; | ||
1095 | spin_unlock_irqrestore(&info->lock,flags); | ||
1096 | p_cuser = argp; | ||
1097 | if (put_user(cnow.cts, &p_cuser->cts) || | ||
1098 | put_user(cnow.dsr, &p_cuser->dsr) || | ||
1099 | put_user(cnow.rng, &p_cuser->rng) || | ||
1100 | put_user(cnow.dcd, &p_cuser->dcd) || | ||
1101 | put_user(cnow.rx, &p_cuser->rx) || | ||
1102 | put_user(cnow.tx, &p_cuser->tx) || | ||
1103 | put_user(cnow.frame, &p_cuser->frame) || | ||
1104 | put_user(cnow.overrun, &p_cuser->overrun) || | ||
1105 | put_user(cnow.parity, &p_cuser->parity) || | ||
1106 | put_user(cnow.brk, &p_cuser->brk) || | ||
1107 | put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | ||
1108 | ret = -EFAULT; | ||
1109 | ret = 0; | ||
1110 | break; | ||
1111 | default: | 1111 | default: |
1112 | ret = -ENOIOCTLCMD; | 1112 | ret = -ENOIOCTLCMD; |
1113 | } | 1113 | } |
1114 | unlock_kernel(); | 1114 | mutex_unlock(&info->port.mutex); |
1115 | return ret; | 1115 | return ret; |
1116 | } | 1116 | } |
1117 | 1117 | ||
@@ -3244,7 +3244,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3244 | } | 3244 | } |
3245 | 3245 | ||
3246 | DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); | 3246 | DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); |
3247 | tty_unlock(); | ||
3247 | schedule(); | 3248 | schedule(); |
3249 | tty_lock(); | ||
3248 | } | 3250 | } |
3249 | 3251 | ||
3250 | set_current_state(TASK_RUNNING); | 3252 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 2b18adc4ee19..e56caf7d82aa 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/mm.h> | 52 | #include <linux/mm.h> |
53 | #include <linux/seq_file.h> | 53 | #include <linux/seq_file.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/smp_lock.h> | ||
56 | #include <linux/netdevice.h> | 55 | #include <linux/netdevice.h> |
57 | #include <linux/vmalloc.h> | 56 | #include <linux/vmalloc.h> |
58 | #include <linux/init.h> | 57 | #include <linux/init.h> |
@@ -813,13 +812,15 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
813 | 812 | ||
814 | if (tty_port_close_start(&info->port, tty, filp) == 0) | 813 | if (tty_port_close_start(&info->port, tty, filp) == 0) |
815 | goto cleanup; | 814 | goto cleanup; |
816 | 815 | ||
816 | mutex_lock(&info->port.mutex); | ||
817 | if (info->port.flags & ASYNC_INITIALIZED) | 817 | if (info->port.flags & ASYNC_INITIALIZED) |
818 | wait_until_sent(tty, info->timeout); | 818 | wait_until_sent(tty, info->timeout); |
819 | 819 | ||
820 | flush_buffer(tty); | 820 | flush_buffer(tty); |
821 | tty_ldisc_flush(tty); | 821 | tty_ldisc_flush(tty); |
822 | shutdown(info); | 822 | shutdown(info); |
823 | mutex_unlock(&info->port.mutex); | ||
823 | 824 | ||
824 | tty_port_close_end(&info->port, tty); | 825 | tty_port_close_end(&info->port, tty); |
825 | info->port.tty = NULL; | 826 | info->port.tty = NULL; |
@@ -835,6 +836,7 @@ cleanup: | |||
835 | static void hangup(struct tty_struct *tty) | 836 | static void hangup(struct tty_struct *tty) |
836 | { | 837 | { |
837 | SLMP_INFO *info = tty->driver_data; | 838 | SLMP_INFO *info = tty->driver_data; |
839 | unsigned long flags; | ||
838 | 840 | ||
839 | if (debug_level >= DEBUG_LEVEL_INFO) | 841 | if (debug_level >= DEBUG_LEVEL_INFO) |
840 | printk("%s(%d):%s hangup()\n", | 842 | printk("%s(%d):%s hangup()\n", |
@@ -843,12 +845,16 @@ static void hangup(struct tty_struct *tty) | |||
843 | if (sanity_check(info, tty->name, "hangup")) | 845 | if (sanity_check(info, tty->name, "hangup")) |
844 | return; | 846 | return; |
845 | 847 | ||
848 | mutex_lock(&info->port.mutex); | ||
846 | flush_buffer(tty); | 849 | flush_buffer(tty); |
847 | shutdown(info); | 850 | shutdown(info); |
848 | 851 | ||
852 | spin_lock_irqsave(&info->port.lock, flags); | ||
849 | info->port.count = 0; | 853 | info->port.count = 0; |
850 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 854 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
851 | info->port.tty = NULL; | 855 | info->port.tty = NULL; |
856 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
857 | mutex_unlock(&info->port.mutex); | ||
852 | 858 | ||
853 | wake_up_interruptible(&info->port.open_wait); | 859 | wake_up_interruptible(&info->port.open_wait); |
854 | } | 860 | } |
@@ -1062,9 +1068,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1062 | if (sanity_check(info, tty->name, "wait_until_sent")) | 1068 | if (sanity_check(info, tty->name, "wait_until_sent")) |
1063 | return; | 1069 | return; |
1064 | 1070 | ||
1065 | lock_kernel(); | 1071 | if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) |
1066 | |||
1067 | if (!(info->port.flags & ASYNC_INITIALIZED)) | ||
1068 | goto exit; | 1072 | goto exit; |
1069 | 1073 | ||
1070 | orig_jiffies = jiffies; | 1074 | orig_jiffies = jiffies; |
@@ -1094,8 +1098,10 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1094 | break; | 1098 | break; |
1095 | } | 1099 | } |
1096 | } else { | 1100 | } else { |
1097 | //TODO: determine if there is something similar to USC16C32 | 1101 | /* |
1098 | // TXSTATUS_ALL_SENT status | 1102 | * TODO: determine if there is something similar to USC16C32 |
1103 | * TXSTATUS_ALL_SENT status | ||
1104 | */ | ||
1099 | while ( info->tx_active && info->tx_enabled) { | 1105 | while ( info->tx_active && info->tx_enabled) { |
1100 | msleep_interruptible(jiffies_to_msecs(char_time)); | 1106 | msleep_interruptible(jiffies_to_msecs(char_time)); |
1101 | if (signal_pending(current)) | 1107 | if (signal_pending(current)) |
@@ -1106,7 +1112,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1106 | } | 1112 | } |
1107 | 1113 | ||
1108 | exit: | 1114 | exit: |
1109 | unlock_kernel(); | ||
1110 | if (debug_level >= DEBUG_LEVEL_INFO) | 1115 | if (debug_level >= DEBUG_LEVEL_INFO) |
1111 | printk("%s(%d):%s wait_until_sent() exit\n", | 1116 | printk("%s(%d):%s wait_until_sent() exit\n", |
1112 | __FILE__,__LINE__, info->device_name ); | 1117 | __FILE__,__LINE__, info->device_name ); |
@@ -1122,7 +1127,6 @@ static int write_room(struct tty_struct *tty) | |||
1122 | if (sanity_check(info, tty->name, "write_room")) | 1127 | if (sanity_check(info, tty->name, "write_room")) |
1123 | return 0; | 1128 | return 0; |
1124 | 1129 | ||
1125 | lock_kernel(); | ||
1126 | if (info->params.mode == MGSL_MODE_HDLC) { | 1130 | if (info->params.mode == MGSL_MODE_HDLC) { |
1127 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; | 1131 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; |
1128 | } else { | 1132 | } else { |
@@ -1130,7 +1134,6 @@ static int write_room(struct tty_struct *tty) | |||
1130 | if (ret < 0) | 1134 | if (ret < 0) |
1131 | ret = 0; | 1135 | ret = 0; |
1132 | } | 1136 | } |
1133 | unlock_kernel(); | ||
1134 | 1137 | ||
1135 | if (debug_level >= DEBUG_LEVEL_INFO) | 1138 | if (debug_level >= DEBUG_LEVEL_INFO) |
1136 | printk("%s(%d):%s write_room()=%d\n", | 1139 | printk("%s(%d):%s write_room()=%d\n", |
@@ -1251,7 +1254,7 @@ static void tx_release(struct tty_struct *tty) | |||
1251 | * | 1254 | * |
1252 | * Return Value: 0 if success, otherwise error code | 1255 | * Return Value: 0 if success, otherwise error code |
1253 | */ | 1256 | */ |
1254 | static int do_ioctl(struct tty_struct *tty, struct file *file, | 1257 | static int ioctl(struct tty_struct *tty, struct file *file, |
1255 | unsigned int cmd, unsigned long arg) | 1258 | unsigned int cmd, unsigned long arg) |
1256 | { | 1259 | { |
1257 | SLMP_INFO *info = tty->driver_data; | 1260 | SLMP_INFO *info = tty->driver_data; |
@@ -1341,16 +1344,6 @@ static int do_ioctl(struct tty_struct *tty, struct file *file, | |||
1341 | return 0; | 1344 | return 0; |
1342 | } | 1345 | } |
1343 | 1346 | ||
1344 | static int ioctl(struct tty_struct *tty, struct file *file, | ||
1345 | unsigned int cmd, unsigned long arg) | ||
1346 | { | ||
1347 | int ret; | ||
1348 | lock_kernel(); | ||
1349 | ret = do_ioctl(tty, file, cmd, arg); | ||
1350 | unlock_kernel(); | ||
1351 | return ret; | ||
1352 | } | ||
1353 | |||
1354 | /* | 1347 | /* |
1355 | * /proc fs routines.... | 1348 | * /proc fs routines.... |
1356 | */ | 1349 | */ |
@@ -2883,7 +2876,9 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) | |||
2883 | if (!user_icount) { | 2876 | if (!user_icount) { |
2884 | memset(&info->icount, 0, sizeof(info->icount)); | 2877 | memset(&info->icount, 0, sizeof(info->icount)); |
2885 | } else { | 2878 | } else { |
2879 | mutex_lock(&info->port.mutex); | ||
2886 | COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); | 2880 | COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); |
2881 | mutex_unlock(&info->port.mutex); | ||
2887 | if (err) | 2882 | if (err) |
2888 | return -EFAULT; | 2883 | return -EFAULT; |
2889 | } | 2884 | } |
@@ -2898,7 +2893,9 @@ static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params) | |||
2898 | printk("%s(%d):%s get_params()\n", | 2893 | printk("%s(%d):%s get_params()\n", |
2899 | __FILE__,__LINE__, info->device_name); | 2894 | __FILE__,__LINE__, info->device_name); |
2900 | 2895 | ||
2896 | mutex_lock(&info->port.mutex); | ||
2901 | COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); | 2897 | COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); |
2898 | mutex_unlock(&info->port.mutex); | ||
2902 | if (err) { | 2899 | if (err) { |
2903 | if ( debug_level >= DEBUG_LEVEL_INFO ) | 2900 | if ( debug_level >= DEBUG_LEVEL_INFO ) |
2904 | printk( "%s(%d):%s get_params() user buffer copy failed\n", | 2901 | printk( "%s(%d):%s get_params() user buffer copy failed\n", |
@@ -2926,11 +2923,13 @@ static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params) | |||
2926 | return -EFAULT; | 2923 | return -EFAULT; |
2927 | } | 2924 | } |
2928 | 2925 | ||
2926 | mutex_lock(&info->port.mutex); | ||
2929 | spin_lock_irqsave(&info->lock,flags); | 2927 | spin_lock_irqsave(&info->lock,flags); |
2930 | memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); | 2928 | memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); |
2931 | spin_unlock_irqrestore(&info->lock,flags); | 2929 | spin_unlock_irqrestore(&info->lock,flags); |
2932 | 2930 | ||
2933 | change_params(info); | 2931 | change_params(info); |
2932 | mutex_unlock(&info->port.mutex); | ||
2934 | 2933 | ||
2935 | return 0; | 2934 | return 0; |
2936 | } | 2935 | } |
@@ -3366,7 +3365,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3366 | printk("%s(%d):%s block_til_ready() count=%d\n", | 3365 | printk("%s(%d):%s block_til_ready() count=%d\n", |
3367 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3366 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3368 | 3367 | ||
3368 | tty_unlock(); | ||
3369 | schedule(); | 3369 | schedule(); |
3370 | tty_lock(); | ||
3370 | } | 3371 | } |
3371 | 3372 | ||
3372 | set_current_state(TASK_RUNNING); | 3373 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 507441ac6edb..0350c42375a2 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -149,6 +149,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
149 | #else | 149 | #else |
150 | #define tty_compat_ioctl NULL | 150 | #define tty_compat_ioctl NULL |
151 | #endif | 151 | #endif |
152 | static int __tty_fasync(int fd, struct file *filp, int on); | ||
152 | static int tty_fasync(int fd, struct file *filp, int on); | 153 | static int tty_fasync(int fd, struct file *filp, int on); |
153 | static void release_tty(struct tty_struct *tty, int idx); | 154 | static void release_tty(struct tty_struct *tty, int idx); |
154 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | 155 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
@@ -470,7 +471,7 @@ void tty_wakeup(struct tty_struct *tty) | |||
470 | EXPORT_SYMBOL_GPL(tty_wakeup); | 471 | EXPORT_SYMBOL_GPL(tty_wakeup); |
471 | 472 | ||
472 | /** | 473 | /** |
473 | * do_tty_hangup - actual handler for hangup events | 474 | * __tty_hangup - actual handler for hangup events |
474 | * @work: tty device | 475 | * @work: tty device |
475 | * | 476 | * |
476 | * This can be called by the "eventd" kernel thread. That is process | 477 | * This can be called by the "eventd" kernel thread. That is process |
@@ -483,7 +484,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
483 | * remains intact. | 484 | * remains intact. |
484 | * | 485 | * |
485 | * Locking: | 486 | * Locking: |
486 | * BKL | 487 | * BTM |
487 | * redirect lock for undoing redirection | 488 | * redirect lock for undoing redirection |
488 | * file list lock for manipulating list of ttys | 489 | * file list lock for manipulating list of ttys |
489 | * tty_ldisc_lock from called functions | 490 | * tty_ldisc_lock from called functions |
@@ -491,10 +492,8 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
491 | * tasklist_lock to walk task list for hangup event | 492 | * tasklist_lock to walk task list for hangup event |
492 | * ->siglock to protect ->signal/->sighand | 493 | * ->siglock to protect ->signal/->sighand |
493 | */ | 494 | */ |
494 | static void do_tty_hangup(struct work_struct *work) | 495 | void __tty_hangup(struct tty_struct *tty) |
495 | { | 496 | { |
496 | struct tty_struct *tty = | ||
497 | container_of(work, struct tty_struct, hangup_work); | ||
498 | struct file *cons_filp = NULL; | 497 | struct file *cons_filp = NULL; |
499 | struct file *filp, *f = NULL; | 498 | struct file *filp, *f = NULL; |
500 | struct task_struct *p; | 499 | struct task_struct *p; |
@@ -513,9 +512,12 @@ static void do_tty_hangup(struct work_struct *work) | |||
513 | } | 512 | } |
514 | spin_unlock(&redirect_lock); | 513 | spin_unlock(&redirect_lock); |
515 | 514 | ||
516 | /* inuse_filps is protected by the single kernel lock */ | 515 | tty_lock(); |
517 | lock_kernel(); | 516 | |
518 | check_tty_count(tty, "do_tty_hangup"); | 517 | /* inuse_filps is protected by the single tty lock, |
518 | this really needs to change if we want to flush the | ||
519 | workqueue with the lock held */ | ||
520 | check_tty_count(tty, "tty_hangup"); | ||
519 | 521 | ||
520 | file_list_lock(); | 522 | file_list_lock(); |
521 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 523 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
@@ -525,7 +527,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
525 | if (filp->f_op->write != tty_write) | 527 | if (filp->f_op->write != tty_write) |
526 | continue; | 528 | continue; |
527 | closecount++; | 529 | closecount++; |
528 | tty_fasync(-1, filp, 0); /* can't block */ | 530 | __tty_fasync(-1, filp, 0); /* can't block */ |
529 | filp->f_op = &hung_up_tty_fops; | 531 | filp->f_op = &hung_up_tty_fops; |
530 | } | 532 | } |
531 | file_list_unlock(); | 533 | file_list_unlock(); |
@@ -594,11 +596,21 @@ static void do_tty_hangup(struct work_struct *work) | |||
594 | */ | 596 | */ |
595 | set_bit(TTY_HUPPED, &tty->flags); | 597 | set_bit(TTY_HUPPED, &tty->flags); |
596 | tty_ldisc_enable(tty); | 598 | tty_ldisc_enable(tty); |
597 | unlock_kernel(); | 599 | |
600 | tty_unlock(); | ||
601 | |||
598 | if (f) | 602 | if (f) |
599 | fput(f); | 603 | fput(f); |
600 | } | 604 | } |
601 | 605 | ||
606 | static void do_tty_hangup(struct work_struct *work) | ||
607 | { | ||
608 | struct tty_struct *tty = | ||
609 | container_of(work, struct tty_struct, hangup_work); | ||
610 | |||
611 | __tty_hangup(tty); | ||
612 | } | ||
613 | |||
602 | /** | 614 | /** |
603 | * tty_hangup - trigger a hangup event | 615 | * tty_hangup - trigger a hangup event |
604 | * @tty: tty to hangup | 616 | * @tty: tty to hangup |
@@ -634,11 +646,12 @@ void tty_vhangup(struct tty_struct *tty) | |||
634 | 646 | ||
635 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); | 647 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); |
636 | #endif | 648 | #endif |
637 | do_tty_hangup(&tty->hangup_work); | 649 | __tty_hangup(tty); |
638 | } | 650 | } |
639 | 651 | ||
640 | EXPORT_SYMBOL(tty_vhangup); | 652 | EXPORT_SYMBOL(tty_vhangup); |
641 | 653 | ||
654 | |||
642 | /** | 655 | /** |
643 | * tty_vhangup_self - process vhangup for own ctty | 656 | * tty_vhangup_self - process vhangup for own ctty |
644 | * | 657 | * |
@@ -696,7 +709,8 @@ static void session_clear_tty(struct pid *session) | |||
696 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 709 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
697 | * | 710 | * |
698 | * Locking: | 711 | * Locking: |
699 | * BKL is taken for hysterical raisins | 712 | * BTM is taken for hysterical raisins, and held when |
713 | * called from no_tty(). | ||
700 | * tty_mutex is taken to protect tty | 714 | * tty_mutex is taken to protect tty |
701 | * ->siglock is taken to protect ->signal/->sighand | 715 | * ->siglock is taken to protect ->signal/->sighand |
702 | * tasklist_lock is taken to walk process list for sessions | 716 | * tasklist_lock is taken to walk process list for sessions |
@@ -714,10 +728,10 @@ void disassociate_ctty(int on_exit) | |||
714 | tty = get_current_tty(); | 728 | tty = get_current_tty(); |
715 | if (tty) { | 729 | if (tty) { |
716 | tty_pgrp = get_pid(tty->pgrp); | 730 | tty_pgrp = get_pid(tty->pgrp); |
717 | lock_kernel(); | 731 | if (on_exit) { |
718 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 732 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY) |
719 | tty_vhangup(tty); | 733 | tty_vhangup(tty); |
720 | unlock_kernel(); | 734 | } |
721 | tty_kref_put(tty); | 735 | tty_kref_put(tty); |
722 | } else if (on_exit) { | 736 | } else if (on_exit) { |
723 | struct pid *old_pgrp; | 737 | struct pid *old_pgrp; |
@@ -774,9 +788,9 @@ void disassociate_ctty(int on_exit) | |||
774 | void no_tty(void) | 788 | void no_tty(void) |
775 | { | 789 | { |
776 | struct task_struct *tsk = current; | 790 | struct task_struct *tsk = current; |
777 | lock_kernel(); | 791 | tty_lock(); |
778 | disassociate_ctty(0); | 792 | disassociate_ctty(0); |
779 | unlock_kernel(); | 793 | tty_unlock(); |
780 | proc_clear_tty(tsk); | 794 | proc_clear_tty(tsk); |
781 | } | 795 | } |
782 | 796 | ||
@@ -879,7 +893,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
879 | struct inode *inode; | 893 | struct inode *inode; |
880 | struct tty_ldisc *ld; | 894 | struct tty_ldisc *ld; |
881 | 895 | ||
882 | tty = (struct tty_struct *)file->private_data; | 896 | tty = file->private_data; |
883 | inode = file->f_path.dentry->d_inode; | 897 | inode = file->f_path.dentry->d_inode; |
884 | if (tty_paranoia_check(tty, inode, "tty_read")) | 898 | if (tty_paranoia_check(tty, inode, "tty_read")) |
885 | return -EIO; | 899 | return -EIO; |
@@ -1013,19 +1027,19 @@ out: | |||
1013 | * We don't put it into the syslog queue right now maybe in the future if | 1027 | * We don't put it into the syslog queue right now maybe in the future if |
1014 | * really needed. | 1028 | * really needed. |
1015 | * | 1029 | * |
1016 | * We must still hold the BKL and test the CLOSING flag for the moment. | 1030 | * We must still hold the BTM and test the CLOSING flag for the moment. |
1017 | */ | 1031 | */ |
1018 | 1032 | ||
1019 | void tty_write_message(struct tty_struct *tty, char *msg) | 1033 | void tty_write_message(struct tty_struct *tty, char *msg) |
1020 | { | 1034 | { |
1021 | if (tty) { | 1035 | if (tty) { |
1022 | mutex_lock(&tty->atomic_write_lock); | 1036 | mutex_lock(&tty->atomic_write_lock); |
1023 | lock_kernel(); | 1037 | tty_lock(); |
1024 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1038 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1025 | unlock_kernel(); | 1039 | tty_unlock(); |
1026 | tty->ops->write(tty, msg, strlen(msg)); | 1040 | tty->ops->write(tty, msg, strlen(msg)); |
1027 | } else | 1041 | } else |
1028 | unlock_kernel(); | 1042 | tty_unlock(); |
1029 | tty_write_unlock(tty); | 1043 | tty_write_unlock(tty); |
1030 | } | 1044 | } |
1031 | return; | 1045 | return; |
@@ -1056,7 +1070,7 @@ static ssize_t tty_write(struct file *file, const char __user *buf, | |||
1056 | ssize_t ret; | 1070 | ssize_t ret; |
1057 | struct tty_ldisc *ld; | 1071 | struct tty_ldisc *ld; |
1058 | 1072 | ||
1059 | tty = (struct tty_struct *)file->private_data; | 1073 | tty = file->private_data; |
1060 | if (tty_paranoia_check(tty, inode, "tty_write")) | 1074 | if (tty_paranoia_check(tty, inode, "tty_write")) |
1061 | return -EIO; | 1075 | return -EIO; |
1062 | if (!tty || !tty->ops->write || | 1076 | if (!tty || !tty->ops->write || |
@@ -1208,18 +1222,14 @@ static int tty_driver_install_tty(struct tty_driver *driver, | |||
1208 | int ret; | 1222 | int ret; |
1209 | 1223 | ||
1210 | if (driver->ops->install) { | 1224 | if (driver->ops->install) { |
1211 | lock_kernel(); | ||
1212 | ret = driver->ops->install(driver, tty); | 1225 | ret = driver->ops->install(driver, tty); |
1213 | unlock_kernel(); | ||
1214 | return ret; | 1226 | return ret; |
1215 | } | 1227 | } |
1216 | 1228 | ||
1217 | if (tty_init_termios(tty) == 0) { | 1229 | if (tty_init_termios(tty) == 0) { |
1218 | lock_kernel(); | ||
1219 | tty_driver_kref_get(driver); | 1230 | tty_driver_kref_get(driver); |
1220 | tty->count++; | 1231 | tty->count++; |
1221 | driver->ttys[idx] = tty; | 1232 | driver->ttys[idx] = tty; |
1222 | unlock_kernel(); | ||
1223 | return 0; | 1233 | return 0; |
1224 | } | 1234 | } |
1225 | return -ENOMEM; | 1235 | return -ENOMEM; |
@@ -1312,14 +1322,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1312 | struct tty_struct *tty; | 1322 | struct tty_struct *tty; |
1313 | int retval; | 1323 | int retval; |
1314 | 1324 | ||
1315 | lock_kernel(); | ||
1316 | /* Check if pty master is being opened multiple times */ | 1325 | /* Check if pty master is being opened multiple times */ |
1317 | if (driver->subtype == PTY_TYPE_MASTER && | 1326 | if (driver->subtype == PTY_TYPE_MASTER && |
1318 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { | 1327 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { |
1319 | unlock_kernel(); | ||
1320 | return ERR_PTR(-EIO); | 1328 | return ERR_PTR(-EIO); |
1321 | } | 1329 | } |
1322 | unlock_kernel(); | ||
1323 | 1330 | ||
1324 | /* | 1331 | /* |
1325 | * First time open is complex, especially for PTY devices. | 1332 | * First time open is complex, especially for PTY devices. |
@@ -1363,9 +1370,7 @@ release_mem_out: | |||
1363 | if (printk_ratelimit()) | 1370 | if (printk_ratelimit()) |
1364 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " | 1371 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1365 | "clearing slot %d\n", idx); | 1372 | "clearing slot %d\n", idx); |
1366 | lock_kernel(); | ||
1367 | release_tty(tty, idx); | 1373 | release_tty(tty, idx); |
1368 | unlock_kernel(); | ||
1369 | return ERR_PTR(retval); | 1374 | return ERR_PTR(retval); |
1370 | } | 1375 | } |
1371 | 1376 | ||
@@ -1508,14 +1513,14 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1508 | int idx; | 1513 | int idx; |
1509 | char buf[64]; | 1514 | char buf[64]; |
1510 | 1515 | ||
1511 | tty = (struct tty_struct *)filp->private_data; | 1516 | tty = filp->private_data; |
1512 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1517 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1513 | return 0; | 1518 | return 0; |
1514 | 1519 | ||
1515 | lock_kernel(); | 1520 | tty_lock(); |
1516 | check_tty_count(tty, "tty_release_dev"); | 1521 | check_tty_count(tty, "tty_release_dev"); |
1517 | 1522 | ||
1518 | tty_fasync(-1, filp, 0); | 1523 | __tty_fasync(-1, filp, 0); |
1519 | 1524 | ||
1520 | idx = tty->index; | 1525 | idx = tty->index; |
1521 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1526 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
@@ -1527,18 +1532,18 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1527 | if (idx < 0 || idx >= tty->driver->num) { | 1532 | if (idx < 0 || idx >= tty->driver->num) { |
1528 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " | 1533 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1529 | "free (%s)\n", tty->name); | 1534 | "free (%s)\n", tty->name); |
1530 | unlock_kernel(); | 1535 | tty_unlock(); |
1531 | return 0; | 1536 | return 0; |
1532 | } | 1537 | } |
1533 | if (!devpts) { | 1538 | if (!devpts) { |
1534 | if (tty != tty->driver->ttys[idx]) { | 1539 | if (tty != tty->driver->ttys[idx]) { |
1535 | unlock_kernel(); | 1540 | tty_unlock(); |
1536 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | 1541 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1537 | "for (%s)\n", idx, tty->name); | 1542 | "for (%s)\n", idx, tty->name); |
1538 | return 0; | 1543 | return 0; |
1539 | } | 1544 | } |
1540 | if (tty->termios != tty->driver->termios[idx]) { | 1545 | if (tty->termios != tty->driver->termios[idx]) { |
1541 | unlock_kernel(); | 1546 | tty_unlock(); |
1542 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " | 1547 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1543 | "for (%s)\n", | 1548 | "for (%s)\n", |
1544 | idx, tty->name); | 1549 | idx, tty->name); |
@@ -1556,21 +1561,21 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1556 | if (tty->driver->other && | 1561 | if (tty->driver->other && |
1557 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1562 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1558 | if (o_tty != tty->driver->other->ttys[idx]) { | 1563 | if (o_tty != tty->driver->other->ttys[idx]) { |
1559 | unlock_kernel(); | 1564 | tty_unlock(); |
1560 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " | 1565 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1561 | "not o_tty for (%s)\n", | 1566 | "not o_tty for (%s)\n", |
1562 | idx, tty->name); | 1567 | idx, tty->name); |
1563 | return 0 ; | 1568 | return 0 ; |
1564 | } | 1569 | } |
1565 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1570 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1566 | unlock_kernel(); | 1571 | tty_unlock(); |
1567 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " | 1572 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1568 | "not o_termios for (%s)\n", | 1573 | "not o_termios for (%s)\n", |
1569 | idx, tty->name); | 1574 | idx, tty->name); |
1570 | return 0; | 1575 | return 0; |
1571 | } | 1576 | } |
1572 | if (o_tty->link != tty) { | 1577 | if (o_tty->link != tty) { |
1573 | unlock_kernel(); | 1578 | tty_unlock(); |
1574 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); | 1579 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
1575 | return 0; | 1580 | return 0; |
1576 | } | 1581 | } |
@@ -1579,7 +1584,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1579 | if (tty->ops->close) | 1584 | if (tty->ops->close) |
1580 | tty->ops->close(tty, filp); | 1585 | tty->ops->close(tty, filp); |
1581 | 1586 | ||
1582 | unlock_kernel(); | 1587 | tty_unlock(); |
1583 | /* | 1588 | /* |
1584 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1589 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1585 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1590 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1602,7 +1607,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1602 | opens on /dev/tty */ | 1607 | opens on /dev/tty */ |
1603 | 1608 | ||
1604 | mutex_lock(&tty_mutex); | 1609 | mutex_lock(&tty_mutex); |
1605 | lock_kernel(); | 1610 | tty_lock(); |
1606 | tty_closing = tty->count <= 1; | 1611 | tty_closing = tty->count <= 1; |
1607 | o_tty_closing = o_tty && | 1612 | o_tty_closing = o_tty && |
1608 | (o_tty->count <= (pty_master ? 1 : 0)); | 1613 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1633,7 +1638,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1633 | 1638 | ||
1634 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " | 1639 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
1635 | "active!\n", tty_name(tty, buf)); | 1640 | "active!\n", tty_name(tty, buf)); |
1636 | unlock_kernel(); | 1641 | tty_unlock(); |
1637 | mutex_unlock(&tty_mutex); | 1642 | mutex_unlock(&tty_mutex); |
1638 | schedule(); | 1643 | schedule(); |
1639 | } | 1644 | } |
@@ -1698,7 +1703,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1698 | 1703 | ||
1699 | /* check whether both sides are closing ... */ | 1704 | /* check whether both sides are closing ... */ |
1700 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1705 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1701 | unlock_kernel(); | 1706 | tty_unlock(); |
1702 | return 0; | 1707 | return 0; |
1703 | } | 1708 | } |
1704 | 1709 | ||
@@ -1718,7 +1723,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1718 | /* Make this pty number available for reallocation */ | 1723 | /* Make this pty number available for reallocation */ |
1719 | if (devpts) | 1724 | if (devpts) |
1720 | devpts_kill_index(inode, idx); | 1725 | devpts_kill_index(inode, idx); |
1721 | unlock_kernel(); | 1726 | tty_unlock(); |
1722 | return 0; | 1727 | return 0; |
1723 | } | 1728 | } |
1724 | 1729 | ||
@@ -1760,12 +1765,12 @@ retry_open: | |||
1760 | retval = 0; | 1765 | retval = 0; |
1761 | 1766 | ||
1762 | mutex_lock(&tty_mutex); | 1767 | mutex_lock(&tty_mutex); |
1763 | lock_kernel(); | 1768 | tty_lock(); |
1764 | 1769 | ||
1765 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { | 1770 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { |
1766 | tty = get_current_tty(); | 1771 | tty = get_current_tty(); |
1767 | if (!tty) { | 1772 | if (!tty) { |
1768 | unlock_kernel(); | 1773 | tty_unlock(); |
1769 | mutex_unlock(&tty_mutex); | 1774 | mutex_unlock(&tty_mutex); |
1770 | return -ENXIO; | 1775 | return -ENXIO; |
1771 | } | 1776 | } |
@@ -1797,14 +1802,14 @@ retry_open: | |||
1797 | goto got_driver; | 1802 | goto got_driver; |
1798 | } | 1803 | } |
1799 | } | 1804 | } |
1800 | unlock_kernel(); | 1805 | tty_unlock(); |
1801 | mutex_unlock(&tty_mutex); | 1806 | mutex_unlock(&tty_mutex); |
1802 | return -ENODEV; | 1807 | return -ENODEV; |
1803 | } | 1808 | } |
1804 | 1809 | ||
1805 | driver = get_tty_driver(device, &index); | 1810 | driver = get_tty_driver(device, &index); |
1806 | if (!driver) { | 1811 | if (!driver) { |
1807 | unlock_kernel(); | 1812 | tty_unlock(); |
1808 | mutex_unlock(&tty_mutex); | 1813 | mutex_unlock(&tty_mutex); |
1809 | return -ENODEV; | 1814 | return -ENODEV; |
1810 | } | 1815 | } |
@@ -1814,7 +1819,7 @@ got_driver: | |||
1814 | tty = tty_driver_lookup_tty(driver, inode, index); | 1819 | tty = tty_driver_lookup_tty(driver, inode, index); |
1815 | 1820 | ||
1816 | if (IS_ERR(tty)) { | 1821 | if (IS_ERR(tty)) { |
1817 | unlock_kernel(); | 1822 | tty_unlock(); |
1818 | mutex_unlock(&tty_mutex); | 1823 | mutex_unlock(&tty_mutex); |
1819 | return PTR_ERR(tty); | 1824 | return PTR_ERR(tty); |
1820 | } | 1825 | } |
@@ -1830,7 +1835,7 @@ got_driver: | |||
1830 | mutex_unlock(&tty_mutex); | 1835 | mutex_unlock(&tty_mutex); |
1831 | tty_driver_kref_put(driver); | 1836 | tty_driver_kref_put(driver); |
1832 | if (IS_ERR(tty)) { | 1837 | if (IS_ERR(tty)) { |
1833 | unlock_kernel(); | 1838 | tty_unlock(); |
1834 | return PTR_ERR(tty); | 1839 | return PTR_ERR(tty); |
1835 | } | 1840 | } |
1836 | 1841 | ||
@@ -1860,29 +1865,29 @@ got_driver: | |||
1860 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1865 | printk(KERN_DEBUG "error %d in opening %s...", retval, |
1861 | tty->name); | 1866 | tty->name); |
1862 | #endif | 1867 | #endif |
1868 | tty_unlock(); /* need to call tty_release without BTM */ | ||
1863 | tty_release(inode, filp); | 1869 | tty_release(inode, filp); |
1864 | if (retval != -ERESTARTSYS) { | 1870 | if (retval != -ERESTARTSYS) |
1865 | unlock_kernel(); | ||
1866 | return retval; | 1871 | return retval; |
1867 | } | 1872 | |
1868 | if (signal_pending(current)) { | 1873 | if (signal_pending(current)) |
1869 | unlock_kernel(); | ||
1870 | return retval; | 1874 | return retval; |
1871 | } | 1875 | |
1872 | schedule(); | 1876 | schedule(); |
1873 | /* | 1877 | /* |
1874 | * Need to reset f_op in case a hangup happened. | 1878 | * Need to reset f_op in case a hangup happened. |
1875 | */ | 1879 | */ |
1880 | tty_lock(); | ||
1876 | if (filp->f_op == &hung_up_tty_fops) | 1881 | if (filp->f_op == &hung_up_tty_fops) |
1877 | filp->f_op = &tty_fops; | 1882 | filp->f_op = &tty_fops; |
1878 | unlock_kernel(); | 1883 | tty_unlock(); |
1879 | goto retry_open; | 1884 | goto retry_open; |
1880 | } | 1885 | } |
1881 | unlock_kernel(); | 1886 | tty_unlock(); |
1882 | 1887 | ||
1883 | 1888 | ||
1884 | mutex_lock(&tty_mutex); | 1889 | mutex_lock(&tty_mutex); |
1885 | lock_kernel(); | 1890 | tty_lock(); |
1886 | spin_lock_irq(¤t->sighand->siglock); | 1891 | spin_lock_irq(¤t->sighand->siglock); |
1887 | if (!noctty && | 1892 | if (!noctty && |
1888 | current->signal->leader && | 1893 | current->signal->leader && |
@@ -1890,7 +1895,7 @@ got_driver: | |||
1890 | tty->session == NULL) | 1895 | tty->session == NULL) |
1891 | __proc_set_tty(current, tty); | 1896 | __proc_set_tty(current, tty); |
1892 | spin_unlock_irq(¤t->sighand->siglock); | 1897 | spin_unlock_irq(¤t->sighand->siglock); |
1893 | unlock_kernel(); | 1898 | tty_unlock(); |
1894 | mutex_unlock(&tty_mutex); | 1899 | mutex_unlock(&tty_mutex); |
1895 | return 0; | 1900 | return 0; |
1896 | } | 1901 | } |
@@ -1915,7 +1920,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1915 | struct tty_ldisc *ld; | 1920 | struct tty_ldisc *ld; |
1916 | int ret = 0; | 1921 | int ret = 0; |
1917 | 1922 | ||
1918 | tty = (struct tty_struct *)filp->private_data; | 1923 | tty = filp->private_data; |
1919 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) | 1924 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
1920 | return 0; | 1925 | return 0; |
1921 | 1926 | ||
@@ -1926,14 +1931,13 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1926 | return ret; | 1931 | return ret; |
1927 | } | 1932 | } |
1928 | 1933 | ||
1929 | static int tty_fasync(int fd, struct file *filp, int on) | 1934 | static int __tty_fasync(int fd, struct file *filp, int on) |
1930 | { | 1935 | { |
1931 | struct tty_struct *tty; | 1936 | struct tty_struct *tty; |
1932 | unsigned long flags; | 1937 | unsigned long flags; |
1933 | int retval = 0; | 1938 | int retval = 0; |
1934 | 1939 | ||
1935 | lock_kernel(); | 1940 | tty = filp->private_data; |
1936 | tty = (struct tty_struct *)filp->private_data; | ||
1937 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 1941 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
1938 | goto out; | 1942 | goto out; |
1939 | 1943 | ||
@@ -1966,7 +1970,15 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
1966 | } | 1970 | } |
1967 | retval = 0; | 1971 | retval = 0; |
1968 | out: | 1972 | out: |
1969 | unlock_kernel(); | 1973 | return retval; |
1974 | } | ||
1975 | |||
1976 | static int tty_fasync(int fd, struct file *filp, int on) | ||
1977 | { | ||
1978 | int retval; | ||
1979 | tty_lock(); | ||
1980 | retval = __tty_fasync(fd, filp, on); | ||
1981 | tty_unlock(); | ||
1970 | return retval; | 1982 | return retval; |
1971 | } | 1983 | } |
1972 | 1984 | ||
@@ -2485,7 +2497,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2485 | struct tty_ldisc *ld; | 2497 | struct tty_ldisc *ld; |
2486 | struct inode *inode = file->f_dentry->d_inode; | 2498 | struct inode *inode = file->f_dentry->d_inode; |
2487 | 2499 | ||
2488 | tty = (struct tty_struct *)file->private_data; | 2500 | tty = file->private_data; |
2489 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | 2501 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) |
2490 | return -EINVAL; | 2502 | return -EINVAL; |
2491 | 2503 | ||
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 6bd5f8866c74..0c1889971459 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -517,19 +517,25 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
517 | 517 | ||
518 | /* See if packet mode change of state. */ | 518 | /* See if packet mode change of state. */ |
519 | if (tty->link && tty->link->packet) { | 519 | if (tty->link && tty->link->packet) { |
520 | int extproc = (old_termios.c_lflag & EXTPROC) | | ||
521 | (tty->termios->c_lflag & EXTPROC); | ||
520 | int old_flow = ((old_termios.c_iflag & IXON) && | 522 | int old_flow = ((old_termios.c_iflag & IXON) && |
521 | (old_termios.c_cc[VSTOP] == '\023') && | 523 | (old_termios.c_cc[VSTOP] == '\023') && |
522 | (old_termios.c_cc[VSTART] == '\021')); | 524 | (old_termios.c_cc[VSTART] == '\021')); |
523 | int new_flow = (I_IXON(tty) && | 525 | int new_flow = (I_IXON(tty) && |
524 | STOP_CHAR(tty) == '\023' && | 526 | STOP_CHAR(tty) == '\023' && |
525 | START_CHAR(tty) == '\021'); | 527 | START_CHAR(tty) == '\021'); |
526 | if (old_flow != new_flow) { | 528 | if ((old_flow != new_flow) || extproc) { |
527 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 529 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
528 | tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); | 530 | if (old_flow != new_flow) { |
529 | if (new_flow) | 531 | tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); |
530 | tty->ctrl_status |= TIOCPKT_DOSTOP; | 532 | if (new_flow) |
531 | else | 533 | tty->ctrl_status |= TIOCPKT_DOSTOP; |
532 | tty->ctrl_status |= TIOCPKT_NOSTOP; | 534 | else |
535 | tty->ctrl_status |= TIOCPKT_NOSTOP; | ||
536 | } | ||
537 | if (extproc) | ||
538 | tty->ctrl_status |= TIOCPKT_IOCTL; | ||
533 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 539 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
534 | wake_up_interruptible(&tty->link->read_wait); | 540 | wake_up_interruptible(&tty->link->read_wait); |
535 | } | 541 | } |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 500e740ec5e4..412f9775d19c 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -440,6 +440,8 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | |||
440 | * | 440 | * |
441 | * A helper opening method. Also a convenient debugging and check | 441 | * A helper opening method. Also a convenient debugging and check |
442 | * point. | 442 | * point. |
443 | * | ||
444 | * Locking: always called with BTM already held. | ||
443 | */ | 445 | */ |
444 | 446 | ||
445 | static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | 447 | static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) |
@@ -447,10 +449,9 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | |||
447 | WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); | 449 | WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); |
448 | if (ld->ops->open) { | 450 | if (ld->ops->open) { |
449 | int ret; | 451 | int ret; |
450 | /* BKL here locks verus a hangup event */ | 452 | /* BTM here locks versus a hangup event */ |
451 | lock_kernel(); | 453 | WARN_ON(!tty_locked()); |
452 | ret = ld->ops->open(tty); | 454 | ret = ld->ops->open(tty); |
453 | unlock_kernel(); | ||
454 | return ret; | 455 | return ret; |
455 | } | 456 | } |
456 | return 0; | 457 | return 0; |
@@ -553,7 +554,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
553 | if (IS_ERR(new_ldisc)) | 554 | if (IS_ERR(new_ldisc)) |
554 | return PTR_ERR(new_ldisc); | 555 | return PTR_ERR(new_ldisc); |
555 | 556 | ||
556 | lock_kernel(); | 557 | tty_lock(); |
557 | /* | 558 | /* |
558 | * We need to look at the tty locking here for pty/tty pairs | 559 | * We need to look at the tty locking here for pty/tty pairs |
559 | * when both sides try to change in parallel. | 560 | * when both sides try to change in parallel. |
@@ -567,12 +568,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
567 | */ | 568 | */ |
568 | 569 | ||
569 | if (tty->ldisc->ops->num == ldisc) { | 570 | if (tty->ldisc->ops->num == ldisc) { |
570 | unlock_kernel(); | 571 | tty_unlock(); |
571 | tty_ldisc_put(new_ldisc); | 572 | tty_ldisc_put(new_ldisc); |
572 | return 0; | 573 | return 0; |
573 | } | 574 | } |
574 | 575 | ||
575 | unlock_kernel(); | 576 | tty_unlock(); |
576 | /* | 577 | /* |
577 | * Problem: What do we do if this blocks ? | 578 | * Problem: What do we do if this blocks ? |
578 | * We could deadlock here | 579 | * We could deadlock here |
@@ -580,6 +581,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
580 | 581 | ||
581 | tty_wait_until_sent(tty, 0); | 582 | tty_wait_until_sent(tty, 0); |
582 | 583 | ||
584 | tty_lock(); | ||
583 | mutex_lock(&tty->ldisc_mutex); | 585 | mutex_lock(&tty->ldisc_mutex); |
584 | 586 | ||
585 | /* | 587 | /* |
@@ -589,13 +591,13 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
589 | 591 | ||
590 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { | 592 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { |
591 | mutex_unlock(&tty->ldisc_mutex); | 593 | mutex_unlock(&tty->ldisc_mutex); |
594 | tty_unlock(); | ||
592 | wait_event(tty_ldisc_wait, | 595 | wait_event(tty_ldisc_wait, |
593 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); | 596 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); |
597 | tty_lock(); | ||
594 | mutex_lock(&tty->ldisc_mutex); | 598 | mutex_lock(&tty->ldisc_mutex); |
595 | } | 599 | } |
596 | 600 | ||
597 | lock_kernel(); | ||
598 | |||
599 | set_bit(TTY_LDISC_CHANGING, &tty->flags); | 601 | set_bit(TTY_LDISC_CHANGING, &tty->flags); |
600 | 602 | ||
601 | /* | 603 | /* |
@@ -607,7 +609,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
607 | 609 | ||
608 | o_ldisc = tty->ldisc; | 610 | o_ldisc = tty->ldisc; |
609 | 611 | ||
610 | unlock_kernel(); | 612 | tty_unlock(); |
611 | /* | 613 | /* |
612 | * Make sure we don't change while someone holds a | 614 | * Make sure we don't change while someone holds a |
613 | * reference to the line discipline. The TTY_LDISC bit | 615 | * reference to the line discipline. The TTY_LDISC bit |
@@ -632,15 +634,15 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
632 | 634 | ||
633 | flush_scheduled_work(); | 635 | flush_scheduled_work(); |
634 | 636 | ||
637 | tty_lock(); | ||
635 | mutex_lock(&tty->ldisc_mutex); | 638 | mutex_lock(&tty->ldisc_mutex); |
636 | lock_kernel(); | ||
637 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 639 | if (test_bit(TTY_HUPPED, &tty->flags)) { |
638 | /* We were raced by the hangup method. It will have stomped | 640 | /* We were raced by the hangup method. It will have stomped |
639 | the ldisc data and closed the ldisc down */ | 641 | the ldisc data and closed the ldisc down */ |
640 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 642 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
641 | mutex_unlock(&tty->ldisc_mutex); | 643 | mutex_unlock(&tty->ldisc_mutex); |
642 | tty_ldisc_put(new_ldisc); | 644 | tty_ldisc_put(new_ldisc); |
643 | unlock_kernel(); | 645 | tty_unlock(); |
644 | return -EIO; | 646 | return -EIO; |
645 | } | 647 | } |
646 | 648 | ||
@@ -682,7 +684,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
682 | if (o_work) | 684 | if (o_work) |
683 | schedule_delayed_work(&o_tty->buf.work, 1); | 685 | schedule_delayed_work(&o_tty->buf.work, 1); |
684 | mutex_unlock(&tty->ldisc_mutex); | 686 | mutex_unlock(&tty->ldisc_mutex); |
685 | unlock_kernel(); | 687 | tty_unlock(); |
686 | return retval; | 688 | return retval; |
687 | } | 689 | } |
688 | 690 | ||
@@ -780,7 +782,20 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
780 | * Avoid racing set_ldisc or tty_ldisc_release | 782 | * Avoid racing set_ldisc or tty_ldisc_release |
781 | */ | 783 | */ |
782 | mutex_lock(&tty->ldisc_mutex); | 784 | mutex_lock(&tty->ldisc_mutex); |
783 | tty_ldisc_halt(tty); | 785 | |
786 | /* | ||
787 | * this is like tty_ldisc_halt, but we need to give up | ||
788 | * the BTM before calling cancel_delayed_work_sync, | ||
789 | * which may need to wait for another function taking the BTM | ||
790 | */ | ||
791 | clear_bit(TTY_LDISC, &tty->flags); | ||
792 | tty_unlock(); | ||
793 | cancel_delayed_work_sync(&tty->buf.work); | ||
794 | mutex_unlock(&tty->ldisc_mutex); | ||
795 | |||
796 | tty_lock(); | ||
797 | mutex_lock(&tty->ldisc_mutex); | ||
798 | |||
784 | /* At this point we have a closed ldisc and we want to | 799 | /* At this point we have a closed ldisc and we want to |
785 | reopen it. We could defer this to the next open but | 800 | reopen it. We could defer this to the next open but |
786 | it means auditing a lot of other paths so this is | 801 | it means auditing a lot of other paths so this is |
@@ -851,8 +866,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
851 | * race with the set_ldisc code path. | 866 | * race with the set_ldisc code path. |
852 | */ | 867 | */ |
853 | 868 | ||
869 | tty_unlock(); | ||
854 | tty_ldisc_halt(tty); | 870 | tty_ldisc_halt(tty); |
855 | flush_scheduled_work(); | 871 | flush_scheduled_work(); |
872 | tty_lock(); | ||
856 | 873 | ||
857 | mutex_lock(&tty->ldisc_mutex); | 874 | mutex_lock(&tty->ldisc_mutex); |
858 | /* | 875 | /* |
diff --git a/drivers/char/tty_mutex.c b/drivers/char/tty_mutex.c new file mode 100644 index 000000000000..133697540c73 --- /dev/null +++ b/drivers/char/tty_mutex.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * drivers/char/tty_lock.c | ||
3 | */ | ||
4 | #include <linux/tty.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/kallsyms.h> | ||
7 | #include <linux/semaphore.h> | ||
8 | #include <linux/sched.h> | ||
9 | |||
10 | /* | ||
11 | * The 'big tty mutex' | ||
12 | * | ||
13 | * This mutex is taken and released by tty_lock() and tty_unlock(), | ||
14 | * replacing the older big kernel lock. | ||
15 | * It can no longer be taken recursively, and does not get | ||
16 | * released implicitly while sleeping. | ||
17 | * | ||
18 | * Don't use in new code. | ||
19 | */ | ||
20 | static DEFINE_MUTEX(big_tty_mutex); | ||
21 | struct task_struct *__big_tty_mutex_owner; | ||
22 | EXPORT_SYMBOL_GPL(__big_tty_mutex_owner); | ||
23 | |||
24 | /* | ||
25 | * Getting the big tty mutex. | ||
26 | */ | ||
27 | void __lockfunc tty_lock(void) | ||
28 | { | ||
29 | struct task_struct *task = current; | ||
30 | |||
31 | WARN_ON(__big_tty_mutex_owner == task); | ||
32 | |||
33 | mutex_lock(&big_tty_mutex); | ||
34 | __big_tty_mutex_owner = task; | ||
35 | } | ||
36 | EXPORT_SYMBOL(tty_lock); | ||
37 | |||
38 | void __lockfunc tty_unlock(void) | ||
39 | { | ||
40 | struct task_struct *task = current; | ||
41 | |||
42 | WARN_ON(__big_tty_mutex_owner != task); | ||
43 | __big_tty_mutex_owner = NULL; | ||
44 | |||
45 | mutex_unlock(&big_tty_mutex); | ||
46 | } | ||
47 | EXPORT_SYMBOL(tty_unlock); | ||
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index a3bd1d0b66cf..33d37d230f8f 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -231,7 +231,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
231 | 231 | ||
232 | /* block if port is in the process of being closed */ | 232 | /* block if port is in the process of being closed */ |
233 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | 233 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
234 | wait_event_interruptible(port->close_wait, | 234 | wait_event_interruptible_tty(port->close_wait, |
235 | !(port->flags & ASYNC_CLOSING)); | 235 | !(port->flags & ASYNC_CLOSING)); |
236 | if (port->flags & ASYNC_HUP_NOTIFY) | 236 | if (port->flags & ASYNC_HUP_NOTIFY) |
237 | return -EAGAIN; | 237 | return -EAGAIN; |
@@ -294,7 +294,9 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
294 | retval = -ERESTARTSYS; | 294 | retval = -ERESTARTSYS; |
295 | break; | 295 | break; |
296 | } | 296 | } |
297 | tty_unlock(); | ||
297 | schedule(); | 298 | schedule(); |
299 | tty_lock(); | ||
298 | } | 300 | } |
299 | finish_wait(&port->open_wait, &wait); | 301 | finish_wait(&port->open_wait, &wait); |
300 | 302 | ||
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index c1791a63d99d..bcce46c96b88 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -463,10 +463,10 @@ vcs_open(struct inode *inode, struct file *filp) | |||
463 | unsigned int currcons = iminor(inode) & 127; | 463 | unsigned int currcons = iminor(inode) & 127; |
464 | int ret = 0; | 464 | int ret = 0; |
465 | 465 | ||
466 | lock_kernel(); | 466 | tty_lock(); |
467 | if(currcons && !vc_cons_allocated(currcons-1)) | 467 | if(currcons && !vc_cons_allocated(currcons-1)) |
468 | ret = -ENXIO; | 468 | ret = -ENXIO; |
469 | unlock_kernel(); | 469 | tty_unlock(); |
470 | return ret; | 470 | return ret; |
471 | } | 471 | } |
472 | 472 | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 44f03ddd8871..c734f9b1263a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -105,6 +105,7 @@ | |||
105 | #include <asm/system.h> | 105 | #include <asm/system.h> |
106 | #include <linux/uaccess.h> | 106 | #include <linux/uaccess.h> |
107 | #include <linux/kdb.h> | 107 | #include <linux/kdb.h> |
108 | #include <linux/ctype.h> | ||
108 | 109 | ||
109 | #define MAX_NR_CON_DRIVER 16 | 110 | #define MAX_NR_CON_DRIVER 16 |
110 | 111 | ||
@@ -286,8 +287,12 @@ static inline unsigned short *screenpos(struct vc_data *vc, int offset, int view | |||
286 | return p; | 287 | return p; |
287 | } | 288 | } |
288 | 289 | ||
290 | /* Called from the keyboard irq path.. */ | ||
289 | static inline void scrolldelta(int lines) | 291 | static inline void scrolldelta(int lines) |
290 | { | 292 | { |
293 | /* FIXME */ | ||
294 | /* scrolldelta needs some kind of consistency lock, but the BKL was | ||
295 | and still is not protecting versus the scheduled back end */ | ||
291 | scrollback_delta += lines; | 296 | scrollback_delta += lines; |
292 | schedule_console_callback(); | 297 | schedule_console_callback(); |
293 | } | 298 | } |
@@ -704,7 +709,10 @@ void redraw_screen(struct vc_data *vc, int is_switch) | |||
704 | update_attr(vc); | 709 | update_attr(vc); |
705 | clear_buffer_attributes(vc); | 710 | clear_buffer_attributes(vc); |
706 | } | 711 | } |
707 | if (update && vc->vc_mode != KD_GRAPHICS) | 712 | |
713 | /* Forcibly update if we're panicing */ | ||
714 | if ((update && vc->vc_mode != KD_GRAPHICS) || | ||
715 | vt_force_oops_output(vc)) | ||
708 | do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); | 716 | do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); |
709 | } | 717 | } |
710 | set_cursor(vc); | 718 | set_cursor(vc); |
@@ -742,6 +750,7 @@ static void visual_init(struct vc_data *vc, int num, int init) | |||
742 | vc->vc_hi_font_mask = 0; | 750 | vc->vc_hi_font_mask = 0; |
743 | vc->vc_complement_mask = 0; | 751 | vc->vc_complement_mask = 0; |
744 | vc->vc_can_do_color = 0; | 752 | vc->vc_can_do_color = 0; |
753 | vc->vc_panic_force_write = false; | ||
745 | vc->vc_sw->con_init(vc, init); | 754 | vc->vc_sw->con_init(vc, init); |
746 | if (!vc->vc_complement_mask) | 755 | if (!vc->vc_complement_mask) |
747 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; | 756 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; |
@@ -774,6 +783,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
774 | if (!vc) | 783 | if (!vc) |
775 | return -ENOMEM; | 784 | return -ENOMEM; |
776 | vc_cons[currcons].d = vc; | 785 | vc_cons[currcons].d = vc; |
786 | tty_port_init(&vc->port); | ||
777 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 787 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
778 | visual_init(vc, currcons, 1); | 788 | visual_init(vc, currcons, 1); |
779 | if (!*vc->vc_uni_pagedir_loc) | 789 | if (!*vc->vc_uni_pagedir_loc) |
@@ -963,12 +973,12 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
963 | * Resize a virtual console as seen from the console end of things. We | 973 | * Resize a virtual console as seen from the console end of things. We |
964 | * use the common vc_do_resize methods to update the structures. The | 974 | * use the common vc_do_resize methods to update the structures. The |
965 | * caller must hold the console sem to protect console internals and | 975 | * caller must hold the console sem to protect console internals and |
966 | * vc->vc_tty | 976 | * vc->port.tty |
967 | */ | 977 | */ |
968 | 978 | ||
969 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) | 979 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) |
970 | { | 980 | { |
971 | return vc_do_resize(vc->vc_tty, vc, cols, rows); | 981 | return vc_do_resize(vc->port.tty, vc, cols, rows); |
972 | } | 982 | } |
973 | 983 | ||
974 | /** | 984 | /** |
@@ -1796,8 +1806,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1796 | vc->vc_state = ESnormal; | 1806 | vc->vc_state = ESnormal; |
1797 | return; | 1807 | return; |
1798 | case ESpalette: | 1808 | case ESpalette: |
1799 | if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) { | 1809 | if (isxdigit(c)) { |
1800 | vc->vc_par[vc->vc_npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0'); | 1810 | vc->vc_par[vc->vc_npar++] = hex_to_bin(c); |
1801 | if (vc->vc_npar == 7) { | 1811 | if (vc->vc_npar == 7) { |
1802 | int i = vc->vc_par[0] * 3, j = 1; | 1812 | int i = vc->vc_par[0] * 3, j = 1; |
1803 | vc->vc_palette[i] = 16 * vc->vc_par[j++]; | 1813 | vc->vc_palette[i] = 16 * vc->vc_par[j++]; |
@@ -2505,7 +2515,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2505 | goto quit; | 2515 | goto quit; |
2506 | } | 2516 | } |
2507 | 2517 | ||
2508 | if (vc->vc_mode != KD_TEXT) | 2518 | if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) |
2509 | goto quit; | 2519 | goto quit; |
2510 | 2520 | ||
2511 | /* undraw cursor first */ | 2521 | /* undraw cursor first */ |
@@ -2611,8 +2621,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2611 | return -EFAULT; | 2621 | return -EFAULT; |
2612 | ret = 0; | 2622 | ret = 0; |
2613 | 2623 | ||
2614 | lock_kernel(); | ||
2615 | |||
2616 | switch (type) | 2624 | switch (type) |
2617 | { | 2625 | { |
2618 | case TIOCL_SETSEL: | 2626 | case TIOCL_SETSEL: |
@@ -2687,7 +2695,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2687 | ret = -EINVAL; | 2695 | ret = -EINVAL; |
2688 | break; | 2696 | break; |
2689 | } | 2697 | } |
2690 | unlock_kernel(); | ||
2691 | return ret; | 2698 | return ret; |
2692 | } | 2699 | } |
2693 | 2700 | ||
@@ -2800,12 +2807,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2800 | struct vc_data *vc = vc_cons[currcons].d; | 2807 | struct vc_data *vc = vc_cons[currcons].d; |
2801 | 2808 | ||
2802 | /* Still being freed */ | 2809 | /* Still being freed */ |
2803 | if (vc->vc_tty) { | 2810 | if (vc->port.tty) { |
2804 | release_console_sem(); | 2811 | release_console_sem(); |
2805 | return -ERESTARTSYS; | 2812 | return -ERESTARTSYS; |
2806 | } | 2813 | } |
2807 | tty->driver_data = vc; | 2814 | tty->driver_data = vc; |
2808 | vc->vc_tty = tty; | 2815 | vc->port.tty = tty; |
2809 | 2816 | ||
2810 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 2817 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { |
2811 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | 2818 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; |
@@ -2833,7 +2840,7 @@ static void con_shutdown(struct tty_struct *tty) | |||
2833 | struct vc_data *vc = tty->driver_data; | 2840 | struct vc_data *vc = tty->driver_data; |
2834 | BUG_ON(vc == NULL); | 2841 | BUG_ON(vc == NULL); |
2835 | acquire_console_sem(); | 2842 | acquire_console_sem(); |
2836 | vc->vc_tty = NULL; | 2843 | vc->port.tty = NULL; |
2837 | release_console_sem(); | 2844 | release_console_sem(); |
2838 | tty_shutdown(tty); | 2845 | tty_shutdown(tty); |
2839 | } | 2846 | } |
@@ -2915,6 +2922,7 @@ static int __init con_init(void) | |||
2915 | for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { | 2922 | for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { |
2916 | vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); | 2923 | vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); |
2917 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 2924 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
2925 | tty_port_init(&vc->port); | ||
2918 | visual_init(vc, currcons, 1); | 2926 | visual_init(vc, currcons, 1); |
2919 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); | 2927 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); |
2920 | vc_init(vc, vc->vc_rows, vc->vc_cols, | 2928 | vc_init(vc, vc->vc_rows, vc->vc_cols, |
@@ -3783,7 +3791,8 @@ void do_unblank_screen(int leaving_gfx) | |||
3783 | return; | 3791 | return; |
3784 | } | 3792 | } |
3785 | vc = vc_cons[fg_console].d; | 3793 | vc = vc_cons[fg_console].d; |
3786 | if (vc->vc_mode != KD_TEXT) | 3794 | /* Try to unblank in oops case too */ |
3795 | if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) | ||
3787 | return; /* but leave console_blanked != 0 */ | 3796 | return; /* but leave console_blanked != 0 */ |
3788 | 3797 | ||
3789 | if (blankinterval) { | 3798 | if (blankinterval) { |
@@ -3792,7 +3801,7 @@ void do_unblank_screen(int leaving_gfx) | |||
3792 | } | 3801 | } |
3793 | 3802 | ||
3794 | console_blanked = 0; | 3803 | console_blanked = 0; |
3795 | if (vc->vc_sw->con_blank(vc, 0, leaving_gfx)) | 3804 | if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc)) |
3796 | /* Low-level driver cannot restore -> do it ourselves */ | 3805 | /* Low-level driver cannot restore -> do it ourselves */ |
3797 | update_screen(vc); | 3806 | update_screen(vc); |
3798 | if (console_blank_hook) | 3807 | if (console_blank_hook) |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index cb19dbc52136..2bbeaaea46e9 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -133,7 +133,7 @@ static void vt_event_wait(struct vt_event_wait *vw) | |||
133 | list_add(&vw->list, &vt_events); | 133 | list_add(&vw->list, &vt_events); |
134 | spin_unlock_irqrestore(&vt_event_lock, flags); | 134 | spin_unlock_irqrestore(&vt_event_lock, flags); |
135 | /* Wait for it to pass */ | 135 | /* Wait for it to pass */ |
136 | wait_event_interruptible(vt_event_waitqueue, vw->done); | 136 | wait_event_interruptible_tty(vt_event_waitqueue, vw->done); |
137 | /* Dequeue it */ | 137 | /* Dequeue it */ |
138 | spin_lock_irqsave(&vt_event_lock, flags); | 138 | spin_lock_irqsave(&vt_event_lock, flags); |
139 | list_del(&vw->list); | 139 | list_del(&vw->list); |
@@ -509,7 +509,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
509 | 509 | ||
510 | console = vc->vc_num; | 510 | console = vc->vc_num; |
511 | 511 | ||
512 | lock_kernel(); | 512 | tty_lock(); |
513 | 513 | ||
514 | if (!vc_cons_allocated(console)) { /* impossible? */ | 514 | if (!vc_cons_allocated(console)) { /* impossible? */ |
515 | ret = -ENOIOCTLCMD; | 515 | ret = -ENOIOCTLCMD; |
@@ -1336,7 +1336,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
1336 | ret = -ENOIOCTLCMD; | 1336 | ret = -ENOIOCTLCMD; |
1337 | } | 1337 | } |
1338 | out: | 1338 | out: |
1339 | unlock_kernel(); | 1339 | tty_unlock(); |
1340 | return ret; | 1340 | return ret; |
1341 | eperm: | 1341 | eperm: |
1342 | ret = -EPERM; | 1342 | ret = -EPERM; |
@@ -1369,7 +1369,7 @@ void vc_SAK(struct work_struct *work) | |||
1369 | acquire_console_sem(); | 1369 | acquire_console_sem(); |
1370 | vc = vc_con->d; | 1370 | vc = vc_con->d; |
1371 | if (vc) { | 1371 | if (vc) { |
1372 | tty = vc->vc_tty; | 1372 | tty = vc->port.tty; |
1373 | /* | 1373 | /* |
1374 | * SAK should also work in all raw modes and reset | 1374 | * SAK should also work in all raw modes and reset |
1375 | * them properly. | 1375 | * them properly. |
@@ -1503,7 +1503,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, | |||
1503 | 1503 | ||
1504 | console = vc->vc_num; | 1504 | console = vc->vc_num; |
1505 | 1505 | ||
1506 | lock_kernel(); | 1506 | tty_lock(); |
1507 | 1507 | ||
1508 | if (!vc_cons_allocated(console)) { /* impossible? */ | 1508 | if (!vc_cons_allocated(console)) { /* impossible? */ |
1509 | ret = -ENOIOCTLCMD; | 1509 | ret = -ENOIOCTLCMD; |
@@ -1571,11 +1571,11 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, | |||
1571 | goto fallback; | 1571 | goto fallback; |
1572 | } | 1572 | } |
1573 | out: | 1573 | out: |
1574 | unlock_kernel(); | 1574 | tty_unlock(); |
1575 | return ret; | 1575 | return ret; |
1576 | 1576 | ||
1577 | fallback: | 1577 | fallback: |
1578 | unlock_kernel(); | 1578 | tty_unlock(); |
1579 | return vt_ioctl(tty, file, cmd, arg); | 1579 | return vt_ioctl(tty, file, cmd, arg); |
1580 | } | 1580 | } |
1581 | 1581 | ||
@@ -1761,10 +1761,13 @@ int vt_move_to_console(unsigned int vt, int alloc) | |||
1761 | return -EIO; | 1761 | return -EIO; |
1762 | } | 1762 | } |
1763 | release_console_sem(); | 1763 | release_console_sem(); |
1764 | tty_lock(); | ||
1764 | if (vt_waitactive(vt + 1)) { | 1765 | if (vt_waitactive(vt + 1)) { |
1765 | pr_debug("Suspend: Can't switch VCs."); | 1766 | pr_debug("Suspend: Can't switch VCs."); |
1767 | tty_unlock(); | ||
1766 | return -EINTR; | 1768 | return -EINTR; |
1767 | } | 1769 | } |
1770 | tty_unlock(); | ||
1768 | return prev; | 1771 | return prev; |
1769 | } | 1772 | } |
1770 | 1773 | ||