diff options
author | Alan Cox <alan@redhat.com> | 2008-07-16 16:53:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:12:35 -0400 |
commit | 6f67048cd010afe19d79d821f16055d9c704c6f0 (patch) | |
tree | 1fbd4717f97632a4753ea98555e285483e35cd45 | |
parent | d87a6d951c6c09d191d9c10903deb3cc353fcd2c (diff) |
tty: Introduce a tty_port common structure
Every tty driver has its own concept of a port structure and because
they all differ we cannot extract commonality. Begin fixing this by
creating a structure drivers can elect to use so that over time we can
push fields into this and create commonality and then introduce common
methods.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/tty_io.c | 34 | ||||
-rw-r--r-- | include/linux/tty.h | 30 |
2 files changed, 63 insertions, 1 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 54c4ada460ee..739c9c59fc62 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -2088,6 +2088,40 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, | |||
2088 | return tty_write(file, buf, count, ppos); | 2088 | return tty_write(file, buf, count, ppos); |
2089 | } | 2089 | } |
2090 | 2090 | ||
2091 | void tty_port_init(struct tty_port *port) | ||
2092 | { | ||
2093 | memset(port, 0, sizeof(*port)); | ||
2094 | init_waitqueue_head(&port->open_wait); | ||
2095 | init_waitqueue_head(&port->close_wait); | ||
2096 | mutex_init(&port->mutex); | ||
2097 | } | ||
2098 | EXPORT_SYMBOL(tty_port_init); | ||
2099 | |||
2100 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
2101 | { | ||
2102 | /* We may sleep in get_zeroed_page() */ | ||
2103 | mutex_lock(&port->mutex); | ||
2104 | if (port->xmit_buf == NULL) | ||
2105 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
2106 | mutex_unlock(&port->mutex); | ||
2107 | if (port->xmit_buf == NULL) | ||
2108 | return -ENOMEM; | ||
2109 | return 0; | ||
2110 | } | ||
2111 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
2112 | |||
2113 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
2114 | { | ||
2115 | mutex_lock(&port->mutex); | ||
2116 | if (port->xmit_buf != NULL) { | ||
2117 | free_page((unsigned long)port->xmit_buf); | ||
2118 | port->xmit_buf = NULL; | ||
2119 | } | ||
2120 | mutex_unlock(&port->mutex); | ||
2121 | } | ||
2122 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
2123 | |||
2124 | |||
2091 | static char ptychar[] = "pqrstuvwxyzabcde"; | 2125 | static char ptychar[] = "pqrstuvwxyzabcde"; |
2092 | 2126 | ||
2093 | /** | 2127 | /** |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 013711ea7385..d7c695b65c0e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -166,6 +166,29 @@ struct tty_bufhead { | |||
166 | 166 | ||
167 | struct device; | 167 | struct device; |
168 | struct signal_struct; | 168 | struct signal_struct; |
169 | |||
170 | /* | ||
171 | * Port level information. Each device keeps its own port level information | ||
172 | * so provide a common structure for those ports wanting to use common support | ||
173 | * routines. | ||
174 | * | ||
175 | * The tty port has a different lifetime to the tty so must be kept apart. | ||
176 | * In addition be careful as tty -> port mappings are valid for the life | ||
177 | * of the tty object but in many cases port -> tty mappings are valid only | ||
178 | * until a hangup so don't use the wrong path. | ||
179 | */ | ||
180 | |||
181 | struct tty_port { | ||
182 | struct tty_struct *tty; /* Back pointer */ | ||
183 | int blocked_open; /* Waiting to open */ | ||
184 | int count; /* Usage count */ | ||
185 | wait_queue_head_t open_wait; /* Open waiters */ | ||
186 | wait_queue_head_t close_wait; /* Close waiters */ | ||
187 | unsigned long flags; /* TTY flags ASY_*/ | ||
188 | struct mutex mutex; /* Locking */ | ||
189 | unsigned char *xmit_buf; /* Optional buffer */ | ||
190 | }; | ||
191 | |||
169 | /* | 192 | /* |
170 | * Where all of the state associated with a tty is kept while the tty | 193 | * Where all of the state associated with a tty is kept while the tty |
171 | * is open. Since the termios state should be kept even if the tty | 194 | * is open. Since the termios state should be kept even if the tty |
@@ -214,7 +237,7 @@ struct tty_struct { | |||
214 | struct list_head tty_files; | 237 | struct list_head tty_files; |
215 | 238 | ||
216 | #define N_TTY_BUF_SIZE 4096 | 239 | #define N_TTY_BUF_SIZE 4096 |
217 | 240 | ||
218 | /* | 241 | /* |
219 | * The following is data for the N_TTY line discipline. For | 242 | * The following is data for the N_TTY line discipline. For |
220 | * historical reasons, this is included in the tty structure. | 243 | * historical reasons, this is included in the tty structure. |
@@ -242,6 +265,7 @@ struct tty_struct { | |||
242 | spinlock_t read_lock; | 265 | spinlock_t read_lock; |
243 | /* If the tty has a pending do_SAK, queue it here - akpm */ | 266 | /* If the tty has a pending do_SAK, queue it here - akpm */ |
244 | struct work_struct SAK_work; | 267 | struct work_struct SAK_work; |
268 | struct tty_port *port; | ||
245 | }; | 269 | }; |
246 | 270 | ||
247 | /* tty magic number */ | 271 | /* tty magic number */ |
@@ -350,6 +374,10 @@ extern void tty_write_unlock(struct tty_struct *tty); | |||
350 | extern int tty_write_lock(struct tty_struct *tty, int ndelay); | 374 | extern int tty_write_lock(struct tty_struct *tty, int ndelay); |
351 | #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) | 375 | #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) |
352 | 376 | ||
377 | extern void tty_port_init(struct tty_port *port); | ||
378 | extern int tty_port_alloc_xmit_buf(struct tty_port *port); | ||
379 | extern void tty_port_free_xmit_buf(struct tty_port *port); | ||
380 | |||
353 | 381 | ||
354 | 382 | ||
355 | /* n_tty.c */ | 383 | /* n_tty.c */ |