aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPaul Fulghum <paulkf@microgate.com>2006-02-03 06:04:41 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-03 11:32:09 -0500
commit808249ceba49cdb3054c0aa5b75a61862d6cab94 (patch)
tree246d11a687db3e8a775e746ed8f0da1aeedae70c /include/linux
parent546cfdf47f2ea2438b01f8626a60b87f9d8d1e53 (diff)
[PATCH] new tty buffering locking fix
Change locking in the new tty buffering facility from using tty->read_lock, which is currently ignored by drivers and thus ineffective. New locking uses a new tty buffering specific lock enforced centrally in the tty buffering code. Two drivers (esp and cyclades) are updated to use the tty buffering functions instead of accessing tty buffering internals directly. This is required for the new locking to work. Minor checks for NULL buffers added to tty_prepare_flip_string/tty_prepare_flip_string_flags Signed-off-by: Paul Fulghum <paulkf@microgate.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/kbd_kern.h5
-rw-r--r--include/linux/tty.h2
-rw-r--r--include/linux/tty_flip.h7
3 files changed, 13 insertions, 1 deletions
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index 45f625d7d0b2..3aed37314ab8 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -151,6 +151,11 @@ extern unsigned int keymap_count;
151 151
152static inline void con_schedule_flip(struct tty_struct *t) 152static inline void con_schedule_flip(struct tty_struct *t)
153{ 153{
154 unsigned long flags;
155 spin_lock_irqsave(&t->buf.lock, flags);
156 if (t->buf.tail != NULL)
157 t->buf.tail->active = 0;
158 spin_unlock_irqrestore(&t->buf.lock, flags);
154 schedule_work(&t->buf.work); 159 schedule_work(&t->buf.work);
155} 160}
156 161
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 3787102e4b12..a7bd3b4558d2 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -57,6 +57,7 @@ struct tty_buffer {
57 unsigned char *flag_buf_ptr; 57 unsigned char *flag_buf_ptr;
58 int used; 58 int used;
59 int size; 59 int size;
60 int active;
60 /* Data points here */ 61 /* Data points here */
61 unsigned long data[0]; 62 unsigned long data[0];
62}; 63};
@@ -64,6 +65,7 @@ struct tty_buffer {
64struct tty_bufhead { 65struct tty_bufhead {
65 struct work_struct work; 66 struct work_struct work;
66 struct semaphore pty_sem; 67 struct semaphore pty_sem;
68 spinlock_t lock;
67 struct tty_buffer *head; /* Queue head */ 69 struct tty_buffer *head; /* Queue head */
68 struct tty_buffer *tail; /* Active buffer */ 70 struct tty_buffer *tail; /* Active buffer */
69 struct tty_buffer *free; /* Free queue head */ 71 struct tty_buffer *free; /* Free queue head */
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index be1400e82482..82961eb19888 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -17,7 +17,7 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
17 unsigned char ch, char flag) 17 unsigned char ch, char flag)
18{ 18{
19 struct tty_buffer *tb = tty->buf.tail; 19 struct tty_buffer *tb = tty->buf.tail;
20 if (tb && tb->used < tb->size) { 20 if (tb && tb->active && tb->used < tb->size) {
21 tb->flag_buf_ptr[tb->used] = flag; 21 tb->flag_buf_ptr[tb->used] = flag;
22 tb->char_buf_ptr[tb->used++] = ch; 22 tb->char_buf_ptr[tb->used++] = ch;
23 return 1; 23 return 1;
@@ -27,6 +27,11 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
27 27
28_INLINE_ void tty_schedule_flip(struct tty_struct *tty) 28_INLINE_ void tty_schedule_flip(struct tty_struct *tty)
29{ 29{
30 unsigned long flags;
31 spin_lock_irqsave(&tty->buf.lock, flags);
32 if (tty->buf.tail != NULL)
33 tty->buf.tail->active = 0;
34 spin_unlock_irqrestore(&tty->buf.lock, flags);
30 schedule_delayed_work(&tty->buf.work, 1); 35 schedule_delayed_work(&tty->buf.work, 1);
31} 36}
32 37