aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/parisc-agp.c2
-rw-r--r--drivers/char/amiserial.c1
-rw-r--r--drivers/char/cyclades.c1
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/hvc_console.c2
-rw-r--r--drivers/char/hw_random/intel-rng.c9
-rw-r--r--drivers/char/isicom.c17
-rw-r--r--drivers/char/istallion.c1
-rw-r--r--drivers/char/moxa.c1
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/n_hdlc.c1
-rw-r--r--drivers/char/n_r3964.c1
-rw-r--r--drivers/char/n_tty.c4
-rw-r--r--drivers/char/nozomi.c16
-rw-r--r--drivers/char/pcmcia/ipwireless/tty.c4
-rw-r--r--drivers/char/pty.c155
-rw-r--r--drivers/char/rio/rio_linux.c1
-rw-r--r--drivers/char/riscom8.c1
-rw-r--r--drivers/char/rocket.c1
-rw-r--r--drivers/char/serial167.c1
-rw-r--r--drivers/char/specialix.c25
-rw-r--r--drivers/char/sx.c1
-rw-r--r--drivers/char/synclink.c1
-rw-r--r--drivers/char/synclink_gt.c1
-rw-r--r--drivers/char/synclinkmp.c1
-rw-r--r--drivers/char/sysrq.c8
-rw-r--r--drivers/char/tpm/tpm.c1
-rw-r--r--drivers/char/tty_buffer.c13
-rw-r--r--drivers/char/tty_ioctl.c1
-rw-r--r--drivers/char/tty_ldisc.c176
-rw-r--r--drivers/char/tty_port.c2
-rw-r--r--drivers/char/vc_screen.c4
-rw-r--r--drivers/char/vr41xx_giu.c0
-rw-r--r--drivers/char/vt.c13
-rw-r--r--drivers/char/vt_ioctl.c1
35 files changed, 212 insertions, 257 deletions
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index f4bb43fb8016..e077701ae3d9 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -225,7 +225,7 @@ static const struct agp_bridge_driver parisc_agp_driver = {
225 .configure = parisc_agp_configure, 225 .configure = parisc_agp_configure,
226 .fetch_size = parisc_agp_fetch_size, 226 .fetch_size = parisc_agp_fetch_size,
227 .tlb_flush = parisc_agp_tlbflush, 227 .tlb_flush = parisc_agp_tlbflush,
228 .mask_memory = parisc_agp_mask_memory, 228 .mask_memory = parisc_agp_page_mask_memory,
229 .masks = parisc_agp_masks, 229 .masks = parisc_agp_masks,
230 .agp_enable = parisc_agp_enable, 230 .agp_enable = parisc_agp_enable,
231 .cache_flush = global_cache_flush, 231 .cache_flush = global_cache_flush,
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 72429b6b2fa8..6c32fbf07164 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -81,6 +81,7 @@ static char *serial_version = "4.30";
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>
84#include <linux/init.h> 85#include <linux/init.h>
85#include <linux/bitops.h> 86#include <linux/bitops.h>
86 87
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index f3366d3f06cf..2dafc2da0648 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -633,6 +633,7 @@
633#include <linux/tty.h> 633#include <linux/tty.h>
634#include <linux/tty_flip.h> 634#include <linux/tty_flip.h>
635#include <linux/serial.h> 635#include <linux/serial.h>
636#include <linux/smp_lock.h>
636#include <linux/major.h> 637#include <linux/major.h>
637#include <linux/string.h> 638#include <linux/string.h>
638#include <linux/fcntl.h> 639#include <linux/fcntl.h>
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index abef1f7d84fe..ff647ca1c489 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -36,6 +36,7 @@
36#include <linux/tty.h> 36#include <linux/tty.h>
37#include <linux/tty_flip.h> 37#include <linux/tty_flip.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/smp_lock.h>
39#include <linux/ioport.h> 40#include <linux/ioport.h>
40#include <linux/interrupt.h> 41#include <linux/interrupt.h>
41#include <linux/uaccess.h> 42#include <linux/uaccess.h>
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 94e7e3c8c05a..d97779ef72cb 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -552,7 +552,7 @@ static int hvc_chars_in_buffer(struct tty_struct *tty)
552 struct hvc_struct *hp = tty->driver_data; 552 struct hvc_struct *hp = tty->driver_data;
553 553
554 if (!hp) 554 if (!hp)
555 return -1; 555 return 0;
556 return hp->n_outbuf; 556 return hp->n_outbuf;
557} 557}
558 558
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index 5dcbe603eca2..91b53eb1c053 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -305,10 +305,11 @@ static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw,
305 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) 305 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
306 == BIOS_CNTL_LOCK_ENABLE_MASK) { 306 == BIOS_CNTL_LOCK_ENABLE_MASK) {
307 static __initdata /*const*/ char warning[] = 307 static __initdata /*const*/ char warning[] =
308 KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n" 308 KERN_WARNING
309 KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n" 309PFX "Firmware space is locked read-only. If you can't or\n"
310 KERN_WARNING PFX "you are certain that your system has a functional\n" 310PFX "don't want to disable this in firmware setup, and if\n"
311 KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n"; 311PFX "you are certain that your system has a functional\n"
312PFX "RNG, try using the 'no_fwh_detect' option.\n";
312 313
313 if (no_fwh_detect) 314 if (no_fwh_detect)
314 return -ENODEV; 315 return -ENODEV;
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 4159292e35cf..4f1f4cd670da 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -122,6 +122,7 @@
122#include <linux/fs.h> 122#include <linux/fs.h>
123#include <linux/sched.h> 123#include <linux/sched.h>
124#include <linux/serial.h> 124#include <linux/serial.h>
125#include <linux/smp_lock.h>
125#include <linux/mm.h> 126#include <linux/mm.h>
126#include <linux/interrupt.h> 127#include <linux/interrupt.h>
127#include <linux/timer.h> 128#include <linux/timer.h>
@@ -1478,10 +1479,10 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1478 status = inw(base + 0x4); 1479 status = inw(base + 0x4);
1479 if (status != 0) { 1480 if (status != 0) {
1480 dev_warn(&pdev->dev, "Card%d rejected load header:\n" 1481 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1481 KERN_WARNING "Address:0x%x\n" 1482 "Address:0x%x\n"
1482 KERN_WARNING "Count:0x%x\n" 1483 "Count:0x%x\n"
1483 KERN_WARNING "Status:0x%x\n", 1484 "Status:0x%x\n",
1484 index + 1, frame->addr, frame->count, status); 1485 index + 1, frame->addr, frame->count, status);
1485 goto errrelfw; 1486 goto errrelfw;
1486 } 1487 }
1487 outsw(base, frame->data, word_count); 1488 outsw(base, frame->data, word_count);
@@ -1526,10 +1527,10 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1526 status = inw(base + 0x4); 1527 status = inw(base + 0x4);
1527 if (status != 0) { 1528 if (status != 0) {
1528 dev_warn(&pdev->dev, "Card%d rejected verify header:\n" 1529 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1529 KERN_WARNING "Address:0x%x\n" 1530 "Address:0x%x\n"
1530 KERN_WARNING "Count:0x%x\n" 1531 "Count:0x%x\n"
1531 KERN_WARNING "Status: 0x%x\n", 1532 "Status: 0x%x\n",
1532 index + 1, frame->addr, frame->count, status); 1533 index + 1, frame->addr, frame->count, status);
1533 goto errrelfw; 1534 goto errrelfw;
1534 } 1535 }
1535 1536
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 0c999f5bb3db..ab2f3349c5c4 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/smp_lock.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/tty.h> 25#include <linux/tty.h>
25#include <linux/tty_flip.h> 26#include <linux/tty_flip.h>
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 65b6ff2442c6..dd0083bbb64a 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -34,6 +34,7 @@
34#include <linux/tty.h> 34#include <linux/tty.h>
35#include <linux/tty_flip.h> 35#include <linux/tty_flip.h>
36#include <linux/major.h> 36#include <linux/major.h>
37#include <linux/smp_lock.h>
37#include <linux/string.h> 38#include <linux/string.h>
38#include <linux/fcntl.h> 39#include <linux/fcntl.h>
39#include <linux/ptrace.h> 40#include <linux/ptrace.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 52d953eb30c3..dbf8d52f31d0 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -23,6 +23,7 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/signal.h> 24#include <linux/signal.h>
25#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/smp_lock.h>
26#include <linux/timer.h> 27#include <linux/timer.h>
27#include <linux/interrupt.h> 28#include <linux/interrupt.h>
28#include <linux/tty.h> 29#include <linux/tty.h>
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 1c43c8cdee25..c68118efad84 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -97,6 +97,7 @@
97#include <linux/slab.h> 97#include <linux/slab.h>
98#include <linux/tty.h> 98#include <linux/tty.h>
99#include <linux/errno.h> 99#include <linux/errno.h>
100#include <linux/smp_lock.h>
100#include <linux/string.h> /* used in new tty drivers */ 101#include <linux/string.h> /* used in new tty drivers */
101#include <linux/signal.h> /* used in new tty drivers */ 102#include <linux/signal.h> /* used in new tty drivers */
102#include <linux/if.h> 103#include <linux/if.h>
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 2e99158ebb8a..6934025a1ac1 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -58,6 +58,7 @@
58#include <linux/ioport.h> 58#include <linux/ioport.h>
59#include <linux/in.h> 59#include <linux/in.h>
60#include <linux/slab.h> 60#include <linux/slab.h>
61#include <linux/smp_lock.h>
61#include <linux/tty.h> 62#include <linux/tty.h>
62#include <linux/errno.h> 63#include <linux/errno.h>
63#include <linux/string.h> /* used in new tty drivers */ 64#include <linux/string.h> /* used in new tty drivers */
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 94a5d5020abc..973be2f44195 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1331,9 +1331,6 @@ handle_newline:
1331 1331
1332static void n_tty_write_wakeup(struct tty_struct *tty) 1332static void n_tty_write_wakeup(struct tty_struct *tty)
1333{ 1333{
1334 /* Write out any echoed characters that are still pending */
1335 process_echoes(tty);
1336
1337 if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) 1334 if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags))
1338 kill_fasync(&tty->fasync, SIGIO, POLL_OUT); 1335 kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
1339} 1336}
@@ -1586,6 +1583,7 @@ static int n_tty_open(struct tty_struct *tty)
1586 1583
1587static inline int input_available_p(struct tty_struct *tty, int amt) 1584static inline int input_available_p(struct tty_struct *tty, int amt)
1588{ 1585{
1586 tty_flush_to_ldisc(tty);
1589 if (tty->icanon) { 1587 if (tty->icanon) {
1590 if (tty->canon_data) 1588 if (tty->canon_data)
1591 return 1; 1589 return 1;
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index 574f1c79b6e6..ec58d8c387ff 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -828,7 +828,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
828 struct port *port = &dc->port[index]; 828 struct port *port = &dc->port[index];
829 void __iomem *addr = port->dl_addr[port->toggle_dl]; 829 void __iomem *addr = port->dl_addr[port->toggle_dl];
830 struct tty_struct *tty = tty_port_tty_get(&port->port); 830 struct tty_struct *tty = tty_port_tty_get(&port->port);
831 int i; 831 int i, ret;
832 832
833 if (unlikely(!tty)) { 833 if (unlikely(!tty)) {
834 DBG1("tty not open for port: %d?", index); 834 DBG1("tty not open for port: %d?", index);
@@ -844,12 +844,14 @@ static int receive_data(enum port_type index, struct nozomi *dc)
844 844
845 /* disable interrupt in downlink... */ 845 /* disable interrupt in downlink... */
846 disable_transmit_dl(index, dc); 846 disable_transmit_dl(index, dc);
847 return 0; 847 ret = 0;
848 goto put;
848 } 849 }
849 850
850 if (unlikely(size == 0)) { 851 if (unlikely(size == 0)) {
851 dev_err(&dc->pdev->dev, "size == 0?\n"); 852 dev_err(&dc->pdev->dev, "size == 0?\n");
852 return 1; 853 ret = 1;
854 goto put;
853 } 855 }
854 856
855 tty_buffer_request_room(tty, size); 857 tty_buffer_request_room(tty, size);
@@ -871,8 +873,10 @@ static int receive_data(enum port_type index, struct nozomi *dc)
871 } 873 }
872 874
873 set_bit(index, &dc->flip); 875 set_bit(index, &dc->flip);
876 ret = 1;
877put:
874 tty_kref_put(tty); 878 tty_kref_put(tty);
875 return 1; 879 return ret;
876} 880}
877 881
878/* Debug for interrupts */ 882/* Debug for interrupts */
@@ -1862,16 +1866,14 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
1862{ 1866{
1863 struct port *port = tty->driver_data; 1867 struct port *port = tty->driver_data;
1864 struct nozomi *dc = get_dc_by_tty(tty); 1868 struct nozomi *dc = get_dc_by_tty(tty);
1865 s32 rval; 1869 s32 rval = 0;
1866 1870
1867 if (unlikely(!dc || !port)) { 1871 if (unlikely(!dc || !port)) {
1868 rval = -ENODEV;
1869 goto exit_in_buffer; 1872 goto exit_in_buffer;
1870 } 1873 }
1871 1874
1872 if (unlikely(!port->port.count)) { 1875 if (unlikely(!port->port.count)) {
1873 dev_err(&dc->pdev->dev, "No tty open?\n"); 1876 dev_err(&dc->pdev->dev, "No tty open?\n");
1874 rval = -ENODEV;
1875 goto exit_in_buffer; 1877 goto exit_in_buffer;
1876 } 1878 }
1877 1879
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index 569f2f7743a7..674b3ab3587d 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
+++ b/drivers/char/pcmcia/ipwireless/tty.c
@@ -320,10 +320,10 @@ static int ipw_chars_in_buffer(struct tty_struct *linux_tty)
320 struct ipw_tty *tty = linux_tty->driver_data; 320 struct ipw_tty *tty = linux_tty->driver_data;
321 321
322 if (!tty) 322 if (!tty)
323 return -ENODEV; 323 return 0;
324 324
325 if (!tty->open_count) 325 if (!tty->open_count)
326 return -EINVAL; 326 return 0;
327 327
328 return tty->tx_bytes_queued; 328 return tty->tx_bytes_queued;
329} 329}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index daebe1ba43d4..6e6942c45f5b 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -22,6 +22,7 @@
22#include <linux/major.h> 22#include <linux/major.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/smp_lock.h>
25#include <linux/sysctl.h> 26#include <linux/sysctl.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include <linux/uaccess.h> 28#include <linux/uaccess.h>
@@ -75,114 +76,88 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
75 */ 76 */
76static void pty_unthrottle(struct tty_struct *tty) 77static void pty_unthrottle(struct tty_struct *tty)
77{ 78{
78 struct tty_struct *o_tty = tty->link; 79 tty_wakeup(tty->link);
79
80 if (!o_tty)
81 return;
82
83 tty_wakeup(o_tty);
84 set_bit(TTY_THROTTLED, &tty->flags); 80 set_bit(TTY_THROTTLED, &tty->flags);
85} 81}
86 82
87/* 83/**
88 * WSH 05/24/97: modified to 84 * pty_space - report space left for writing
89 * (1) use space in tty->flip instead of a shared temp buffer 85 * @to: tty we are writing into
90 * The flip buffers aren't being used for a pty, so there's lots
91 * of space available. The buffer is protected by a per-pty
92 * semaphore that should almost never come under contention.
93 * (2) avoid redundant copying for cases where count >> receive_room
94 * N.B. Calls from user space may now return an error code instead of
95 * a count.
96 * 86 *
97 * FIXME: Our pty_write method is called with our ldisc lock held but 87 * The tty buffers allow 64K but we sneak a peak and clip at 8K this
98 * not our partners. We can't just wait on the other one blindly without 88 * allows a lot of overspill room for echo and other fun messes to
99 * risking deadlocks. At some point when everything has settled down we need 89 * be handled properly
100 * to look into making pty_write at least able to sleep over an ldisc change. 90 */
91
92static int pty_space(struct tty_struct *to)
93{
94 int n = 8192 - to->buf.memory_used;
95 if (n < 0)
96 return 0;
97 return n;
98}
99
100/**
101 * pty_write - write to a pty
102 * @tty: the tty we write from
103 * @buf: kernel buffer of data
104 * @count: bytes to write
101 * 105 *
102 * The return on no ldisc is a bit counter intuitive but the logic works 106 * Our "hardware" write method. Data is coming from the ldisc which
103 * like this. During an ldisc change the other end will flush its buffers. We 107 * may be in a non sleeping state. We simply throw this at the other
104 * thus return the full length which is identical to the case where we had 108 * end of the link as if we were an IRQ handler receiving stuff for
105 * proper locking and happened to queue the bytes just before the flush during 109 * the other side of the pty/tty pair.
106 * the ldisc change.
107 */ 110 */
111
108static int pty_write(struct tty_struct *tty, const unsigned char *buf, 112static int pty_write(struct tty_struct *tty, const unsigned char *buf,
109 int count) 113 int count)
110{ 114{
111 struct tty_struct *to = tty->link; 115 struct tty_struct *to = tty->link;
112 struct tty_ldisc *ld; 116 int c;
113 int c = count;
114 117
115 if (!to || tty->stopped) 118 if (tty->stopped)
116 return 0; 119 return 0;
117 ld = tty_ldisc_ref(to); 120
118 121 /* This isn't locked but our 8K is quite sloppy so no
119 if (ld) { 122 big deal */
120 c = to->receive_room; 123
121 if (c > count) 124 c = pty_space(to);
122 c = count; 125 if (c > count)
123 ld->ops->receive_buf(to, buf, NULL, c); 126 c = count;
124 tty_ldisc_deref(ld); 127 if (c > 0) {
128 /* Stuff the data into the input queue of the other end */
129 c = tty_insert_flip_string(to, buf, c);
130 /* And shovel */
131 tty_flip_buffer_push(to);
132 tty_wakeup(tty);
125 } 133 }
126 return c; 134 return c;
127} 135}
128 136
137/**
138 * pty_write_room - write space
139 * @tty: tty we are writing from
140 *
141 * Report how many bytes the ldisc can send into the queue for
142 * the other device.
143 */
144
129static int pty_write_room(struct tty_struct *tty) 145static int pty_write_room(struct tty_struct *tty)
130{ 146{
131 struct tty_struct *to = tty->link; 147 return pty_space(tty->link);
132
133 if (!to || tty->stopped)
134 return 0;
135
136 return to->receive_room;
137} 148}
138 149
139/* 150/**
140 * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior 151 * pty_chars_in_buffer - characters currently in our tx queue
141 * The chars_in_buffer() value is used by the ldisc select() function 152 * @tty: our tty
142 * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256).
143 * The pty driver chars_in_buffer() Master/Slave must behave differently:
144 *
145 * The Master side needs to allow typed-ahead commands to accumulate
146 * while being canonicalized, so we report "our buffer" as empty until
147 * some threshold is reached, and then report the count. (Any count >
148 * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock
149 * the count returned must be 0 if no canonical data is available to be
150 * read. (The N_TTY ldisc.chars_in_buffer now knows this.)
151 * 153 *
152 * The Slave side passes all characters in raw mode to the Master side's 154 * Report how much we have in the transmit queue. As everything is
153 * buffer where they can be read immediately, so in this case we can 155 * instantly at the other end this is easy to implement.
154 * return the true count in the buffer.
155 */ 156 */
157
156static int pty_chars_in_buffer(struct tty_struct *tty) 158static int pty_chars_in_buffer(struct tty_struct *tty)
157{ 159{
158 struct tty_struct *to = tty->link; 160 return 0;
159 struct tty_ldisc *ld;
160 int count = 0;
161
162 /* We should get the line discipline lock for "tty->link" */
163 if (!to)
164 return 0;
165 /* We cannot take a sleeping reference here without deadlocking with
166 an ldisc change - but it doesn't really matter */
167 ld = tty_ldisc_ref(to);
168 if (ld == NULL)
169 return 0;
170
171 /* The ldisc must report 0 if no characters available to be read */
172 if (ld->ops->chars_in_buffer)
173 count = ld->ops->chars_in_buffer(to);
174
175 tty_ldisc_deref(ld);
176
177 if (tty->driver->subtype == PTY_TYPE_SLAVE)
178 return count;
179
180 /* Master side driver ... if the other side's read buffer is less than
181 * half full, return 0 to allow writers to proceed; otherwise return
182 * the count. This leaves a comfortable margin to avoid overflow,
183 * and still allows half a buffer's worth of typed-ahead commands.
184 */
185 return (count < N_TTY_BUF_SIZE/2) ? 0 : count;
186} 161}
187 162
188/* Set the lock flag on a pty */ 163/* Set the lock flag on a pty */
@@ -202,20 +177,10 @@ static void pty_flush_buffer(struct tty_struct *tty)
202{ 177{
203 struct tty_struct *to = tty->link; 178 struct tty_struct *to = tty->link;
204 unsigned long flags; 179 unsigned long flags;
205 struct tty_ldisc *ld;
206 180
207 if (!to) 181 if (!to)
208 return; 182 return;
209 ld = tty_ldisc_ref(to); 183 /* tty_buffer_flush(to); FIXME */
210
211 /* The other end is changing discipline */
212 if (!ld)
213 return;
214
215 if (ld->ops->flush_buffer)
216 to->ldisc->ops->flush_buffer(to);
217 tty_ldisc_deref(ld);
218
219 if (to->packet) { 184 if (to->packet) {
220 spin_lock_irqsave(&tty->ctrl_lock, flags); 185 spin_lock_irqsave(&tty->ctrl_lock, flags);
221 tty->ctrl_status |= TIOCPKT_FLUSHWRITE; 186 tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index ce81da5b2da9..d58c2eb07f07 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -44,6 +44,7 @@
44#include <linux/delay.h> 44#include <linux/delay.h>
45#include <linux/pci.h> 45#include <linux/pci.h>
46#include <linux/slab.h> 46#include <linux/slab.h>
47#include <linux/smp_lock.h>
47#include <linux/miscdevice.h> 48#include <linux/miscdevice.h>
48#include <linux/init.h> 49#include <linux/init.h>
49 50
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 217660451237..171711acf5cd 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -47,6 +47,7 @@
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>
50#include <linux/spinlock.h> 51#include <linux/spinlock.h>
51#include <linux/device.h> 52#include <linux/device.h>
52 53
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 63d5b628477a..0e29a23ec4c5 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -73,6 +73,7 @@
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>
76#include <linux/string.h> 77#include <linux/string.h>
77#include <linux/fcntl.h> 78#include <linux/fcntl.h>
78#include <linux/ptrace.h> 79#include <linux/ptrace.h>
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index f1f24f0ee26f..51e7a46787be 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -52,6 +52,7 @@
52#include <linux/interrupt.h> 52#include <linux/interrupt.h>
53#include <linux/serial.h> 53#include <linux/serial.h>
54#include <linux/serialP.h> 54#include <linux/serialP.h>
55#include <linux/smp_lock.h>
55#include <linux/string.h> 56#include <linux/string.h>
56#include <linux/fcntl.h> 57#include <linux/fcntl.h>
57#include <linux/ptrace.h> 58#include <linux/ptrace.h>
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index e72be4190a44..268e17f9ec3f 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -87,6 +87,7 @@
87#include <linux/tty_flip.h> 87#include <linux/tty_flip.h>
88#include <linux/mm.h> 88#include <linux/mm.h>
89#include <linux/serial.h> 89#include <linux/serial.h>
90#include <linux/smp_lock.h>
90#include <linux/fcntl.h> 91#include <linux/fcntl.h>
91#include <linux/major.h> 92#include <linux/major.h>
92#include <linux/delay.h> 93#include <linux/delay.h>
@@ -1808,10 +1809,10 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1808 if (clear & TIOCM_DTR) 1809 if (clear & TIOCM_DTR)
1809 port->MSVR &= ~MSVR_DTR; 1810 port->MSVR &= ~MSVR_DTR;
1810 } 1811 }
1811 spin_lock_irqsave(&bp->lock, flags); 1812 spin_lock(&bp->lock);
1812 sx_out(bp, CD186x_CAR, port_No(port)); 1813 sx_out(bp, CD186x_CAR, port_No(port));
1813 sx_out(bp, CD186x_MSVR, port->MSVR); 1814 sx_out(bp, CD186x_MSVR, port->MSVR);
1814 spin_unlock_irqrestore(&bp->lock, flags); 1815 spin_unlock(&bp->lock);
1815 spin_unlock_irqrestore(&port->lock, flags); 1816 spin_unlock_irqrestore(&port->lock, flags);
1816 func_exit(); 1817 func_exit();
1817 return 0; 1818 return 0;
@@ -1832,11 +1833,11 @@ static int sx_send_break(struct tty_struct *tty, int length)
1832 port->break_length = SPECIALIX_TPS / HZ * length; 1833 port->break_length = SPECIALIX_TPS / HZ * length;
1833 port->COR2 |= COR2_ETC; 1834 port->COR2 |= COR2_ETC;
1834 port->IER |= IER_TXRDY; 1835 port->IER |= IER_TXRDY;
1835 spin_lock_irqsave(&bp->lock, flags); 1836 spin_lock(&bp->lock);
1836 sx_out(bp, CD186x_CAR, port_No(port)); 1837 sx_out(bp, CD186x_CAR, port_No(port));
1837 sx_out(bp, CD186x_COR2, port->COR2); 1838 sx_out(bp, CD186x_COR2, port->COR2);
1838 sx_out(bp, CD186x_IER, port->IER); 1839 sx_out(bp, CD186x_IER, port->IER);
1839 spin_unlock_irqrestore(&bp->lock, flags); 1840 spin_unlock(&bp->lock);
1840 spin_unlock_irqrestore(&port->lock, flags); 1841 spin_unlock_irqrestore(&port->lock, flags);
1841 sx_wait_CCR(bp); 1842 sx_wait_CCR(bp);
1842 spin_lock_irqsave(&bp->lock, flags); 1843 spin_lock_irqsave(&bp->lock, flags);
@@ -2022,9 +2023,9 @@ static void sx_unthrottle(struct tty_struct *tty)
2022 if (sx_crtscts(tty)) 2023 if (sx_crtscts(tty))
2023 port->MSVR |= MSVR_DTR; 2024 port->MSVR |= MSVR_DTR;
2024 /* Else clause: see remark in "sx_throttle"... */ 2025 /* Else clause: see remark in "sx_throttle"... */
2025 spin_lock_irqsave(&bp->lock, flags); 2026 spin_lock(&bp->lock);
2026 sx_out(bp, CD186x_CAR, port_No(port)); 2027 sx_out(bp, CD186x_CAR, port_No(port));
2027 spin_unlock_irqrestore(&bp->lock, flags); 2028 spin_unlock(&bp->lock);
2028 if (I_IXOFF(tty)) { 2029 if (I_IXOFF(tty)) {
2029 spin_unlock_irqrestore(&port->lock, flags); 2030 spin_unlock_irqrestore(&port->lock, flags);
2030 sx_wait_CCR(bp); 2031 sx_wait_CCR(bp);
@@ -2034,9 +2035,9 @@ static void sx_unthrottle(struct tty_struct *tty)
2034 sx_wait_CCR(bp); 2035 sx_wait_CCR(bp);
2035 spin_lock_irqsave(&port->lock, flags); 2036 spin_lock_irqsave(&port->lock, flags);
2036 } 2037 }
2037 spin_lock_irqsave(&bp->lock, flags); 2038 spin_lock(&bp->lock);
2038 sx_out(bp, CD186x_MSVR, port->MSVR); 2039 sx_out(bp, CD186x_MSVR, port->MSVR);
2039 spin_unlock_irqrestore(&bp->lock, flags); 2040 spin_unlock(&bp->lock);
2040 spin_unlock_irqrestore(&port->lock, flags); 2041 spin_unlock_irqrestore(&port->lock, flags);
2041 2042
2042 func_exit(); 2043 func_exit();
@@ -2060,10 +2061,10 @@ static void sx_stop(struct tty_struct *tty)
2060 2061
2061 spin_lock_irqsave(&port->lock, flags); 2062 spin_lock_irqsave(&port->lock, flags);
2062 port->IER &= ~IER_TXRDY; 2063 port->IER &= ~IER_TXRDY;
2063 spin_lock_irqsave(&bp->lock, flags); 2064 spin_lock(&bp->lock);
2064 sx_out(bp, CD186x_CAR, port_No(port)); 2065 sx_out(bp, CD186x_CAR, port_No(port));
2065 sx_out(bp, CD186x_IER, port->IER); 2066 sx_out(bp, CD186x_IER, port->IER);
2066 spin_unlock_irqrestore(&bp->lock, flags); 2067 spin_unlock(&bp->lock);
2067 spin_unlock_irqrestore(&port->lock, flags); 2068 spin_unlock_irqrestore(&port->lock, flags);
2068 2069
2069 func_exit(); 2070 func_exit();
@@ -2088,10 +2089,10 @@ static void sx_start(struct tty_struct *tty)
2088 spin_lock_irqsave(&port->lock, flags); 2089 spin_lock_irqsave(&port->lock, flags);
2089 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { 2090 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2090 port->IER |= IER_TXRDY; 2091 port->IER |= IER_TXRDY;
2091 spin_lock_irqsave(&bp->lock, flags); 2092 spin_lock(&bp->lock);
2092 sx_out(bp, CD186x_CAR, port_No(port)); 2093 sx_out(bp, CD186x_CAR, port_No(port));
2093 sx_out(bp, CD186x_IER, port->IER); 2094 sx_out(bp, CD186x_IER, port->IER);
2094 spin_unlock_irqrestore(&bp->lock, flags); 2095 spin_unlock(&bp->lock);
2095 } 2096 }
2096 spin_unlock_irqrestore(&port->lock, flags); 2097 spin_unlock_irqrestore(&port->lock, flags);
2097 2098
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 518f2a25d91e..a81ec4fcf6ff 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -216,6 +216,7 @@
216#include <linux/eisa.h> 216#include <linux/eisa.h>
217#include <linux/pci.h> 217#include <linux/pci.h>
218#include <linux/slab.h> 218#include <linux/slab.h>
219#include <linux/smp_lock.h>
219#include <linux/init.h> 220#include <linux/init.h>
220#include <linux/miscdevice.h> 221#include <linux/miscdevice.h>
221#include <linux/bitops.h> 222#include <linux/bitops.h>
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index afded3a2379c..813552f14884 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -81,6 +81,7 @@
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>
84#include <linux/delay.h> 85#include <linux/delay.h>
85#include <linux/netdevice.h> 86#include <linux/netdevice.h>
86#include <linux/vmalloc.h> 87#include <linux/vmalloc.h>
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index a2e67e6df3a1..91f20a92fddf 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -62,6 +62,7 @@
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>
65#include <linux/netdevice.h> 66#include <linux/netdevice.h>
66#include <linux/vmalloc.h> 67#include <linux/vmalloc.h>
67#include <linux/init.h> 68#include <linux/init.h>
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 6f727e3c53ad..8d4a2a8a0a70 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -52,6 +52,7 @@
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>
55#include <linux/netdevice.h> 56#include <linux/netdevice.h>
56#include <linux/vmalloc.h> 57#include <linux/vmalloc.h>
57#include <linux/init.h> 58#include <linux/init.h>
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 0db35857e4d8..5d7a02f63e1c 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,7 +35,6 @@
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/vt_kern.h> 36#include <linux/vt_kern.h>
37#include <linux/workqueue.h> 37#include <linux/workqueue.h>
38#include <linux/kexec.h>
39#include <linux/hrtimer.h> 38#include <linux/hrtimer.h>
40#include <linux/oom.h> 39#include <linux/oom.h>
41 40
@@ -124,9 +123,12 @@ static struct sysrq_key_op sysrq_unraw_op = {
124static void sysrq_handle_crash(int key, struct tty_struct *tty) 123static void sysrq_handle_crash(int key, struct tty_struct *tty)
125{ 124{
126 char *killer = NULL; 125 char *killer = NULL;
126
127 panic_on_oops = 1; /* force panic */
128 wmb();
127 *killer = 1; 129 *killer = 1;
128} 130}
129static struct sysrq_key_op sysrq_crashdump_op = { 131static struct sysrq_key_op sysrq_crash_op = {
130 .handler = sysrq_handle_crash, 132 .handler = sysrq_handle_crash,
131 .help_msg = "Crash", 133 .help_msg = "Crash",
132 .action_msg = "Trigger a crash", 134 .action_msg = "Trigger a crash",
@@ -401,7 +403,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
401 */ 403 */
402 NULL, /* a */ 404 NULL, /* a */
403 &sysrq_reboot_op, /* b */ 405 &sysrq_reboot_op, /* b */
404 &sysrq_crashdump_op, /* c & ibm_emac driver debug */ 406 &sysrq_crash_op, /* c & ibm_emac driver debug */
405 &sysrq_showlocks_op, /* d */ 407 &sysrq_showlocks_op, /* d */
406 &sysrq_term_op, /* e */ 408 &sysrq_term_op, /* e */
407 &sysrq_moom_op, /* f */ 409 &sysrq_moom_op, /* f */
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index ccdd828adcef..b0603b2e5684 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -26,7 +26,6 @@
26#include <linux/poll.h> 26#include <linux/poll.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <linux/smp_lock.h>
30 29
31#include "tpm.h" 30#include "tpm.h"
32 31
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 810ee25d66a4..3108991c5c8b 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -462,6 +462,19 @@ static void flush_to_ldisc(struct work_struct *work)
462} 462}
463 463
464/** 464/**
465 * tty_flush_to_ldisc
466 * @tty: tty to push
467 *
468 * Push the terminal flip buffers to the line discipline.
469 *
470 * Must not be called from IRQ context.
471 */
472void tty_flush_to_ldisc(struct tty_struct *tty)
473{
474 flush_to_ldisc(&tty->buf.work.work);
475}
476
477/**
465 * tty_flip_buffer_push - terminal 478 * tty_flip_buffer_push - terminal
466 * @tty: tty to push 479 * @tty: tty to push
467 * 480 *
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index b24f6c6a1ea3..ad6ba4ed2808 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -21,7 +21,6 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/smp_lock.h>
25 24
26#include <asm/io.h> 25#include <asm/io.h>
27#include <asm/uaccess.h> 26#include <asm/uaccess.h>
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index 913aa8d3f1c5..1733d3439ad2 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -21,7 +21,6 @@
21#include <linux/proc_fs.h> 21#include <linux/proc_fs.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/smp_lock.h>
25#include <linux/device.h> 24#include <linux/device.h>
26#include <linux/wait.h> 25#include <linux/wait.h>
27#include <linux/bitops.h> 26#include <linux/bitops.h>
@@ -49,6 +48,41 @@ static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
49/* Line disc dispatch table */ 48/* Line disc dispatch table */
50static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; 49static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
51 50
51static inline struct tty_ldisc *get_ldisc(struct tty_ldisc *ld)
52{
53 if (ld)
54 atomic_inc(&ld->users);
55 return ld;
56}
57
58static void put_ldisc(struct tty_ldisc *ld)
59{
60 unsigned long flags;
61
62 if (WARN_ON_ONCE(!ld))
63 return;
64
65 /*
66 * If this is the last user, free the ldisc, and
67 * release the ldisc ops.
68 *
69 * We really want an "atomic_dec_and_lock_irqsave()",
70 * but we don't have it, so this does it by hand.
71 */
72 local_irq_save(flags);
73 if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
74 struct tty_ldisc_ops *ldo = ld->ops;
75
76 ldo->refcount--;
77 module_put(ldo->owner);
78 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
79
80 kfree(ld);
81 return;
82 }
83 local_irq_restore(flags);
84}
85
52/** 86/**
53 * tty_register_ldisc - install a line discipline 87 * tty_register_ldisc - install a line discipline
54 * @disc: ldisc number 88 * @disc: ldisc number
@@ -143,7 +177,7 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
143 /* lock it */ 177 /* lock it */
144 ldops->refcount++; 178 ldops->refcount++;
145 ld->ops = ldops; 179 ld->ops = ldops;
146 ld->refcount = 0; 180 atomic_set(&ld->users, 1);
147 err = 0; 181 err = 0;
148 } 182 }
149 } 183 }
@@ -182,35 +216,6 @@ static struct tty_ldisc *tty_ldisc_get(int disc)
182 return ld; 216 return ld;
183} 217}
184 218
185/**
186 * tty_ldisc_put - drop ldisc reference
187 * @ld: ldisc
188 *
189 * Drop a reference to a line discipline. Manage refcounts and
190 * module usage counts. Free the ldisc once the recount hits zero.
191 *
192 * Locking:
193 * takes tty_ldisc_lock to guard against ldisc races
194 */
195
196static void tty_ldisc_put(struct tty_ldisc *ld)
197{
198 unsigned long flags;
199 int disc = ld->ops->num;
200 struct tty_ldisc_ops *ldo;
201
202 BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
203
204 spin_lock_irqsave(&tty_ldisc_lock, flags);
205 ldo = tty_ldiscs[disc];
206 BUG_ON(ldo->refcount == 0);
207 ldo->refcount--;
208 module_put(ldo->owner);
209 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
210 WARN_ON(ld->refcount);
211 kfree(ld);
212}
213
214static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) 219static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
215{ 220{
216 return (*pos < NR_LDISCS) ? pos : NULL; 221 return (*pos < NR_LDISCS) ? pos : NULL;
@@ -235,7 +240,7 @@ static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
235 if (IS_ERR(ld)) 240 if (IS_ERR(ld))
236 return 0; 241 return 0;
237 seq_printf(m, "%-10s %2d\n", ld->ops->name ? ld->ops->name : "???", i); 242 seq_printf(m, "%-10s %2d\n", ld->ops->name ? ld->ops->name : "???", i);
238 tty_ldisc_put(ld); 243 put_ldisc(ld);
239 return 0; 244 return 0;
240} 245}
241 246
@@ -289,20 +294,17 @@ static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
289 * Locking: takes tty_ldisc_lock 294 * Locking: takes tty_ldisc_lock
290 */ 295 */
291 296
292static int tty_ldisc_try(struct tty_struct *tty) 297static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty)
293{ 298{
294 unsigned long flags; 299 unsigned long flags;
295 struct tty_ldisc *ld; 300 struct tty_ldisc *ld;
296 int ret = 0;
297 301
298 spin_lock_irqsave(&tty_ldisc_lock, flags); 302 spin_lock_irqsave(&tty_ldisc_lock, flags);
299 ld = tty->ldisc; 303 ld = NULL;
300 if (test_bit(TTY_LDISC, &tty->flags)) { 304 if (test_bit(TTY_LDISC, &tty->flags))
301 ld->refcount++; 305 ld = get_ldisc(tty->ldisc);
302 ret = 1;
303 }
304 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 306 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
305 return ret; 307 return ld;
306} 308}
307 309
308/** 310/**
@@ -323,10 +325,11 @@ static int tty_ldisc_try(struct tty_struct *tty)
323 325
324struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) 326struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
325{ 327{
328 struct tty_ldisc *ld;
329
326 /* wait_event is a macro */ 330 /* wait_event is a macro */
327 wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); 331 wait_event(tty_ldisc_wait, (ld = tty_ldisc_try(tty)) != NULL);
328 WARN_ON(tty->ldisc->refcount == 0); 332 return ld;
329 return tty->ldisc;
330} 333}
331EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); 334EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
332 335
@@ -343,9 +346,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
343 346
344struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) 347struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
345{ 348{
346 if (tty_ldisc_try(tty)) 349 return tty_ldisc_try(tty);
347 return tty->ldisc;
348 return NULL;
349} 350}
350EXPORT_SYMBOL_GPL(tty_ldisc_ref); 351EXPORT_SYMBOL_GPL(tty_ldisc_ref);
351 352
@@ -361,21 +362,15 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref);
361 362
362void tty_ldisc_deref(struct tty_ldisc *ld) 363void tty_ldisc_deref(struct tty_ldisc *ld)
363{ 364{
364 unsigned long flags; 365 put_ldisc(ld);
365
366 BUG_ON(ld == NULL);
367
368 spin_lock_irqsave(&tty_ldisc_lock, flags);
369 if (ld->refcount == 0)
370 printk(KERN_ERR "tty_ldisc_deref: no references.\n");
371 else
372 ld->refcount--;
373 if (ld->refcount == 0)
374 wake_up(&tty_ldisc_wait);
375 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
376} 366}
377EXPORT_SYMBOL_GPL(tty_ldisc_deref); 367EXPORT_SYMBOL_GPL(tty_ldisc_deref);
378 368
369static inline void tty_ldisc_put(struct tty_ldisc *ld)
370{
371 put_ldisc(ld);
372}
373
379/** 374/**
380 * tty_ldisc_enable - allow ldisc use 375 * tty_ldisc_enable - allow ldisc use
381 * @tty: terminal to activate ldisc on 376 * @tty: terminal to activate ldisc on
@@ -524,31 +519,6 @@ static int tty_ldisc_halt(struct tty_struct *tty)
524} 519}
525 520
526/** 521/**
527 * tty_ldisc_wait_idle - wait for the ldisc to become idle
528 * @tty: tty to wait for
529 *
530 * Wait for the line discipline to become idle. The discipline must
531 * have been halted for this to guarantee it remains idle.
532 *
533 * tty_ldisc_lock protects the ref counts currently.
534 */
535
536static int tty_ldisc_wait_idle(struct tty_struct *tty)
537{
538 unsigned long flags;
539 spin_lock_irqsave(&tty_ldisc_lock, flags);
540 while (tty->ldisc->refcount) {
541 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
542 if (wait_event_timeout(tty_ldisc_wait,
543 tty->ldisc->refcount == 0, 5 * HZ) == 0)
544 return -EBUSY;
545 spin_lock_irqsave(&tty_ldisc_lock, flags);
546 }
547 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
548 return 0;
549}
550
551/**
552 * tty_set_ldisc - set line discipline 522 * tty_set_ldisc - set line discipline
553 * @tty: the terminal to set 523 * @tty: the terminal to set
554 * @ldisc: the line discipline 524 * @ldisc: the line discipline
@@ -643,14 +613,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
643 613
644 flush_scheduled_work(); 614 flush_scheduled_work();
645 615
646 /* Let any existing reference holders finish */
647 retval = tty_ldisc_wait_idle(tty);
648 if (retval < 0) {
649 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
650 tty_ldisc_put(new_ldisc);
651 return retval;
652 }
653
654 mutex_lock(&tty->ldisc_mutex); 616 mutex_lock(&tty->ldisc_mutex);
655 if (test_bit(TTY_HUPPED, &tty->flags)) { 617 if (test_bit(TTY_HUPPED, &tty->flags)) {
656 /* We were raced by the hangup method. It will have stomped 618 /* We were raced by the hangup method. It will have stomped
@@ -791,17 +753,19 @@ void tty_ldisc_hangup(struct tty_struct *tty)
791 * N_TTY. 753 * N_TTY.
792 */ 754 */
793 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { 755 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
794 /* Avoid racing set_ldisc */ 756 /* Avoid racing set_ldisc or tty_ldisc_release */
795 mutex_lock(&tty->ldisc_mutex); 757 mutex_lock(&tty->ldisc_mutex);
796 /* Switch back to N_TTY */ 758 if (tty->ldisc) { /* Not yet closed */
797 tty_ldisc_halt(tty); 759 /* Switch back to N_TTY */
798 tty_ldisc_wait_idle(tty); 760 tty_ldisc_halt(tty);
799 tty_ldisc_reinit(tty); 761 tty_ldisc_reinit(tty);
800 /* At this point we have a closed ldisc and we want to 762 /* At this point we have a closed ldisc and we want to
801 reopen it. We could defer this to the next open but 763 reopen it. We could defer this to the next open but
802 it means auditing a lot of other paths so this is a FIXME */ 764 it means auditing a lot of other paths so this is
803 WARN_ON(tty_ldisc_open(tty, tty->ldisc)); 765 a FIXME */
804 tty_ldisc_enable(tty); 766 WARN_ON(tty_ldisc_open(tty, tty->ldisc));
767 tty_ldisc_enable(tty);
768 }
805 mutex_unlock(&tty->ldisc_mutex); 769 mutex_unlock(&tty->ldisc_mutex);
806 tty_reset_termios(tty); 770 tty_reset_termios(tty);
807 } 771 }
@@ -858,14 +822,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
858 tty_ldisc_halt(tty); 822 tty_ldisc_halt(tty);
859 flush_scheduled_work(); 823 flush_scheduled_work();
860 824
861 /* 825 mutex_lock(&tty->ldisc_mutex);
862 * Wait for any short term users (we know they are just driver
863 * side waiters as the file is closing so user count on the file
864 * side is zero.
865 */
866
867 tty_ldisc_wait_idle(tty);
868
869 /* 826 /*
870 * Now kill off the ldisc 827 * Now kill off the ldisc
871 */ 828 */
@@ -876,6 +833,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
876 833
877 /* Ensure the next open requests the N_TTY ldisc */ 834 /* Ensure the next open requests the N_TTY ldisc */
878 tty_set_termios_ldisc(tty, N_TTY); 835 tty_set_termios_ldisc(tty, N_TTY);
836 mutex_unlock(&tty->ldisc_mutex);
879 837
880 /* This will need doing differently if we need to lock */ 838 /* This will need doing differently if we need to lock */
881 if (o_tty) 839 if (o_tty)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 4e862a75f7ff..9769b1149f76 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -267,7 +267,7 @@ int tty_port_block_til_ready(struct tty_port *port,
267 if (retval == 0) 267 if (retval == 0)
268 port->flags |= ASYNC_NORMAL_ACTIVE; 268 port->flags |= ASYNC_NORMAL_ACTIVE;
269 spin_unlock_irqrestore(&port->lock, flags); 269 spin_unlock_irqrestore(&port->lock, flags);
270 return 0; 270 return retval;
271 271
272} 272}
273EXPORT_SYMBOL(tty_port_block_til_ready); 273EXPORT_SYMBOL(tty_port_block_til_ready);
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index d94d25c12aa8..c1791a63d99d 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -495,11 +495,15 @@ void vcs_remove_sysfs(int index)
495 495
496int __init vcs_init(void) 496int __init vcs_init(void)
497{ 497{
498 unsigned int i;
499
498 if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) 500 if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
499 panic("unable to get major %d for vcs device", VCS_MAJOR); 501 panic("unable to get major %d for vcs device", VCS_MAJOR);
500 vc_class = class_create(THIS_MODULE, "vc"); 502 vc_class = class_create(THIS_MODULE, "vc");
501 503
502 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); 504 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
503 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); 505 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
506 for (i = 0; i < MIN_NR_CONSOLES; i++)
507 vcs_make_sysfs(i);
504 return 0; 508 return 0;
505} 509}
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/drivers/char/vr41xx_giu.c
+++ /dev/null
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index d9113b4c76e3..404f4c1ee431 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -89,6 +89,7 @@
89#include <linux/mutex.h> 89#include <linux/mutex.h>
90#include <linux/vt_kern.h> 90#include <linux/vt_kern.h>
91#include <linux/selection.h> 91#include <linux/selection.h>
92#include <linux/smp_lock.h>
92#include <linux/tiocl.h> 93#include <linux/tiocl.h>
93#include <linux/kbd_kern.h> 94#include <linux/kbd_kern.h>
94#include <linux/consolemap.h> 95#include <linux/consolemap.h>
@@ -769,14 +770,12 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
769 visual_init(vc, currcons, 1); 770 visual_init(vc, currcons, 1);
770 if (!*vc->vc_uni_pagedir_loc) 771 if (!*vc->vc_uni_pagedir_loc)
771 con_set_default_unimap(vc); 772 con_set_default_unimap(vc);
772 if (!vc->vc_kmalloced) 773 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
773 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
774 if (!vc->vc_screenbuf) { 774 if (!vc->vc_screenbuf) {
775 kfree(vc); 775 kfree(vc);
776 vc_cons[currcons].d = NULL; 776 vc_cons[currcons].d = NULL;
777 return -ENOMEM; 777 return -ENOMEM;
778 } 778 }
779 vc->vc_kmalloced = 1;
780 vc_init(vc, vc->vc_rows, vc->vc_cols, 1); 779 vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
781 vcs_make_sysfs(currcons); 780 vcs_make_sysfs(currcons);
782 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param); 781 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
@@ -912,10 +911,8 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
912 if (new_scr_end > new_origin) 911 if (new_scr_end > new_origin)
913 scr_memsetw((void *)new_origin, vc->vc_video_erase_char, 912 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
914 new_scr_end - new_origin); 913 new_scr_end - new_origin);
915 if (vc->vc_kmalloced) 914 kfree(vc->vc_screenbuf);
916 kfree(vc->vc_screenbuf);
917 vc->vc_screenbuf = newscreen; 915 vc->vc_screenbuf = newscreen;
918 vc->vc_kmalloced = 1;
919 vc->vc_screenbuf_size = new_screen_size; 916 vc->vc_screenbuf_size = new_screen_size;
920 set_origin(vc); 917 set_origin(vc);
921 918
@@ -994,8 +991,7 @@ void vc_deallocate(unsigned int currcons)
994 vc->vc_sw->con_deinit(vc); 991 vc->vc_sw->con_deinit(vc);
995 put_pid(vc->vt_pid); 992 put_pid(vc->vt_pid);
996 module_put(vc->vc_sw->owner); 993 module_put(vc->vc_sw->owner);
997 if (vc->vc_kmalloced) 994 kfree(vc->vc_screenbuf);
998 kfree(vc->vc_screenbuf);
999 if (currcons >= MIN_NR_CONSOLES) 995 if (currcons >= MIN_NR_CONSOLES)
1000 kfree(vc); 996 kfree(vc);
1001 vc_cons[currcons].d = NULL; 997 vc_cons[currcons].d = NULL;
@@ -2880,7 +2876,6 @@ static int __init con_init(void)
2880 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); 2876 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
2881 visual_init(vc, currcons, 1); 2877 visual_init(vc, currcons, 1);
2882 vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); 2878 vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
2883 vc->vc_kmalloced = 0;
2884 vc_init(vc, vc->vc_rows, vc->vc_cols, 2879 vc_init(vc, vc->vc_rows, vc->vc_cols,
2885 currcons || !vc->vc_sw->con_save_screen); 2880 currcons || !vc->vc_sw->con_save_screen);
2886 } 2881 }
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 7539bed0f7e0..95189f288f8c 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -25,6 +25,7 @@
25#include <linux/console.h> 25#include <linux/console.h>
26#include <linux/consolemap.h> 26#include <linux/consolemap.h>
27#include <linux/signal.h> 27#include <linux/signal.h>
28#include <linux/smp_lock.h>
28#include <linux/timex.h> 29#include <linux/timex.h>
29 30
30#include <asm/io.h> 31#include <asm/io.h>