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/n_tty.c1
-rw-r--r--drivers/char/pty.c2
-rw-r--r--drivers/char/sysrq.c8
-rw-r--r--drivers/char/tty_buffer.c13
-rw-r--r--drivers/char/tty_ldisc.c152
-rw-r--r--drivers/char/vr41xx_giu.c0
7 files changed, 75 insertions, 103 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/n_tty.c b/drivers/char/n_tty.c
index ff47907ff1bf..973be2f44195 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1583,6 +1583,7 @@ static int n_tty_open(struct tty_struct *tty)
1583 1583
1584static inline int input_available_p(struct tty_struct *tty, int amt) 1584static inline int input_available_p(struct tty_struct *tty, int amt)
1585{ 1585{
1586 tty_flush_to_ldisc(tty);
1586 if (tty->icanon) { 1587 if (tty->icanon) {
1587 if (tty->canon_data) 1588 if (tty->canon_data)
1588 return 1; 1589 return 1;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 6e6942c45f5b..d083c73d784a 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -144,6 +144,8 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf,
144 144
145static int pty_write_room(struct tty_struct *tty) 145static int pty_write_room(struct tty_struct *tty)
146{ 146{
147 if (tty->stopped)
148 return 0;
147 return pty_space(tty->link); 149 return pty_space(tty->link);
148} 150}
149 151
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/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_ldisc.c b/drivers/char/tty_ldisc.c
index acd76b767d4c..1733d3439ad2 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -48,6 +48,41 @@ static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
48/* Line disc dispatch table */ 48/* Line disc dispatch table */
49static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; 49static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
50 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
51/** 86/**
52 * tty_register_ldisc - install a line discipline 87 * tty_register_ldisc - install a line discipline
53 * @disc: ldisc number 88 * @disc: ldisc number
@@ -142,7 +177,7 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
142 /* lock it */ 177 /* lock it */
143 ldops->refcount++; 178 ldops->refcount++;
144 ld->ops = ldops; 179 ld->ops = ldops;
145 ld->refcount = 0; 180 atomic_set(&ld->users, 1);
146 err = 0; 181 err = 0;
147 } 182 }
148 } 183 }
@@ -181,35 +216,6 @@ static struct tty_ldisc *tty_ldisc_get(int disc)
181 return ld; 216 return ld;
182} 217}
183 218
184/**
185 * tty_ldisc_put - drop ldisc reference
186 * @ld: ldisc
187 *
188 * Drop a reference to a line discipline. Manage refcounts and
189 * module usage counts. Free the ldisc once the recount hits zero.
190 *
191 * Locking:
192 * takes tty_ldisc_lock to guard against ldisc races
193 */
194
195static void tty_ldisc_put(struct tty_ldisc *ld)
196{
197 unsigned long flags;
198 int disc = ld->ops->num;
199 struct tty_ldisc_ops *ldo;
200
201 BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
202
203 spin_lock_irqsave(&tty_ldisc_lock, flags);
204 ldo = tty_ldiscs[disc];
205 BUG_ON(ldo->refcount == 0);
206 ldo->refcount--;
207 module_put(ldo->owner);
208 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
209 WARN_ON(ld->refcount);
210 kfree(ld);
211}
212
213static 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)
214{ 220{
215 return (*pos < NR_LDISCS) ? pos : NULL; 221 return (*pos < NR_LDISCS) ? pos : NULL;
@@ -234,7 +240,7 @@ static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
234 if (IS_ERR(ld)) 240 if (IS_ERR(ld))
235 return 0; 241 return 0;
236 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);
237 tty_ldisc_put(ld); 243 put_ldisc(ld);
238 return 0; 244 return 0;
239} 245}
240 246
@@ -288,20 +294,17 @@ static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
288 * Locking: takes tty_ldisc_lock 294 * Locking: takes tty_ldisc_lock
289 */ 295 */
290 296
291static int tty_ldisc_try(struct tty_struct *tty) 297static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty)
292{ 298{
293 unsigned long flags; 299 unsigned long flags;
294 struct tty_ldisc *ld; 300 struct tty_ldisc *ld;
295 int ret = 0;
296 301
297 spin_lock_irqsave(&tty_ldisc_lock, flags); 302 spin_lock_irqsave(&tty_ldisc_lock, flags);
298 ld = tty->ldisc; 303 ld = NULL;
299 if (test_bit(TTY_LDISC, &tty->flags)) { 304 if (test_bit(TTY_LDISC, &tty->flags))
300 ld->refcount++; 305 ld = get_ldisc(tty->ldisc);
301 ret = 1;
302 }
303 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 306 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
304 return ret; 307 return ld;
305} 308}
306 309
307/** 310/**
@@ -322,10 +325,11 @@ static int tty_ldisc_try(struct tty_struct *tty)
322 325
323struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) 326struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
324{ 327{
328 struct tty_ldisc *ld;
329
325 /* wait_event is a macro */ 330 /* wait_event is a macro */
326 wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); 331 wait_event(tty_ldisc_wait, (ld = tty_ldisc_try(tty)) != NULL);
327 WARN_ON(tty->ldisc->refcount == 0); 332 return ld;
328 return tty->ldisc;
329} 333}
330EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); 334EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
331 335
@@ -342,9 +346,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
342 346
343struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) 347struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
344{ 348{
345 if (tty_ldisc_try(tty)) 349 return tty_ldisc_try(tty);
346 return tty->ldisc;
347 return NULL;
348} 350}
349EXPORT_SYMBOL_GPL(tty_ldisc_ref); 351EXPORT_SYMBOL_GPL(tty_ldisc_ref);
350 352
@@ -360,21 +362,15 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref);
360 362
361void tty_ldisc_deref(struct tty_ldisc *ld) 363void tty_ldisc_deref(struct tty_ldisc *ld)
362{ 364{
363 unsigned long flags; 365 put_ldisc(ld);
364
365 BUG_ON(ld == NULL);
366
367 spin_lock_irqsave(&tty_ldisc_lock, flags);
368 if (ld->refcount == 0)
369 printk(KERN_ERR "tty_ldisc_deref: no references.\n");
370 else
371 ld->refcount--;
372 if (ld->refcount == 0)
373 wake_up(&tty_ldisc_wait);
374 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
375} 366}
376EXPORT_SYMBOL_GPL(tty_ldisc_deref); 367EXPORT_SYMBOL_GPL(tty_ldisc_deref);
377 368
369static inline void tty_ldisc_put(struct tty_ldisc *ld)
370{
371 put_ldisc(ld);
372}
373
378/** 374/**
379 * tty_ldisc_enable - allow ldisc use 375 * tty_ldisc_enable - allow ldisc use
380 * @tty: terminal to activate ldisc on 376 * @tty: terminal to activate ldisc on
@@ -523,31 +519,6 @@ static int tty_ldisc_halt(struct tty_struct *tty)
523} 519}
524 520
525/** 521/**
526 * tty_ldisc_wait_idle - wait for the ldisc to become idle
527 * @tty: tty to wait for
528 *
529 * Wait for the line discipline to become idle. The discipline must
530 * have been halted for this to guarantee it remains idle.
531 *
532 * tty_ldisc_lock protects the ref counts currently.
533 */
534
535static int tty_ldisc_wait_idle(struct tty_struct *tty)
536{
537 unsigned long flags;
538 spin_lock_irqsave(&tty_ldisc_lock, flags);
539 while (tty->ldisc->refcount) {
540 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
541 if (wait_event_timeout(tty_ldisc_wait,
542 tty->ldisc->refcount == 0, 5 * HZ) == 0)
543 return -EBUSY;
544 spin_lock_irqsave(&tty_ldisc_lock, flags);
545 }
546 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
547 return 0;
548}
549
550/**
551 * tty_set_ldisc - set line discipline 522 * tty_set_ldisc - set line discipline
552 * @tty: the terminal to set 523 * @tty: the terminal to set
553 * @ldisc: the line discipline 524 * @ldisc: the line discipline
@@ -642,14 +613,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
642 613
643 flush_scheduled_work(); 614 flush_scheduled_work();
644 615
645 /* Let any existing reference holders finish */
646 retval = tty_ldisc_wait_idle(tty);
647 if (retval < 0) {
648 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
649 tty_ldisc_put(new_ldisc);
650 return retval;
651 }
652
653 mutex_lock(&tty->ldisc_mutex); 616 mutex_lock(&tty->ldisc_mutex);
654 if (test_bit(TTY_HUPPED, &tty->flags)) { 617 if (test_bit(TTY_HUPPED, &tty->flags)) {
655 /* We were raced by the hangup method. It will have stomped 618 /* We were raced by the hangup method. It will have stomped
@@ -795,7 +758,6 @@ void tty_ldisc_hangup(struct tty_struct *tty)
795 if (tty->ldisc) { /* Not yet closed */ 758 if (tty->ldisc) { /* Not yet closed */
796 /* Switch back to N_TTY */ 759 /* Switch back to N_TTY */
797 tty_ldisc_halt(tty); 760 tty_ldisc_halt(tty);
798 tty_ldisc_wait_idle(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
@@ -860,14 +822,6 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
860 tty_ldisc_halt(tty); 822 tty_ldisc_halt(tty);
861 flush_scheduled_work(); 823 flush_scheduled_work();
862 824
863 /*
864 * Wait for any short term users (we know they are just driver
865 * side waiters as the file is closing so user count on the file
866 * side is zero.
867 */
868
869 tty_ldisc_wait_idle(tty);
870
871 mutex_lock(&tty->ldisc_mutex); 825 mutex_lock(&tty->ldisc_mutex);
872 /* 826 /*
873 * Now kill off the ldisc 827 * Now kill off the ldisc
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