]> git.pld-linux.org Git - packages/kernel.git/blame - patch-2.2.27-pre2-CAN-2004-0814.patch
- obsolete
[packages/kernel.git] / patch-2.2.27-pre2-CAN-2004-0814.patch
CommitLineData
2cf5f602
KT
1diff -urN linux-2.2.26.orig/drivers/char/cyclades.c linux-2.2.26/drivers/char/cyclades.c
2--- linux-2.2.26.orig/drivers/char/cyclades.c 2001-11-02 17:39:06.000000000 +0100
3+++ linux-2.2.26/drivers/char/cyclades.c 2004-10-25 00:41:47.000000000 +0200
4@@ -1019,10 +1019,7 @@
5 wake_up_interruptible(&info->delta_msr_wait);
6 }
7 if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
8- if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
9- && tty->ldisc.write_wakeup){
10- (tty->ldisc.write_wakeup)(tty);
11- }
12+ tty_wakeup(tty);
13 wake_up_interruptible(&tty->write_wait);
14 wake_up_interruptible(&tty->poll_wait);
15 }
16@@ -2821,6 +2818,7 @@
17 cy_close(struct tty_struct *tty, struct file *filp)
18 {
19 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
20+ struct tty_ldisc *ld;
21 unsigned long flags;
22
23 #ifdef CY_DEBUG_OTHER
24@@ -2938,8 +2936,12 @@
25 shutdown(info);
26 if (tty->driver.flush_buffer)
27 tty->driver.flush_buffer(tty);
28- if (tty->ldisc.flush_buffer)
29- tty->ldisc.flush_buffer(tty);
30+ ld = tty_ldisc_ref(tty);
31+ if (ld) {
32+ if (ld->flush_buffer)
33+ ld->flush_buffer(tty);
34+ tty_ldisc_deref(ld);
35+ }
36 CY_LOCK(info, flags);
37
38 tty->closing = 0;
39@@ -4701,11 +4703,9 @@
40 }
41 CY_UNLOCK(info, flags);
42 }
43+ tty_wakeup(tty);
44 wake_up_interruptible(&tty->write_wait);
45 wake_up_interruptible(&tty->poll_wait);
46- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
47- && tty->ldisc.write_wakeup)
48- (tty->ldisc.write_wakeup)(tty);
49 } /* cy_flush_buffer */
50
51
52diff -urN linux-2.2.26.orig/drivers/char/dz.c linux-2.2.26/drivers/char/dz.c
53--- linux-2.2.26.orig/drivers/char/dz.c 2001-03-25 18:31:27.000000000 +0200
54+++ linux-2.2.26/drivers/char/dz.c 2004-10-31 09:32:57.000000000 +0100
55@@ -1084,10 +1084,10 @@
56 info->event = 0;
57 info->tty = 0;
58
59- if (tty->ldisc.num != ldiscs[N_TTY].num) {
60+ if (tty->ldisc.num != N_TTY) {
61 if (tty->ldisc.close)
62 (tty->ldisc.close)(tty);
63- tty->ldisc = ldiscs[N_TTY];
64+ tty->ldisc = *(tty_ldisc_get(N_TTY));
65 tty->termios->c_line = N_TTY;
66 if (tty->ldisc.open)
67 (tty->ldisc.open)(tty);
68diff -urN linux-2.2.26.orig/drivers/char/epca.c linux-2.2.26/drivers/char/epca.c
69--- linux-2.2.26.orig/drivers/char/epca.c 2001-11-02 17:39:06.000000000 +0100
70+++ linux-2.2.26/drivers/char/epca.c 2004-10-25 00:50:02.000000000 +0200
71@@ -572,7 +572,8 @@
72
73 if ((ch = verifyChannel(tty)) != NULL)
74 { /* Begin if ch != NULL */
75-
76+ struct tty_ldisc *ld;
77+
78 save_flags(flags);
79 cli();
80
81@@ -633,8 +634,12 @@
82 if (tty->driver.flush_buffer)
83 tty->driver.flush_buffer(tty);
84
85- if (tty->ldisc.flush_buffer)
86- tty->ldisc.flush_buffer(tty);
87+ ld = tty_ldisc_ref(tty);
88+ if (ld != NULL) {
89+ if(ld->flush_buffer)
90+ ld->flush_buffer(tty);
91+ tty_ldisc_deref(ld);
92+ }
93
94 shutdown(ch);
95 tty->closing = 0;
96@@ -737,12 +742,20 @@
97 { /* Begin if ch != NULL */
98
99 unsigned long flags;
100-
101+ struct tty_ldisc *ld;
102+
103 save_flags(flags);
104 cli();
105 if (tty->driver.flush_buffer)
106 tty->driver.flush_buffer(tty);
107
108+ ld = tty_ldisc_ref(tty);
109+ if (ld != NULL) {
110+ if (ld->flush_buffer)
111+ ld->flush_buffer(tty);
112+ tty_ldisc_deref(ld);
113+ }
114+
115 if (tty->ldisc.flush_buffer)
116 tty->ldisc.flush_buffer(tty);
117
118@@ -1227,9 +1240,8 @@
119
120 wake_up_interruptible(&tty->write_wait);
121 wake_up_interruptible(&tty->poll_wait);
122- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
123- (tty->ldisc.write_wakeup)(tty);
124-
125+ tty_wakeup(tty);
126+
127 } /* End pc_flush_buffer */
128
129 /* ------------------ Begin pc_flush_chars ---------------------- */
130@@ -2443,9 +2455,7 @@
131 { /* Begin if LOWWAIT */
132
133 ch->statusflags &= ~LOWWAIT;
134- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
135- tty->ldisc.write_wakeup)
136- (tty->ldisc.write_wakeup)(tty);
137+ tty_wakeup(tty);
138 wake_up_interruptible(&tty->write_wait);
139 wake_up_interruptible(&tty->poll_wait);
140 } /* End if LOWWAIT */
141@@ -2462,9 +2472,7 @@
142 { /* Begin if EMPTYWAIT */
143
144 ch->statusflags &= ~EMPTYWAIT;
145- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
146- tty->ldisc.write_wakeup)
147- (tty->ldisc.write_wakeup)(tty);
148+ tty_wakeup(tty);
149
150 wake_up_interruptible(&tty->write_wait);
151 wake_up_interruptible(&tty->poll_wait);
152@@ -3327,6 +3335,7 @@
153 tty_wait_until_sent(tty, 0);
154 }
155 else
156+ /* ldisc lock already held in ioctl */
157 {
158 if (tty->ldisc.flush_buffer)
159 tty->ldisc.flush_buffer(tty);
160diff -urN linux-2.2.26.orig/drivers/char/generic_serial.c linux-2.2.26/drivers/char/generic_serial.c
161--- linux-2.2.26.orig/drivers/char/generic_serial.c 2001-03-25 18:31:27.000000000 +0200
162+++ linux-2.2.26/drivers/char/generic_serial.c 2004-10-31 08:46:56.000000000 +0100
163@@ -453,9 +453,7 @@
164 restore_flags(flags);
165
166 wake_up_interruptible(&tty->write_wait);
167- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
168- tty->ldisc.write_wakeup)
169- (tty->ldisc.write_wakeup)(tty);
170+ tty_wakeup(tty);
171 func_exit ();
172 }
173
174@@ -595,9 +593,7 @@
175 if (!tty) return;
176
177 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
178- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
179- tty->ldisc.write_wakeup)
180- (tty->ldisc.write_wakeup)(tty);
181+ tty_wakeup(tty);
182 wake_up_interruptible(&tty->write_wait);
183 }
184 func_exit ();
185@@ -740,8 +736,9 @@
186 {
187 unsigned long flags;
188 struct gs_port *port;
189-
190- func_enter ();
191+ struct tty_ldisc *ld;
192+
193+ func_enter();
194
195 if (!tty) return;
196
197@@ -818,8 +815,12 @@
198
199 if (tty->driver.flush_buffer)
200 tty->driver.flush_buffer(tty);
201- if (tty->ldisc.flush_buffer)
202- tty->ldisc.flush_buffer(tty);
203+ ld = tty_ldisc_ref(tty);
204+ if (ld != NULL) {
205+ if (ld->flush_buffer)
206+ ld->flush_buffer(tty);
207+ tty_ldisc_deref(ld);
208+ }
209 tty->closing = 0;
210
211 port->event = 0;
212diff -urN linux-2.2.26.orig/drivers/char/isicom.c linux-2.2.26/drivers/char/isicom.c
213--- linux-2.2.26.orig/drivers/char/isicom.c 2001-03-25 18:31:27.000000000 +0200
214+++ linux-2.2.26/drivers/char/isicom.c 2004-10-31 08:56:09.000000000 +0100
215@@ -621,10 +621,8 @@
216
217 if (!tty)
218 return;
219-
220- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
221- tty->ldisc.write_wakeup)
222- (tty->ldisc.write_wakeup)(tty);
223+
224+ tty_wakeup(tty);
225 wake_up_interruptible(&tty->write_wait);
226 }
227
228@@ -1349,7 +1347,8 @@
229 struct isi_port * port = (struct isi_port *) tty->driver_data;
230 struct isi_board * card;
231 unsigned long flags;
232-
233+ struct tty_ldisc *ld;
234+
235 #ifdef ISICOM_DEBUG
236 printk(KERN_DEBUG "ISICOM: Close start!!!.\n");
237 #endif
238@@ -1417,6 +1416,12 @@
239 isicom_shutdown_port(port);
240 if (tty->driver.flush_buffer)
241 tty->driver.flush_buffer(tty);
242+ ld = tty_ldisc_ref(tty);
243+ if (ld != NULL) {
244+ if (ld->flush_buffer)
245+ ld->flush_buffer(tty);
246+ tty_ldisc_deref(ld);
247+ }
248 if (tty->ldisc.flush_buffer)
249 tty->ldisc.flush_buffer(tty);
250
251@@ -1912,9 +1917,7 @@
252 spin_unlock_irqrestore(&card->card_lock, flags);
253
254 wake_up_interruptible(&tty->write_wait);
255- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
256- tty->ldisc.write_wakeup)
257- (tty->ldisc.write_wakeup)(tty);
258+ tty_wakeup(tty);
259 }
260
261
262diff -urN linux-2.2.26.orig/drivers/char/moxa.c linux-2.2.26/drivers/char/moxa.c
263--- linux-2.2.26.orig/drivers/char/moxa.c 2001-11-02 17:39:06.000000000 +0100
264+++ linux-2.2.26/drivers/char/moxa.c 2004-10-31 09:02:00.000000000 +0100
265@@ -616,6 +616,7 @@
266 {
267 struct moxa_str *ch;
268 int port;
269+ struct tty_ldisc *ld;
270
271 port = PORTNO(tty);
272 if (port == MAX_PORTS) {
273@@ -673,8 +674,13 @@
274
275 if (tty->driver.flush_buffer)
276 tty->driver.flush_buffer(tty);
277- if (tty->ldisc.flush_buffer)
278- tty->ldisc.flush_buffer(tty);
279+
280+ ld = tty_ldisc_ref(tty);
281+ if (ld != NULL) {
282+ if (ld->flush_buffer)
283+ ld->flush_buffer(tty);
284+ tty_ldisc_deref(ld);
285+ }
286 tty->closing = 0;
287 ch->event = 0;
288 ch->tty = 0;
289@@ -750,9 +756,7 @@
290 if (ch == NULL)
291 return;
292 MoxaPortFlushData(ch->port, 1);
293- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
294- tty->ldisc.write_wakeup)
295- (tty->ldisc.write_wakeup) (tty);
296+ tty_wakeup(tty);
297 wake_up_interruptible(&tty->write_wait);
298 wake_up_interruptible(&tty->poll_wait);
299 }
300@@ -989,7 +993,6 @@
301 moxaTimer.function = moxa_poll;
302 moxaTimer.expires = jiffies + (HZ / 50);
303 moxaTimer_on = 1;
304- add_timer(&moxaTimer);
305 return;
306 }
307 for (card = 0; card < MAX_BOARDS; card++) {
308@@ -1008,9 +1011,7 @@
309 if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
310 if (!tp->stopped) {
311 ch->statusflags &= ~LOWWAIT;
312- if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
313- tp->ldisc.write_wakeup)
314- (tp->ldisc.write_wakeup) (tp);
315+ tty_wakeup(tp);
316 wake_up_interruptible(&tp->write_wait);
317 wake_up_interruptible(&tp->poll_wait);
318 }
319@@ -1199,9 +1200,7 @@
320 if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
321 if (MoxaPortTxQueue(ch->port) == 0) {
322 ch->statusflags &= ~EMPTYWAIT;
323- if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
324- ch->tty->ldisc.write_wakeup)
325- (ch->tty->ldisc.write_wakeup) (ch->tty);
326+ tty_wakeup(ch->tty);
327 wake_up_interruptible(&ch->tty->write_wait);
328 wake_up_interruptible(&ch->tty->poll_wait);
329 return;
330diff -urN linux-2.2.26.orig/drivers/char/mxser.c linux-2.2.26/drivers/char/mxser.c
331--- linux-2.2.26.orig/drivers/char/mxser.c 2001-03-25 18:31:28.000000000 +0200
332+++ linux-2.2.26/drivers/char/mxser.c 2004-10-31 09:06:54.000000000 +0100
333@@ -712,9 +712,7 @@
334 if (!tty)
335 return;
336 if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) {
337- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
338- tty->ldisc.write_wakeup)
339- (tty->ldisc.write_wakeup) (tty);
340+ tty_wakeup(tty);
341 wake_up_interruptible(&tty->write_wait);
342 wake_up_interruptible(&tty->poll_wait);
343 }
344@@ -796,6 +794,7 @@
345 struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
346 unsigned long flags;
347 unsigned long timeout;
348+ struct tty_ldisc *ld;
349
350 if (PORTNO(tty) == MXSER_PORTS)
351 return;
352@@ -876,6 +875,12 @@
353 mxser_shutdown(info);
354 if (tty->driver.flush_buffer)
355 tty->driver.flush_buffer(tty);
356+ ld = tty_ldisc_ref(tty);
357+ if (ld) {
358+ if (ld->flush_buffer)
359+ ld->flush_buffer(tty);
360+ tty_ldisc_deref(ld);
361+ }
362 if (tty->ldisc.flush_buffer)
363 tty->ldisc.flush_buffer(tty);
364 tty->closing = 0;
365@@ -1013,9 +1018,7 @@
366 restore_flags(flags);
367 wake_up_interruptible(&tty->write_wait);
368 wake_up_interruptible(&tty->poll_wait);
369- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
370- tty->ldisc.write_wakeup)
371- (tty->ldisc.write_wakeup) (tty);
372+ tty_wakeup(tty);
373 }
374
375 static int mxser_ioctl(struct tty_struct *tty, struct file *file,
376diff -urN linux-2.2.26.orig/drivers/char/n_tty.c linux-2.2.26/drivers/char/n_tty.c
377--- linux-2.2.26.orig/drivers/char/n_tty.c 2001-03-25 18:31:25.000000000 +0200
378+++ linux-2.2.26/drivers/char/n_tty.c 2004-10-31 13:27:14.177336648 +0100
379@@ -78,11 +78,18 @@
380 spin_unlock_irqrestore(&tty->read_lock, flags);
381 }
382
383-/*
384+/*
385+ * check_unthrottle - allow new receive data
386+ * @tty; tty device
387+ *
388 * Check whether to call the driver.unthrottle function.
389 * We test the TTY_THROTTLED bit first so that it always
390- * indicates the current state.
391- */
392+ * indicates the current state. The decision about whether
393+ * it is worth allowing more input has been taken by the caller.
394+ * Can sleep, may be called under the atomic_read semaphore but
395+ * this is not guaranteed.
396+*/
397+
398 static void check_unthrottle(struct tty_struct * tty)
399 {
400 if (tty->count &&
401@@ -92,10 +99,14 @@
402 }
403
404 /*
405+ * reset_buffer_flags - reset buffer state
406+ * @tty: terminal to reset
407+ *
408 * Reset the read buffer counters, clear the flags,
409 * and make sure the driver is unthrottled. Called
410 * from n_tty_open() and n_tty_flush_buffer().
411 */
412+
413 static void reset_buffer_flags(struct tty_struct *tty)
414 {
415 unsigned long flags;
416@@ -109,8 +120,18 @@
417 }
418
419 /*
420- * Flush the input buffer
421+ * n_tty_flush_buffer - clean input queue
422+ * @tty: terminal device
423+ *
424+ * Flush the input buffer. Called when the line discipline is
425+ * being closed, when the tty layer wants the buffer flushed (eg
426+ * at hangup) or when the N_TTY line discipline internally has to
427+ * clean the pending queue (for example some signals).
428+ *
429+ * FIXME: tty->ctrl_status is not spinlocked and relies on
430+ * lock_kernel() still.
431 */
432+
433 void n_tty_flush_buffer(struct tty_struct * tty)
434 {
435 /* clear everything and unthrottle the driver */
436@@ -127,8 +148,13 @@
437 }
438
439 /*
440- * Return number of characters buffered to be delivered to user
441+ * n_tty_chars_in_buffer - report available bytes
442+ * @tty: tty device
443+ *
444+ * Report the number of characters buffered to be delivered to user
445+ * at this instant in time.
446 */
447+
448 ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
449 {
450 unsigned long flags;
451@@ -210,9 +236,19 @@
452 }
453
454 /*
455- * opost_block --- to speed up block console writes, among other
456- * things.
457+ * opost_block - block postprocess
458+ * @tty: terminal device
459+ * @inbuf: user buffer
460+ * @nr: number of bytes
461+ *
462+ * This path is used to speed up block console writes, among other
463+ * things when processing blocks of output data. It handles only
464+ * the simple cases normally found and helps to generate blocks of
465+ * symbols for the console driver and thus improve performance.
466+ *
467+ * Called from write_chan under the tty layer write lock.
468 */
469+
470 static ssize_t opost_block(struct tty_struct * tty,
471 const unsigned char * inbuf, unsigned int nr)
472 {
473@@ -301,6 +337,16 @@
474 }
475 }
476
477+/*
478+ * eraser - handle erase function
479+ * @c: character input
480+ * @tty: terminal device
481+ *
482+ * Perform erase and neccessary output when an erase character is
483+ * present in the stream from the driver layer. Handles the complexities
484+ * of UTF-8 multibyte symbols.
485+ */
486+
487 static void eraser(unsigned char c, struct tty_struct *tty)
488 {
489 enum { ERASE, WERASE, KILL } kill_type;
490@@ -417,6 +463,18 @@
491 finish_erasing(tty);
492 }
493
494+/*
495+ * isig - handle the ISIG optio
496+ * @sig: signal
497+ * @tty: terminal
498+ * @flush: force flush
499+ *
500+ * Called when a signal is being sent due to terminal input. This
501+ * may caus terminal flushing to take place according to the termios
502+ * settings and character used. Called from the driver receive_buf
503+ * path so serialized.
504+ */
505+
506 static inline void isig(int sig, struct tty_struct *tty, int flush)
507 {
508 if (tty->pgrp > 0)
509@@ -428,6 +486,16 @@
510 }
511 }
512
513+/*
514+ * n_tty_receive_break - handle break
515+ * @tty: terminal
516+ *
517+ * An RS232 break event has been hit in the incoming bitstream. This
518+ * can cause a variety of events depending upon the termios settings.
519+ *
520+ * Called from the receive_buf path so single threaded.
521+ */
522+
523 static inline void n_tty_receive_break(struct tty_struct *tty)
524 {
525 if (I_IGNBRK(tty))
526@@ -445,19 +513,41 @@
527 wake_up_interruptible(&tty->poll_wait);
528 }
529
530+/*
531+ * n_tty_receive_overrun - handle overrun reporting
532+ * @tty: terminal
533+ *
534+ * Data arrived faster than we could process it. While the tty
535+ * driver has flagged this the bits that were missed are gone
536+ * forever.
537+ *
538+ * Called from the receive_buf path so single threaded. Does not
539+ * need locking as num_overrun and overrun_time are function
540+ * private.
541+ */
542+
543 static inline void n_tty_receive_overrun(struct tty_struct *tty)
544 {
545 char buf[64];
546
547 tty->num_overrun++;
548 if (time_before(tty->overrun_time, jiffies - HZ)) {
549- printk("%s: %d input overrun(s)\n", tty_name(tty, buf),
550+ printk(KERN_WARNING "%s: %d input overrun(s)\n", tty_name(tty, buf),
551 tty->num_overrun);
552 tty->overrun_time = jiffies;
553 tty->num_overrun = 0;
554 }
555 }
556
557+/*
558+ * n_tty_receive_parity_error - error notifier
559+ * @tty: terminal device
560+ * @c: character
561+ *
562+ * Process a parity error and queue the right data to indicate
563+ * the error case if neccessary. Locking as per n_tty_receive_buf.
564+ */
565+
566 static inline void n_tty_receive_parity_error(struct tty_struct *tty,
567 unsigned char c)
568 {
569@@ -476,6 +566,16 @@
570 wake_up_interruptible(&tty->poll_wait);
571 }
572
573+/*
574+ * n_tty_receive_char - perform processing
575+ * @tty: terminal device
576+ * @c: character
577+ *
578+ * Process an individual character of input received from the driver.
579+ * This is serialized with respect to itself by the rules for the
580+ * driver above.
581+ */
582+
583 static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
584 {
585 if (tty->raw) {
586@@ -667,6 +767,16 @@
587 put_tty_queue(c, tty);
588 }
589
590+/*
591+ * n_tty_receive_room - receive space
592+ * @tty: terminal
593+ *
594+ * Called by the driver to find out how much data it is
595+ * permitted to feed to the line discipline without any being lost
596+ * and thus to manage flow control. Not serialized. Answers for the
597+ * "instant".
598+ */
599+
600 static int n_tty_receive_room(struct tty_struct *tty)
601 {
602 int left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
603@@ -685,6 +795,19 @@
604 return 0;
605 }
606
607+/*
608+ * n_tty_receive_buf - data receive
609+ * @tty: terminal device
610+ * @cp: buffer
611+ * @fp: flag buffer
612+ * @count: characters
613+ *
614+ * Called by the terminal driver when a block of characters has
615+ * been received. This function must be called from soft contexts
616+ * not from interrupt context. The driver is responsible for making
617+ * calls one at a time and in order (or using queue_ldisc)
618+ */
619+
620 static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
621 char *fp, int count)
622 {
623@@ -770,6 +893,18 @@
624 current->sig->action[sig-1].sa.sa_handler == SIG_IGN);
625 }
626
627+/*
628+ * n_tty_set_termios - termios data changed
629+ * @tty: terminal
630+ * @old: previous data
631+ *
632+ * Called by the tty layer when the user changes termios flags so
633+ * that the line discipline can plan ahead. This function cannot sleep
634+ * and is protected from re-entry by the tty layer. The user is
635+ * guaranteed that this function will not be re-entered or in progress
636+ * when the ldisc is closed.
637+ */
638+
639 static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
640 {
641 if (!tty)
642@@ -785,7 +920,6 @@
643 I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
644 I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
645 I_PARMRK(tty)) {
646- cli();
647 memset(tty->process_char_map, 0, 256/8);
648
649 if (I_IGNCR(tty) || I_ICRNL(tty))
650@@ -821,7 +955,6 @@
651 set_bit(SUSP_CHAR(tty), &tty->process_char_map);
652 }
653 clear_bit(__DISABLED_CHAR, &tty->process_char_map);
654- sti();
655 tty->raw = 0;
656 tty->real_raw = 0;
657 } else {
658@@ -835,6 +968,16 @@
659 }
660 }
661
662+/*
663+ * n_tty_close - close the ldisc for this tty
664+ * @tty: device
665+ *
666+ * Called from the terminal layer when this line discipline is
667+ * being shut down, either because of a close or becsuse of a
668+ * discipline change. The function will not be called while other
669+ * ldisc methods are in progress.
670+ */
671+
672 static void n_tty_close(struct tty_struct *tty)
673 {
674 n_tty_flush_buffer(tty);
675@@ -844,6 +987,16 @@
676 }
677 }
678
679+/*
680+ * n_tty_open - open an ldisc
681+ * @tty: terminal to open
682+ *
683+ * Called when this line discipline is being attached to the
684+ * terminal device. Can sleep. Called serialized so that no
685+ * other events will occur in parallel. No further open will occur
686+ * until a close.
687+ */
688+
689 static int n_tty_open(struct tty_struct *tty)
690 {
691 if (!tty)
692@@ -876,13 +1029,22 @@
693 }
694
695 /*
696- * Helper function to speed up read_chan. It is only called when
697+ * copy_from_read_buf - copy read data directly
698+ * @tty: terminal device
699+ * @b: user data
700+ * @nr: size of data
701+ *
702+ * Helper function to speed up read_chan. It is only called when
703 * ICANON is off; it copies characters straight from the tty queue to
704- * user space directly. It can be profitably called twice; once to
705+ * user space directly. It can be profitably called twice; once to
706 * drain the space from the tail pointer to the (physical) end of the
707 * buffer, and once to drain the space from the (physical) beginning of
708 * the buffer to head pointer.
709+ *
710+ * Called under the tty->atomic_read sem and with TTY_DONT_FLIP set
711+ *
712 */
713+
714 static inline int copy_from_read_buf(struct tty_struct *tty,
715 unsigned char **b,
716 size_t *nr)
717@@ -910,25 +1072,18 @@
718 return retval;
719 }
720
721-static ssize_t read_chan(struct tty_struct *tty, struct file *file,
722- unsigned char *buf, size_t nr)
723+/**
724+ * job_control - check job control
725+ * @tty: tty
726+ * @file: file handle
727+ *
728+ * Perform job control management checks on this file/tty descriptor
729+ * and if appropriate send any needed signals and return a negative
730+ * error code if action should be taken.
731+*/
732+
733+static int job_control(struct tty_struct *tty, struct file *file)
734 {
735- unsigned char *b = buf;
736- struct wait_queue wait = { current, NULL };
737- int c;
738- int minimum, time;
739- ssize_t retval = 0;
740- ssize_t size;
741- long timeout;
742- unsigned long flags;
743-
744-do_it_again:
745-
746- if (!tty->read_buf) {
747- printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
748- return -EIO;
749- }
750-
751 /* Job control check -- must be done at start and after
752 every sleep (POSIX.1 7.1.1.4). */
753 /* NOTE: not yet done after every sleep pending a thorough
754@@ -947,7 +1102,48 @@
755 return -ERESTARTSYS;
756 }
757 }
758+return 0;
759+
760+}
761+
762+/**
763+ * read_chan - read function for tty
764+ * @tty: tty device
765+ * @file: file object
766+ * @buf: userspace buffer pointer
767+ * @nr: size of I/O
768+ *
769+ * Perform reads for the line discipline. We are guaranteed that the
770+ * line discipline will not be closed under us but we may get multiple
771+ * parallel readers and must handle this ourselves. We may also get
772+ * a hangup. Always called in user context, may sleep.
773+ *
774+ * This code must be sure never to sleep through a hangup.
775+ */
776+
777+static ssize_t read_chan(struct tty_struct *tty, struct file *file,
778+ unsigned char *buf, size_t nr)
779+{
780+ unsigned char *b = buf;
781+ DECLARE_WAITQUEUE(wait, current);
782+ int c;
783+ int minimum, time;
784+ ssize_t retval = 0;
785+ ssize_t size;
786+ long timeout;
787+ unsigned long flags;
788
789+ do_it_again:
790+
791+ if (!tty->read_buf) {
792+ printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
793+ return -EIO;
794+ }
795+
796+ c = job_control(tty, file);
797+ if(c < 0)
798+ return c;
799+
800 minimum = time = 0;
801 timeout = MAX_SCHEDULE_TIMEOUT;
802 if (!tty->icanon) {
803@@ -969,6 +1165,9 @@
804 }
805 }
806
807+ /*
808+ * Internal serialization of reads.
809+ */
810 if (file->f_flags & O_NONBLOCK) {
811 if (down_trylock(&tty->atomic_read))
812 return -EAGAIN;
813@@ -1103,6 +1302,21 @@
814 return retval;
815 }
816
817+/*
818+ * write_chan - write function for tty
819+ * @tty: tty device
820+ * @file: file object
821+ * @buf: userspace buffer pointer
822+ * @nr: size of I/O
823+ *
824+ * Write function of the terminal device. This is serialized with
825+ * respect to other write callers but not to termios changes, reads
826+ * and other such events. We must be careful with N_TTY as the receive
827+ * code will echo characters, thus calling driver write methods.
828+ *
829+ * This code must be sure never to sleep through a hangup.
830+ */
831+
832 static ssize_t write_chan(struct tty_struct * tty, struct file * file,
833 const unsigned char * buf, size_t nr)
834 {
835@@ -1172,6 +1386,25 @@
836 return (b - buf) ? b - buf : retval;
837 }
838
839+/*
840+ * normal_poll - poll method for N_TTY
841+ * @tty: terminal device
842+ * @file: file accessing it
843+ * @wait: poll table
844+ *
845+ * Called when the line discipline is asked to poll() for data or
846+ * for special events. This code is not serialized with respect to
847+ * other events save open/close.
848+ *
849+ * This code must be sure never to sleep through a hangup.
850+ * Called without the kernel lock held - fine
851+ *
852+ * FIXME: if someone changes the VMIN or discipline settings for the
853+ * terminal while another process is in poll() the poll does not
854+ * recompute the new limits. Possibly set_termios should issue
855+ * a read wakeup to fix this bug.
856+ */
857+
858 static unsigned int normal_poll(struct tty_struct * tty, struct file * file, poll_table *wait)
859 {
860 unsigned int mask = 0;
861diff -urN linux-2.2.26.orig/drivers/char/pcxx.c linux-2.2.26/drivers/char/pcxx.c
862--- linux-2.2.26.orig/drivers/char/pcxx.c 2001-03-25 18:31:25.000000000 +0200
863+++ linux-2.2.26/drivers/char/pcxx.c 2004-10-31 09:34:16.000000000 +0100
864@@ -621,10 +621,10 @@
865 ** please send me a note. brian@ilinx.com
866 ** Don't know either what this is supposed to do clameter@waterf.org.
867 */
868- if(tty->ldisc.num != ldiscs[N_TTY].num) {
869+ if(tty->ldisc.num != N_TTY) {
870 if(tty->ldisc.close)
871 (tty->ldisc.close)(tty);
872- tty->ldisc = ldiscs[N_TTY];
873+ tty->ldisc = *(tty_ldisc_get(N_TTY));
874 tty->termios->c_line = N_TTY;
875 if(tty->ldisc.open)
876 (tty->ldisc.open)(tty);
877diff -urN linux-2.2.26.orig/drivers/char/pty.c linux-2.2.26/drivers/char/pty.c
878--- linux-2.2.26.orig/drivers/char/pty.c 2001-03-25 18:31:24.000000000 +0200
879+++ linux-2.2.26/drivers/char/pty.c 2004-10-31 09:17:13.000000000 +0100
880@@ -134,6 +134,10 @@
881 * (2) avoid redundant copying for cases where count >> receive_room
882 * N.B. Calls from user space may now return an error code instead of
883 * a count.
884+ *
885+ * FIXME: Our pty_write method is called with our ldisc lock held but
886+ * not our partners. We can't just take the other one blindly without
887+ + * risking deadlocks. There is also the small matter of TTY_DONT_FLIP
888 */
889 static int pty_write(struct tty_struct * tty, int from_user,
890 const unsigned char *buf, int count)
891diff -urN linux-2.2.26.orig/drivers/char/riscom8.c linux-2.2.26/drivers/char/riscom8.c
892--- linux-2.2.26.orig/drivers/char/riscom8.c 2001-11-02 17:39:06.000000000 +0100
893+++ linux-2.2.26/drivers/char/riscom8.c 2004-10-31 09:21:17.000000000 +0100
894@@ -1110,7 +1110,8 @@
895 struct riscom_board *bp;
896 unsigned long flags;
897 unsigned long timeout;
898-
899+ struct tty_ldisc *ld;
900+
901 if (!port || rc_paranoia_check(port, tty->device, "close"))
902 return;
903
904@@ -1180,6 +1181,12 @@
905 rc_shutdown_port(bp, port);
906 if (tty->driver.flush_buffer)
907 tty->driver.flush_buffer(tty);
908+ ld = tty_ldisc_ref(tty);
909+ if (ld != NULL) {
910+ if(ld->flush_buffer)
911+ ld->flush_buffer(tty);
912+ tty_ldisc_deref(ld);
913+ }
914 if (tty->ldisc.flush_buffer)
915 tty->ldisc.flush_buffer(tty);
916 tty->closing = 0;
917@@ -1358,9 +1365,7 @@
918
919 wake_up_interruptible(&tty->write_wait);
920 wake_up_interruptible(&tty->poll_wait);
921- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
922- tty->ldisc.write_wakeup)
923- (tty->ldisc.write_wakeup)(tty);
924+ tty_wakeup(tty);
925 }
926
927 static int rc_get_modem_info(struct riscom_port * port, unsigned int *value)
928@@ -1736,9 +1741,7 @@
929 return;
930
931 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
932- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
933- tty->ldisc.write_wakeup)
934- (tty->ldisc.write_wakeup)(tty);
935+ tty_wakeup(tty);
936 wake_up_interruptible(&tty->write_wait);
937 wake_up_interruptible(&tty->poll_wait);
938 }
939diff -urN linux-2.2.26.orig/drivers/char/selection.c linux-2.2.26/drivers/char/selection.c
940--- linux-2.2.26.orig/drivers/char/selection.c 2001-03-25 18:31:25.000000000 +0200
941+++ linux-2.2.26/drivers/char/selection.c 2004-10-31 09:22:38.000000000 +0100
942@@ -296,9 +296,11 @@
943 {
944 struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
945 int pasted = 0, count;
946+ struct tty_ldisc *ld;
947 struct wait_queue wait = { current, NULL };
948
949 poke_blanked_console();
950+ ld = tty_ldisc_ref_wait(tty);
951 add_wait_queue(&vt->paste_wait, &wait);
952 while (sel_buffer && sel_buffer_lth > pasted) {
953 current->state = TASK_INTERRUPTIBLE;
954@@ -313,6 +315,8 @@
955 }
956 remove_wait_queue(&vt->paste_wait, &wait);
957 current->state = TASK_RUNNING;
958+
959+ tty_ldisc_deref(ld);
960 return 0;
961 }
962
963diff -urN linux-2.2.26.orig/drivers/char/serial167.c linux-2.2.26/drivers/char/serial167.c
964--- linux-2.2.26.orig/drivers/char/serial167.c 2001-03-25 18:31:26.000000000 +0200
965+++ linux-2.2.26/drivers/char/serial167.c 2004-10-31 09:36:07.000000000 +0100
966@@ -1943,10 +1943,10 @@
967 tty->ldisc.flush_buffer(tty);
968 info->event = 0;
969 info->tty = 0;
970- if (tty->ldisc.num != ldiscs[N_TTY].num) {
971+ if (tty->ldisc.num != N_TTY) {
972 if (tty->ldisc.close)
973 (tty->ldisc.close)(tty);
974- tty->ldisc = ldiscs[N_TTY];
975+ tty->ldisc = *(tty_ldisc_get(N_TTY));
976 tty->termios->c_line = N_TTY;
977 if (tty->ldisc.open)
978 (tty->ldisc.open)(tty);
979diff -urN linux-2.2.26.orig/drivers/char/synclink.c linux-2.2.26/drivers/char/synclink.c
980--- linux-2.2.26.orig/drivers/char/synclink.c 2001-11-02 17:39:06.000000000 +0100
981+++ linux-2.2.26/drivers/char/synclink.c 2004-10-31 09:30:48.000000000 +0100
982@@ -990,6 +990,42 @@
983 return 0;
984 }
985
986+/**
987+ * line discipline callback wrappers
988+ *
989+ * The wrappers maintain line discipline references
990+ * while calling into the line discipline.
991+ *
992+ * ldisc_flush_buffer - flush line discipline receive buffers
993+ * ldisc_receive_buf - pass receive data to line discipline
994+ */
995+
996+static void ldisc_flush_buffer(struct tty_struct *tty)
997+{
998+ struct tty_ldisc *ld = tty_ldisc_ref(tty);
999+
1000+ if (ld) {
1001+ if (ld->flush_buffer)
1002+ ld->flush_buffer(tty);
1003+ tty_ldisc_deref(ld);
1004+ }
1005+}
1006+
1007+static void ldisc_receive_buf(struct tty_struct *tty,
1008+ const __u8 *data, char *flags, int count)
1009+{
1010+ struct tty_ldisc *ld;
1011+
1012+ if (!tty)
1013+ return;
1014+ ld = tty_ldisc_ref(tty);
1015+ if (ld) {
1016+ if (ld->receive_buf)
1017+ ld->receive_buf(tty, data, flags, count);
1018+ tty_ldisc_deref(ld);
1019+ }
1020+}
1021+
1022 /* mgsl_stop() throttle (stop) transmitter
1023 *
1024 * Arguments: tty pointer to tty info structure
1025@@ -1141,13 +1177,7 @@
1026 __FILE__,__LINE__,info->device_name);
1027
1028 if (tty) {
1029- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1030- tty->ldisc.write_wakeup) {
1031- if ( debug_level >= DEBUG_LEVEL_BH )
1032- printk( "%s(%d):calling ldisc.write_wakeup on %s\n",
1033- __FILE__,__LINE__,info->device_name);
1034- (tty->ldisc.write_wakeup)(tty);
1035- }
1036+ tty_wakeup(tty);
1037 wake_up_interruptible(&tty->write_wait);
1038 }
1039
1040@@ -2392,11 +2422,8 @@
1041 spin_unlock_irqrestore(&info->irq_spinlock,flags);
1042
1043 wake_up_interruptible(&tty->write_wait);
1044- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1045- tty->ldisc.write_wakeup)
1046- (tty->ldisc.write_wakeup)(tty);
1047-
1048-} /* end of mgsl_flush_buffer() */
1049+ tty_wakeup(tty);
1050+}
1051
1052 /* mgsl_send_xchar()
1053 *
1054@@ -3297,10 +3324,8 @@
1055
1056 if (tty->driver.flush_buffer)
1057 tty->driver.flush_buffer(tty);
1058-
1059- if (tty->ldisc.flush_buffer)
1060- tty->ldisc.flush_buffer(tty);
1061-
1062+
1063+ ldisc_flush_buffer(tty);
1064 shutdown(info);
1065
1066 tty->closing = 0;
1067@@ -6999,11 +7024,7 @@
1068 }
1069 else
1070 #endif
1071- {
1072- /* Call the line discipline receive callback directly. */
1073- if ( tty && tty->ldisc.receive_buf )
1074- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
1075- }
1076+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
1077 }
1078 }
1079 /* Free the buffers used by this frame. */
1080@@ -7175,9 +7196,7 @@
1081 memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize);
1082 info->icount.rxok++;
1083
1084- /* Call the line discipline receive callback directly. */
1085- if ( tty && tty->ldisc.receive_buf )
1086- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
1087+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
1088 }
1089
1090 /* Free the buffers used by this frame. */
1091diff -urN linux-2.2.26.orig/drivers/char/tty_io.c linux-2.2.26/drivers/char/tty_io.c
1092--- linux-2.2.26.orig/drivers/char/tty_io.c 2004-10-31 11:15:19.128606952 +0100
1093+++ linux-2.2.26/drivers/char/tty_io.c 2004-10-31 12:02:45.000000000 +0100
1094@@ -101,9 +101,13 @@
1095 #define TTY_PARANOIA_CHECK 1
1096 #define CHECK_TTY_COUNT 1
1097
1098+#define __builtin_expect(x, expected_value) (x)
1099+#define likely(x) __builtin_expect((x),1)
1100+
1101+/* Lock for tty_termios changes - private to tty_io/tty_ioctl */
1102+spinlock_t tty_termios_lock = SPIN_LOCK_UNLOCKED;
1103 struct termios tty_std_termios; /* for the benefit of tty drivers */
1104 struct tty_driver *tty_drivers = NULL; /* linked list of tty drivers */
1105-struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */
1106
1107 #ifdef CONFIG_UNIX98_PTYS
1108 extern struct tty_driver ptm_driver[]; /* Unix98 pty masters; for /dev/ptmx */
1109@@ -204,44 +208,256 @@
1110 return 0;
1111 }
1112
1113+/*
1114+ * This is probably overkill for real world processors but
1115+ * they are not on hot paths so a little discipline won't do
1116+ * any harm.
1117+ */
1118+
1119+static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
1120+{
1121+ unsigned long flags;
1122+ spin_lock_irqsave(&tty_termios_lock, flags);
1123+ tty->termios->c_line = num;
1124+ spin_unlock_irqrestore(&tty_termios_lock, flags);
1125+}
1126+
1127+/*
1128+ * This guards the refcounted line discipline lists. The lock
1129+ * must be taken with irqs off because there are hangup path
1130+ * callers who will do ldisc lookups and cannot sleep.
1131+ */
1132+
1133+spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED;
1134+DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
1135+struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */
1136+
1137 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
1138 {
1139+
1140+ unsigned long flags;
1141+ int ret = 0;
1142+
1143 if (disc < N_TTY || disc >= NR_LDISCS)
1144 return -EINVAL;
1145-
1146+
1147+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1148 if (new_ldisc) {
1149- ldiscs[disc] = *new_ldisc;
1150- ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
1151- ldiscs[disc].num = disc;
1152- } else
1153- memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
1154+ tty_ldiscs[disc] = *new_ldisc;
1155+ tty_ldiscs[disc].num = disc;
1156+ tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
1157+ tty_ldiscs[disc].refcount = 0;
1158+ } else {
1159+ if(tty_ldiscs[disc].refcount)
1160+ ret = -EBUSY;
1161+ else
1162+ tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
1163+ }
1164+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1165
1166- return 0;
1167+ return ret;
1168 }
1169
1170-/* Set the discipline of a tty line. */
1171+EXPORT_SYMBOL(tty_register_ldisc);
1172+
1173+struct tty_ldisc *tty_ldisc_get(int disc)
1174+{
1175+ unsigned long flags;
1176+ struct tty_ldisc *ld;
1177+
1178+ if (disc < N_TTY || disc >= NR_LDISCS)
1179+ return NULL;
1180+
1181+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1182+
1183+ ld = &tty_ldiscs[disc];
1184+ /* Check the entry is defined */
1185+ if(ld->flags & LDISC_FLAG_DEFINED)
1186+ ld->refcount++;
1187+ else
1188+ ld = NULL;
1189+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1190+ return ld;
1191+}
1192+
1193+EXPORT_SYMBOL_GPL(tty_ldisc_get);
1194+
1195+void tty_ldisc_put(int disc)
1196+{
1197+ struct tty_ldisc *ld;
1198+ unsigned long flags;
1199+
1200+ if (disc < N_TTY || disc >= NR_LDISCS)
1201+ BUG();
1202+
1203+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1204+ ld = &tty_ldiscs[disc];
1205+ if(ld->refcount <= 0)
1206+ BUG();
1207+ ld->refcount--;
1208+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1209+}
1210+
1211+EXPORT_SYMBOL_GPL(tty_ldisc_put);
1212+
1213+void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
1214+{
1215+ tty->ldisc = *ld;
1216+ tty->ldisc.refcount = 0;
1217+}
1218+
1219+/**
1220+ * tty_ldisc_try - internal helper
1221+ * @tty: the tty
1222+ *
1223+ * Make a single attempt to grab and bump the refcount on
1224+ * the tty ldisc. Return 0 on failure or 1 on success. This is
1225+ * used to implement both the waiting and non waiting versions
1226+ * of tty_ldisc_ref
1227+ */
1228+
1229+static int tty_ldisc_try(struct tty_struct *tty)
1230+{
1231+ unsigned long flags;
1232+ struct tty_ldisc *ld;
1233+ int ret = 0;
1234+
1235+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1236+ ld = &tty->ldisc;
1237+ if(test_bit(TTY_LDISC, &tty->flags)) {
1238+ ld->refcount++;
1239+ ret = 1;
1240+ }
1241+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1242+ return ret;
1243+}
1244+
1245+/**
1246+ * tty_ldisc_ref_wait - wait for the tty ldisc
1247+ * @tty: tty device
1248+ *
1249+ * Dereference the line discipline for the terminal and take a
1250+ * reference to it. If the line discipline is in flux then
1251+ * wait patiently until it changes.
1252+ *
1253+ * Note: Must not be called from an IRQ/timer context. The caller
1254+ * must also be careful not to hold other locks that will deadlock
1255+ * against a discipline change, such as an existing ldisc reference
1256+ * (which we check for)
1257+ */
1258+
1259+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
1260+{
1261+ /* wait_event is a macro */
1262+ wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
1263+ return &tty->ldisc;
1264+}
1265+
1266+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
1267+
1268+/**
1269+ * tty_ldisc_ref - get the tty ldisc
1270+ * @tty: tty device
1271+ *
1272+ * Dereference the line discipline for the terminal and take a
1273+ * reference to it. If the line discipline is in flux then
1274+ * return NULL. Can be called from IRQ and timer functions.
1275+ */
1276+
1277+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
1278+{
1279+ if(tty_ldisc_try(tty))
1280+ return &tty->ldisc;
1281+ return NULL;
1282+}
1283+
1284+EXPORT_SYMBOL_GPL(tty_ldisc_ref);
1285+
1286+void tty_ldisc_deref(struct tty_ldisc *ld)
1287+{
1288+ unsigned long flags;
1289+
1290+ if(ld == NULL)
1291+ BUG();
1292+
1293+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1294+ if(ld->refcount == 0)
1295+ printk(KERN_EMERG "tty_ldisc_deref: no references.\n");
1296+ else
1297+ ld->refcount--;
1298+ if(ld->refcount == 0)
1299+ wake_up(&tty_ldisc_wait);
1300+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1301+}
1302+
1303+EXPORT_SYMBOL_GPL(tty_ldisc_deref);
1304+
1305+/**
1306+ * tty_set_ldisc - set line discipline
1307+ * @tty: the terminal to set
1308+ * @ldisc: the line discipline
1309+ *
1310+ * Set the discipline of a tty line. Must be called from a process
1311+ * context.
1312+ */
1313+
1314 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
1315 {
1316 int retval = 0;
1317 struct tty_ldisc o_ldisc;
1318 char buf[64];
1319+ int work;
1320+ unsigned long flags;
1321+ struct tty_ldisc *ld;
1322
1323 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
1324 return -EINVAL;
1325+
1326+ restart:
1327+
1328+ if (tty->ldisc.num == ldisc)
1329+ return 0; /* We are already in the desired discipline */
1330+
1331+ ld = tty_ldisc_get(ldisc);
1332 /* Eduardo Blanco <ejbs@cs.cs.com.uy> */
1333 /* Cyrus Durgin <cider@speakeasy.org> */
1334- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) {
1335+ if (ld == NULL) {
1336 char modname [20];
1337 sprintf(modname, "tty-ldisc-%d", ldisc);
1338 request_module (modname);
1339- }
1340- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))
1341+ ld = tty_ldisc_get(ldisc); }
1342+ if (ld == NULL)
1343 return -EINVAL;
1344
1345- if (tty->ldisc.num == ldisc)
1346- return 0; /* We are already in the desired discipline */
1347- o_ldisc = tty->ldisc;
1348+ /*
1349+ * Make sure we don't change while someone holds a
1350+ * reference to the line discipline. The TTY_LDISC bit
1351+ * prevents anyone taking a reference once it is clear.
1352+ * We need the lock to avoid racing reference takers.
1353+ */
1354+
1355+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1356+ if(tty->ldisc.refcount)
1357+ {
1358+ /* Free the new ldisc we grabbed. Must drop the lock
1359+ first. */
1360+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1361+ tty_ldisc_put(ldisc);
1362+ if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
1363+ return -ERESTARTSYS;
1364+ goto restart;
1365+ }
1366+ clear_bit(TTY_LDISC, &tty->flags);
1367+ clear_bit(TTY_DONT_FLIP, &tty->flags);
1368+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1369+
1370+ /*
1371+ * From this point on we know nobody has an ldisc
1372+ * usage reference, nor can they obtain one until
1373+ * we say so later on.
1374+ */
1375
1376+ o_ldisc = tty->ldisc;
1377 tty_wait_until_sent(tty, 0);
1378
1379 /* Shutdown the current discipline. */
1380@@ -249,16 +465,20 @@
1381 (tty->ldisc.close)(tty);
1382
1383 /* Now set up the new line discipline. */
1384- tty->ldisc = ldiscs[ldisc];
1385- tty->termios->c_line = ldisc;
1386+ tty_ldisc_assign(tty, ld);
1387+ tty_set_termios_ldisc(tty, ldisc);
1388 if (tty->ldisc.open)
1389 retval = (tty->ldisc.open)(tty);
1390 if (retval < 0) {
1391- tty->ldisc = o_ldisc;
1392- tty->termios->c_line = tty->ldisc.num;
1393+ tty_ldisc_put(ldisc);
1394+ /* There is an outstanding reference here so this is safe */
1395+ tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num));
1396+ tty_set_termios_ldisc(tty, tty->ldisc.num);
1397 if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
1398- tty->ldisc = ldiscs[N_TTY];
1399- tty->termios->c_line = N_TTY;
1400+ tty_ldisc_put(o_ldisc.num);
1401+ /* This driver is always present */
1402+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
1403+ tty_set_termios_ldisc(tty, N_TTY);
1404 if (tty->ldisc.open) {
1405 int r = tty->ldisc.open(tty);
1406
1407@@ -269,8 +489,23 @@
1408 }
1409 }
1410 }
1411+ /* At this point we hold a reference to the new ldisc and a
1412+ reference to the old ldisc. If we ended up flipping back
1413+ to the existing ldisc we have two references to it */
1414+
1415 if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
1416 tty->driver.set_ldisc(tty);
1417+
1418+ tty_ldisc_put(o_ldisc.num);
1419+
1420+ /*
1421+ * Allow ldisc referencing to occur as soon as the driver
1422+ * ldisc callback completes.
1423+ */
1424+
1425+ set_bit(TTY_LDISC, &tty->flags);
1426+ wake_up(&tty_ldisc_wait);
1427+
1428 return retval;
1429 }
1430
1431@@ -385,6 +620,25 @@
1432 };
1433
1434 /*
1435+ * Internal and external helper for wakeups of tty
1436+ */
1437+
1438+void tty_wakeup(struct tty_struct *tty)
1439+{
1440+ struct tty_ldisc *ld;
1441+
1442+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
1443+ ld = tty_ldisc_ref(tty);
1444+ if(ld) {
1445+ if(ld->write_wakeup)
1446+ ld->write_wakeup(tty);
1447+ tty_ldisc_deref(ld);
1448+ }
1449+ }
1450+}
1451+
1452+EXPORT_SYMBOL_GPL(tty_wakeup);
1453+/*
1454 * This can be called through the "tq_scheduler"
1455 * task-list. That is process synchronous, but
1456 * doesn't hold any locks, so we need to make
1457@@ -397,6 +651,7 @@
1458 struct file * filp;
1459 struct file * cons_filp = NULL;
1460 struct task_struct *p;
1461+ struct tty_ldisc *ld;
1462 int closecount = 0, n;
1463
1464 if (!tty)
1465@@ -426,19 +681,18 @@
1466 }
1467
1468 /* FIXME! What are the locking issues here? This may me overdoing things.. */
1469- {
1470- unsigned long flags;
1471-
1472- save_flags(flags); cli();
1473- if (tty->ldisc.flush_buffer)
1474- tty->ldisc.flush_buffer(tty);
1475+ ld = tty_ldisc_ref(tty);
1476+ if(ld != NULL)
1477+ {
1478+ if (ld->flush_buffer)
1479+ ld->flush_buffer(tty);
1480 if (tty->driver.flush_buffer)
1481 tty->driver.flush_buffer(tty);
1482- if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
1483- tty->ldisc.write_wakeup)
1484- (tty->ldisc.write_wakeup)(tty);
1485- restore_flags(flags);
1486- }
1487+ if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && ld->write_wakeup)
1488+ ld->write_wakeup(tty);
1489+ //if (ld->hangup)
1490+ // ld->hangup(tty);
1491+ }
1492
1493 wake_up_interruptible(&tty->write_wait);
1494 wake_up_interruptible(&tty->read_wait);
1495@@ -448,20 +702,17 @@
1496 * Shutdown the current line discipline, and reset it to
1497 * N_TTY.
1498 */
1499+
1500 if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS)
1501+ {
1502+ unsigned long flags;
1503+ spin_lock_irqsave(&tty_termios_lock, flags);
1504 *tty->termios = tty->driver.init_termios;
1505- if (tty->ldisc.num != ldiscs[N_TTY].num) {
1506- if (tty->ldisc.close)
1507- (tty->ldisc.close)(tty);
1508- tty->ldisc = ldiscs[N_TTY];
1509- tty->termios->c_line = N_TTY;
1510- if (tty->ldisc.open) {
1511- int i = (tty->ldisc.open)(tty);
1512- if (i < 0)
1513- printk("do_tty_hangup: N_TTY open: error %d\n",
1514- -i);
1515- }
1516+ spin_unlock_irqrestore(&tty_termios_lock, flags);
1517 }
1518+
1519+ /* Defer ldisc switch */
1520+ /* tty_deferred_ldisc_switch(N_TTY); */
1521
1522 read_lock(&tasklist_lock);
1523 for_each_task(p) {
1524@@ -493,6 +744,15 @@
1525 tty->driver.close(tty, cons_filp);
1526 } else if (tty->driver.hangup)
1527 (tty->driver.hangup)(tty);
1528+
1529+ /* We don't want to have driver/ldisc interactions beyond
1530+ the ones we did here. The driver layer expects no
1531+ calls after ->hangup() from the ldisc side. However we
1532+ can't yet guarantee all that */
1533+
1534+ set_bit(TTY_HUPPED, &tty->flags);
1535+ if(ld)
1536+ tty_ldisc_deref(ld);
1537 unlock_kernel();
1538 }
1539
1540@@ -602,9 +862,8 @@
1541 }
1542 if (tty->driver.start)
1543 (tty->driver.start)(tty);
1544- if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
1545- tty->ldisc.write_wakeup)
1546- (tty->ldisc.write_wakeup)(tty);
1547+ /* If we have a running line discipline it may need kicking */
1548+ tty_wakeup(tty);
1549 wake_up_interruptible(&tty->write_wait);
1550 wake_up_interruptible(&tty->poll_wait);
1551 }
1552@@ -615,6 +874,7 @@
1553 int i;
1554 struct tty_struct * tty;
1555 struct inode *inode;
1556+ struct tty_ldisc *ld;
1557
1558 /* Can't seek (pread) on ttys. */
1559 if (ppos != &file->f_pos)
1560@@ -643,10 +903,16 @@
1561 return -ERESTARTSYS;
1562 }
1563 #endif
1564- if (tty->ldisc.read)
1565- i = (tty->ldisc.read)(tty,file,buf,count);
1566+ /* We want to wait for the line discipline to sort out in this
1567+ situation */
1568+ ld = tty_ldisc_ref_wait(tty);
1569+ lock_kernel();
1570+ if (ld->read)
1571+ i = (ld->read)(tty,file,buf,count);
1572 else
1573 i = -EIO;
1574+ tty_ldisc_deref(ld);
1575+ unlock_kernel();
1576 if (i > 0)
1577 inode->i_atime = CURRENT_TIME;
1578 return i;
1579@@ -717,7 +983,9 @@
1580 int is_console;
1581 struct tty_struct * tty;
1582 struct inode *inode;
1583-
1584+ ssize_t ret;
1585+ struct tty_ldisc *ld;
1586+
1587 /* Can't seek (pwrite) on ttys. */
1588 if (ppos != &file->f_pos)
1589 return -ESPIPE;
1590@@ -749,10 +1017,15 @@
1591 }
1592 }
1593 #endif
1594- if (!tty->ldisc.write)
1595- return -EIO;
1596- return do_tty_write(tty->ldisc.write, tty, file,
1597- (const unsigned char *)buf, count);
1598+
1599+ ld = tty_ldisc_ref_wait(tty);
1600+ if (!ld->write)
1601+ ret = -EIO;
1602+ else
1603+ ret = do_tty_write(ld->write, tty, file,
1604+ (const unsigned char *) buf, count);
1605+ tty_ldisc_deref(ld);
1606+ return ret;
1607 }
1608
1609 /* Semaphore to protect creating and releasing a tty */
2cf5f602
KT
1610@@ -917,7 +1190,9 @@
1611 (tty->ldisc.close)(tty);
1612 goto release_mem_out;
1613 }
1614- }
1615+ set_bit(TTY_LDISC, &o_tty->flags);
1616+ }
1617+ set_bit(TTY_LDISC, &tty->flags);
1618 goto success;
1619
1620 /*
1621@@ -945,7 +1220,9 @@
1622 }
1623 tty->count++;
1624 tty->driver = *driver; /* N.B. why do this every time?? */
1625-
1626+ /* FIXME */
1627+ if(!test_bit(TTY_LDISC, &tty->flags))
1628+ printk(KERN_ERR "init_dev but no ldisc\n");
1629 success:
1630 *ret_tty = tty;
1631
1632@@ -1023,6 +1300,7 @@
1633 int pty_master, tty_closing, o_tty_closing, do_sleep;
1634 int idx;
1635 char buf[64];
1636+ unsigned long flags;
1637
1638 tty = (struct tty_struct *)filp->private_data;
1639 if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev"))
1640@@ -1225,17 +1503,51 @@
1641 #endif
1642
1643 /*
1644+ * Prevent flush_to_ldisc() from rescheduling the work for later. Then
1645+ * kill any delayed work. As this is the final close it does not
1646+ * race with the set_ldisc code path.
1647+ */
1648+ clear_bit(TTY_LDISC, &tty->flags);
1649+ clear_bit(TTY_DONT_FLIP, &tty->flags);
1650+
1651+ /*
1652+ * Wait for any short term users (we know they are just driver
1653+ * side waiters as the file is closing so user count on the file
1654+ * side is zero.
1655+ */
1656+
1657+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1658+ while(tty->ldisc.refcount)
1659+ {
1660+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1661+ wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
1662+ spin_lock_irqsave(&tty_ldisc_lock, flags);
1663+ }
1664+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1665+
1666+ /*
1667 * Shutdown the current line discipline, and reset it to N_TTY.
1668 * N.B. why reset ldisc when we're releasing the memory??
1669+ * FIXME: this MUST get fixed for the new reflocking
1670 */
1671 if (tty->ldisc.close)
1672 (tty->ldisc.close)(tty);
1673- tty->ldisc = ldiscs[N_TTY];
1674- tty->termios->c_line = N_TTY;
1675+ tty_ldisc_put(tty->ldisc.num);
1676+
1677+ /*
1678+ * Switch the line discipline back
1679+ */
1680+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
1681+ tty_set_termios_ldisc(tty,N_TTY);
1682+
1683 if (o_tty) {
1684+ /* FIXME: could o_tty be in setldisc here ? */
1685+ clear_bit(TTY_LDISC, &o_tty->flags);
1686 if (o_tty->ldisc.close)
1687 (o_tty->ldisc.close)(o_tty);
1688- o_tty->ldisc = ldiscs[N_TTY];
1689+ tty_ldisc_put(o_tty->ldisc.num);
1690+ tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY));
1691+ tty_set_termios_ldisc(o_tty,N_TTY);
1692 }
1693
1694 /*
1695@@ -1409,14 +1721,18 @@
1696 static unsigned int tty_poll(struct file * filp, poll_table * wait)
1697 {
1698 struct tty_struct * tty;
1699+ struct tty_ldisc *ld;
1700+ int ret = 0;
1701
1702 tty = (struct tty_struct *)filp->private_data;
1703 if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_poll"))
1704 return 0;
1705
1706- if (tty->ldisc.poll)
1707- return (tty->ldisc.poll)(tty, filp, wait);
1708- return 0;
1709+ ld = tty_ldisc_ref_wait(tty);
1710+ if (ld->poll)
1711+ ret = (ld->poll)(tty, filp, wait);
1712+ tty_ldisc_deref(ld);
1713+ return ret;
1714 }
1715
1716 /*
1717@@ -1493,12 +1809,15 @@
1718 static int tiocsti(struct tty_struct *tty, char * arg)
1719 {
1720 char ch, mbz = 0;
1721+ struct tty_ldisc *ld;
1722
1723 if ((current->tty != tty) && !suser())
1724 return -EPERM;
1725 if (get_user(ch, arg))
1726 return -EFAULT;
1727- tty->ldisc.receive_buf(tty, &ch, &mbz, 1);
1728+ ld = tty_ldisc_ref_wait(tty);
1729+ ld->receive_buf(tty, &ch, &mbz, 1);
1730+ tty_ldisc_deref(ld);
1731 return 0;
1732 }
1733
1734@@ -1679,6 +1998,7 @@
1735 {
1736 struct tty_struct *tty, *real_tty;
1737 int retval;
1738+ struct tty_ldisc *ld;
1739
1740 tty = (struct tty_struct *)file->private_data;
1741 if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1742@@ -1766,6 +2086,7 @@
1743 case TIOCGSID:
1744 return tiocgsid(tty, real_tty, (pid_t *) arg);
1745 case TIOCGETD:
1746+ /* FIXME: check this is ok */
1747 return put_user(tty->ldisc.num, (int *) arg);
1748 case TIOCSETD:
1749 return tiocsetd(tty, (int *) arg);
1750@@ -1799,16 +2120,20 @@
1751 return send_break(tty, arg ? arg*(HZ/10) : HZ/4);
1752 }
1753 if (tty->driver.ioctl) {
1754- int retval = (tty->driver.ioctl)(tty, file, cmd, arg);
1755+ retval = (tty->driver.ioctl)(tty, file, cmd, arg);
1756 if (retval != -ENOIOCTLCMD)
1757 return retval;
1758 }
1759- if (tty->ldisc.ioctl) {
1760- int retval = (tty->ldisc.ioctl)(tty, file, cmd, arg);
1761- if (retval != -ENOIOCTLCMD)
1762- return retval;
1763+ ld = tty_ldisc_ref_wait(tty);
1764+ retval = -EINVAL;
1765+ if (ld->ioctl) {
1766+ if(likely(test_bit(TTY_LDISC, &tty->flags)))
1767+ retval = ld->ioctl(tty, file, cmd, arg);
1768+ if (retval == -ENOIOCTLCMD)
1769+ retval = -EINVAL;
1770 }
1771- return -EINVAL;
1772+ tty_ldisc_deref(ld);
1773+ return retval;
1774 }
1775
1776
1777@@ -1833,14 +2158,20 @@
1778 int session;
1779 int i;
1780 struct file *filp;
1781+ struct tty_ldisc *disc;
1782
1783 if (!tty)
1784 return;
1785 session = tty->session;
1786- if (tty->ldisc.flush_buffer)
1787- tty->ldisc.flush_buffer(tty);
1788+ /* We don't want an ldisc switch during this */
1789+ disc = tty_ldisc_ref(tty);
1790+ if (disc && disc->flush_buffer)
1791+ disc->flush_buffer(tty);
1792+ tty_ldisc_deref(disc);
1793+
1794 if (tty->driver.flush_buffer)
1795 tty->driver.flush_buffer(tty);
1796+
1797 read_lock(&tasklist_lock);
1798 for_each_task(p) {
1799 if ((p->tty == tty) ||
1800@@ -1872,10 +2203,15 @@
1801 char *fp;
1802 int count;
1803 unsigned long flags;
1804+ struct tty_ldisc *disc;
1805+
1806+ disc = tty_ldisc_ref(tty);
1807+ if (disc == NULL) /* !TTY_LDISC */
1808+ return;
1809
1810 if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
1811 queue_task(&tty->flip.tqueue, &tq_timer);
1812- return;
1813+ goto out;
1814 }
1815 if (tty->flip.buf_num) {
1816 cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1817@@ -1897,8 +2233,31 @@
1818 count = tty->flip.count;
1819 tty->flip.count = 0;
1820 restore_flags(flags);
1821-
1822- tty->ldisc.receive_buf(tty, cp, fp, count);
1823+ disc->receive_buf(tty, cp, fp, count);
1824+ out:
1825+ tty_ldisc_deref(disc);
1826+}
1827+
1828+/*
1829+ * Call the ldisc flush directly from a driver. This function may
1830+ * return an error and need retrying by the user.
1831+ */
1832+
1833+int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count)
1834+{
1835+ int ret = 0;
1836+ struct tty_ldisc *disc;
1837+
1838+ disc = tty_ldisc_ref(tty);
1839+ if(test_bit(TTY_DONT_FLIP, &tty->flags))
1840+ ret = -EAGAIN;
1841+ else if(disc == NULL)
1842+ ret = -EIO;
1843+ else
1844+ disc->receive_buf(tty, cp, fp, count);
1845+ tty_ldisc_deref(disc);
1846+ return ret;
1847+
1848 }
1849
1850 /*
1851@@ -1960,7 +2319,7 @@
1852 {
1853 memset(tty, 0, sizeof(struct tty_struct));
1854 tty->magic = TTY_MAGIC;
1855- tty->ldisc = ldiscs[N_TTY];
1856+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
1857 tty->pgrp = -1;
1858 tty->flip.char_buf_ptr = tty->flip.char_buf;
1859 tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1860@@ -2080,7 +2439,7 @@
1861 long __init console_init(long kmem_start, long kmem_end)
1862 {
1863 /* Setup the default TTY line discipline. */
1864- memset(ldiscs, 0, sizeof(ldiscs));
1865+ memset(tty_ldiscs, 0, NR_LDISCS*sizeof(struct tty_ldisc));
1866 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1867
1868 /*
1869diff -urN linux-2.2.26.orig/drivers/char/tty_ioctl.c linux-2.2.26/drivers/char/tty_ioctl.c
1870--- linux-2.2.26.orig/drivers/char/tty_ioctl.c 2001-03-25 18:31:24.000000000 +0200
1871+++ linux-2.2.26/drivers/char/tty_ioctl.c 2004-10-31 12:06:32.000000000 +0100
1872@@ -33,6 +33,8 @@
1873 # define PRINTK(x) /**/
1874 #endif
1875
1876+extern spinlock_t tty_termios_lock;
1877+
1878 /*
1879 * Internal flag options for termios setting behavior
1880 */
1881@@ -100,8 +102,17 @@
1882 {
1883 int canon_change;
1884 struct termios old_termios = *tty->termios;
1885+ struct tty_ldisc *ld;
1886+ unsigned long flags;
1887+
1888+ /*
1889+ * Perform the actual termios internal changes under lock.
1890+ */
1891+
1892+ /* FIXME: we need to decide on some locking/ordering semantics
1893+ for the set_termios notification eventually */
1894+ spin_lock_irqsave(&tty_termios_lock, flags);
1895
1896- cli();
1897 *tty->termios = *new_termios;
1898 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
1899 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
1900@@ -111,7 +122,7 @@
1901 tty->canon_data = 0;
1902 tty->erasing = 0;
1903 }
1904- sti();
1905+
1906 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
1907 {
1908 /* Get characters left over from canonical mode. */
1909@@ -142,16 +153,21 @@
1910 if (tty->driver.set_termios)
1911 (*tty->driver.set_termios)(tty, &old_termios);
1912
1913- if (tty->ldisc.set_termios)
1914- (*tty->ldisc.set_termios)(tty, &old_termios);
1915+ ld = tty_ldisc_ref(tty);
1916+ if (ld != NULL) {
1917+ if (ld->set_termios)
1918+ (ld->set_termios)(tty, &old_termios);
1919+ tty_ldisc_deref(ld);
1920+ }
1921+ spin_unlock_irqrestore(&tty_termios_lock, flags);
1922 }
1923
1924 static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
1925 {
1926 struct termios tmp_termios;
1927- int retval;
1928+ struct tty_ldisc *ld;
1929+ int retval = tty_check_change(tty);
1930
1931- retval = tty_check_change(tty);
1932 if (retval)
1933 return retval;
1934
1935@@ -164,9 +180,13 @@
1936 return -EFAULT;
1937 }
1938
1939- if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer)
1940- tty->ldisc.flush_buffer(tty);
1941+ ld = tty_ldisc_ref(tty);
1942
1943+ if (ld != NULL) {
1944+ if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
1945+ ld->flush_buffer(tty);
1946+ tty_ldisc_deref(ld);
1947+ }
1948 if (opt & TERMIOS_WAIT) {
1949 tty_wait_until_sent(tty, 0);
1950 if (signal_pending(current))
1951@@ -230,12 +250,16 @@
1952 static int get_sgttyb(struct tty_struct * tty, struct sgttyb * sgttyb)
1953 {
1954 struct sgttyb tmp;
1955+ unsigned long flags;
1956
1957+ spin_lock_irqsave(&tty_termios_lock, flags);
1958 tmp.sg_ispeed = 0;
1959 tmp.sg_ospeed = 0;
1960 tmp.sg_erase = tty->termios->c_cc[VERASE];
1961 tmp.sg_kill = tty->termios->c_cc[VKILL];
1962 tmp.sg_flags = get_sgflags(tty);
1963+ spin_unlock_irqrestore(&tty_termios_lock, flags);
1964+
1965 if (copy_to_user(sgttyb, &tmp, sizeof(tmp)))
1966 return -EFAULT;
1967 return 0;
1968@@ -275,12 +299,15 @@
1969 retval = tty_check_change(tty);
1970 if (retval)
1971 return retval;
1972- termios = *tty->termios;
1973+
1974 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
1975 return -EFAULT;
1976+ spin_lock_irqsave(&tty_termios_lock, flags);
1977+ termios = *tty->termios;
1978 termios.c_cc[VERASE] = tmp.sg_erase;
1979 termios.c_cc[VKILL] = tmp.sg_kill;
1980 set_sgflags(&termios, tmp.sg_flags);
1981+ spin_unlock_irqrestore(&tty_termios_lock, flags);
1982 change_termios(tty, &termios);
1983 return 0;
1984 }
1985@@ -374,6 +401,8 @@
1986 {
1987 struct tty_struct * real_tty;
1988 int retval;
1989+ struct tty_ldisc *ld;
1990+ unsigned long flags;
1991
1992 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1993 tty->driver.subtype == PTY_TYPE_MASTER)
1994@@ -423,6 +452,8 @@
1995 retval = tty_check_change(tty);
1996 if (retval)
1997 return retval;
1998+
1999+ ld = tty_ldisc_ref(tty);
2000 switch (arg) {
2001 case TCOOFF:
2002 if (!tty->flow_stopped) {
2003@@ -454,20 +485,22 @@
2004 return retval;
2005 switch (arg) {
2006 case TCIFLUSH:
2007- if (tty->ldisc.flush_buffer)
2008- tty->ldisc.flush_buffer(tty);
2009+ if (ld->flush_buffer)
2010+ ld->flush_buffer(tty);
2011 break;
2012 case TCIOFLUSH:
2013- if (tty->ldisc.flush_buffer)
2014- tty->ldisc.flush_buffer(tty);
2015+ if (ld->flush_buffer)
2016+ ld->flush_buffer(tty);
2017 /* fall through */
2018 case TCOFLUSH:
2019 if (tty->driver.flush_buffer)
2020 tty->driver.flush_buffer(tty);
2021 break;
2022 default:
2023+ tty_ldisc_deref(ld);
2024 return -EINVAL;
2025 }
2026+ tty_ldisc_deref(ld);
2027 return 0;
2028 case TIOCOUTQ:
2029 return put_user(tty->driver.chars_in_buffer ?
2030@@ -515,9 +548,11 @@
2031 retval = get_user(arg, (unsigned int *) arg);
2032 if (retval)
2033 return retval;
2034+ spin_lock_irqsave(&tty_termios_lock, flags);
2035 tty->termios->c_cflag =
2036 ((tty->termios->c_cflag & ~CLOCAL) |
2037 (arg ? CLOCAL : 0));
2038+ spin_unlock_irqrestore(&tty_termios_lock, flags);
2039 return 0;
2040 default:
2041 return -ENOIOCTLCMD;
2042diff -urN linux-2.2.26.orig/drivers/net/slip.c linux-2.2.26/drivers/net/slip.c
2043--- linux-2.2.26.orig/drivers/net/slip.c 2001-03-25 18:31:15.000000000 +0200
2044+++ linux-2.2.26/drivers/net/slip.c 2004-10-24 11:09:19.428600744 +0200
2045@@ -669,7 +669,9 @@
2046 * Handle the 'receiver data ready' interrupt.
2047 * This function is called by the 'tty_io' module in the kernel when
2048 * a block of SLIP data has been received, which can now be decapsulated
2049- * and sent on to some IP layer for further processing.
2050+ * and sent on to some IP layer for further processing. This will not
2051+ * be re-entered while running but other ldisc functions may be called
2052+ * in parallel
2053 */
2054
2055 static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
2056@@ -824,9 +826,11 @@
2057 * SLIP line discipline is called for. Because we are
2058 * sure the tty line exists, we only have to link it to
2059 * a free SLIP channel...
2060+ *
2061+ * Called in process context serialized from other ldisc calls.
2062 */
2063-static int
2064-slip_open(struct tty_struct *tty)
2065+
2066+static int slip_open(struct tty_struct *tty)
2067 {
2068 struct slip *sl;
2069 int err;
2070@@ -908,6 +912,9 @@
2071 }
2072
2073 /*
2074+
2075+ FIXME: 1,2 are fixed 3 was never true anyway.
2076+
2077 Let me to blame a bit.
2078 1. TTY module calls this funstion on soft interrupt.
2079 2. TTY module calls this function WITH MASKED INTERRUPTS!
2080@@ -926,9 +933,8 @@
2081
2082 /*
2083 * Close down a SLIP channel.
2084- * This means flushing out any pending queues, and then restoring the
2085- * TTY line discipline to what it was before it got hooked to SLIP
2086- * (which usually is TTY again).
2087+ * This means flushing out any pending queues, and then returning. This
2088+ * call is serialized against other ldisc functions
2089 */
2090 static void
2091 slip_close(struct tty_struct *tty)
2092diff -urN linux-2.2.26.orig/drivers/sbus/char/zs.c linux-2.2.26/drivers/sbus/char/zs.c
2093--- linux-2.2.26.orig/drivers/sbus/char/zs.c 2001-11-02 17:39:07.000000000 +0100
2094+++ linux-2.2.26/drivers/sbus/char/zs.c 2004-10-31 09:43:01.192501208 +0100
2095@@ -1606,10 +1606,10 @@
2096 tty->closing = 0;
2097 info->event = 0;
2098 info->tty = 0;
2099- if (tty->ldisc.num != ldiscs[N_TTY].num) {
2100+ if (tty->ldisc.num != N_TTY) {
2101 if (tty->ldisc.close)
2102 (tty->ldisc.close)(tty);
2103- tty->ldisc = ldiscs[N_TTY];
2104+ tty->ldisc = *(tty_ldisc_get(N_TTY));
2105 tty->termios->c_line = N_TTY;
2106 if (tty->ldisc.open)
2107 (tty->ldisc.open)(tty);
2108diff -urN linux-2.2.26.orig/drivers/sgi/char/sgiserial.c linux-2.2.26/drivers/sgi/char/sgiserial.c
2109--- linux-2.2.26.orig/drivers/sgi/char/sgiserial.c 2001-03-25 18:31:41.000000000 +0200
2110+++ linux-2.2.26/drivers/sgi/char/sgiserial.c 2004-10-31 09:38:06.825251832 +0100
2111@@ -1465,10 +1465,10 @@
2112 tty->closing = 0;
2113 info->event = 0;
2114 info->tty = 0;
2115- if (tty->ldisc.num != ldiscs[N_TTY].num) {
2116+ if (tty->ldisc.num != N_TTY) {
2117 if (tty->ldisc.close)
2118 (tty->ldisc.close)(tty);
2119- tty->ldisc = ldiscs[N_TTY];
2120+ tty->ldisc = *(tty_ldisc_get(N_TTY));
2121 tty->termios->c_line = N_TTY;
2122 if (tty->ldisc.open)
2123 (tty->ldisc.open)(tty);
2124diff -urN linux-2.2.26.orig/fs/proc/proc_tty.c linux-2.2.26/fs/proc/proc_tty.c
2125--- linux-2.2.26.orig/fs/proc/proc_tty.c 2004-02-24 14:48:05.000000000 +0100
2126+++ linux-2.2.26/fs/proc/proc_tty.c 2004-10-31 13:07:51.212134232 +0100
2127@@ -15,8 +15,6 @@
2128 #include <asm/bitops.h>
2129
2130 extern struct tty_driver *tty_drivers; /* linked list of tty drivers */
2131-extern struct tty_ldisc ldiscs[];
2132-
2133
2134 static int tty_drivers_read_proc(char *page, char **start, off_t off,
2135 int count, int *eof, void *data);
2136@@ -112,16 +110,20 @@
2137 int len = 0;
2138 off_t begin = 0;
2139 off_t end;
2140+ struct tty_ldisc *ld;
2141
2142 end = off + count; /* XXX: undefined on overflow per ISO C99 */
2143 if (end < off)
2144 return -EINVAL;
2145
2146 for (i=0; i < NR_LDISCS; i++) {
2147- if (!(ldiscs[i].flags & LDISC_FLAG_DEFINED))
2148+ ld = tty_ldisc_get(i);
2149+ if (ld == NULL)
2150+
2151 continue;
2152 len += sprintf(page+len, "%-10s %2d\n",
2153- ldiscs[i].name ? ldiscs[i].name : "???", i);
2154+ ld->name ? ld->name : "???", i);
2155+ tty_ldisc_put(i);
2156 if (len+begin > end)
2157 break;
2158 if (len+begin < off) {
2159diff -urN linux-2.2.26.orig/include/linux/tty.h linux-2.2.26/include/linux/tty.h
2160--- linux-2.2.26.orig/include/linux/tty.h 2004-02-24 18:33:31.000000000 +0100
2161+++ linux-2.2.26/include/linux/tty.h 2004-10-24 10:59:54.653459616 +0200
2162@@ -319,19 +319,21 @@
2163 * tty->write. Thus, you must use the inline functions set_bit() and
2164 * clear_bit() to make things atomic.
2165 */
2166-#define TTY_THROTTLED 0
2167-#define TTY_IO_ERROR 1
2168-#define TTY_OTHER_CLOSED 2
2169-#define TTY_EXCLUSIVE 3
2170-#define TTY_DEBUG 4
2171-#define TTY_DO_WRITE_WAKEUP 5
2172-#define TTY_PUSH 6
2173-#define TTY_CLOSING 7
2174-#define TTY_DONT_FLIP 8
2175-#define TTY_HW_COOK_OUT 14
2176-#define TTY_HW_COOK_IN 15
2177-#define TTY_PTY_LOCK 16
2178-#define TTY_NO_WRITE_SPLIT 17
2179+#define TTY_THROTTLED 0 /* Call unthrottle() at threshold min */
2180+#define TTY_IO_ERROR 1 /* Canse an I/O error (may be no ldisc too) */
2181+#define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */
2182+#define TTY_EXCLUSIVE 3 /* Exclusive open mode */
2183+#define TTY_DEBUG 4 /* Debugging */
2184+#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */
2185+#define TTY_PUSH 6 /* n_tty private */
2186+#define TTY_CLOSING 7 /* ->close() in progress */
2187+#define TTY_DONT_FLIP 8 /* Defer buffer flip */
2188+#define TTY_LDISC 9 /* Line discipline attached */
2189+#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */
2190+#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */
2191+#define TTY_PTY_LOCK 16 /* pty private */
2192+#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
2193+#define TTY_HUPPED 18 /* Post driver->hangup() */
2194
2195 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
2196
2197@@ -339,7 +341,7 @@
2198
2199 extern struct termios tty_std_termios;
2200 extern struct tty_struct * redirect;
2201-extern struct tty_ldisc ldiscs[];
2202+extern struct tty_ldisc tty_ldiscs[];
2203 extern int fg_console, last_console, want_console;
2204
2205 extern int kmsg_redirect;
2206@@ -393,6 +395,16 @@
2207 extern void tty_flip_buffer_push(struct tty_struct *tty);
2208 extern int tty_get_baud_rate(struct tty_struct *tty);
2209
2210+extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
2211+extern void tty_ldisc_deref(struct tty_ldisc *);
2212+extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
2213+
2214+extern struct tty_ldisc *tty_ldisc_get(int);
2215+extern void tty_ldisc_put(int);
2216+
2217+extern void tty_wakeup(struct tty_struct *tty);
2218+
2219+
2220 /* n_tty.c */
2221 extern struct tty_ldisc tty_ldisc_N_TTY;
2222
2223diff -urN linux-2.2.26.orig/include/linux/tty_ldisc.h linux-2.2.26/include/linux/tty_ldisc.h
2224--- linux-2.2.26.orig/include/linux/tty_ldisc.h 2004-02-24 18:33:31.000000000 +0100
2225+++ linux-2.2.26/include/linux/tty_ldisc.h 2004-10-24 11:04:07.991946312 +0200
2226@@ -129,6 +129,7 @@
2227 char *fp, int count);
2228 int (*receive_room)(struct tty_struct *);
2229 void (*write_wakeup)(struct tty_struct *);
2230+int refcount;
2231 };
2232
2233 #define TTY_LDISC_MAGIC 0x5403
This page took 0.349523 seconds and 4 git commands to generate.