diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:42:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:42 -0400 |
commit | 8b0a88d5912ab549d5adac2c8498ecdaae5319a5 (patch) | |
tree | 8ed71420259881fd6d1dd5f5841ffe2f3c5d1fa2 | |
parent | 7d7b93c1452f381350dbaf276a63357fa6559e6d (diff) |
tty: More driver operations
We have the lookup operation abstracted which is nice for pty cleanup but
we really want to abstract the add/remove entries as well so that we can
pull the pty code out of the tty core and create a clear defined interface
for the tty driver table.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/pty.c | 16 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 57 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 16 |
3 files changed, 79 insertions, 10 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 0fdfa0517140..4e6490bda751 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -433,8 +433,22 @@ static void pty_shutdown(struct tty_struct *tty) | |||
433 | kfree(tty->termios_locked); | 433 | kfree(tty->termios_locked); |
434 | } | 434 | } |
435 | 435 | ||
436 | /* We have no need to install and remove our tty objects as devpts does all | ||
437 | the work for us */ | ||
438 | |||
439 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
440 | { | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
445 | { | ||
446 | } | ||
447 | |||
436 | static const struct tty_operations ptm_unix98_ops = { | 448 | static const struct tty_operations ptm_unix98_ops = { |
437 | .lookup = ptm_unix98_lookup, | 449 | .lookup = ptm_unix98_lookup, |
450 | .install = pty_install, | ||
451 | .remove = pty_remove, | ||
438 | .open = pty_open, | 452 | .open = pty_open, |
439 | .close = pty_close, | 453 | .close = pty_close, |
440 | .write = pty_write, | 454 | .write = pty_write, |
@@ -449,6 +463,8 @@ static const struct tty_operations ptm_unix98_ops = { | |||
449 | 463 | ||
450 | static const struct tty_operations pty_unix98_ops = { | 464 | static const struct tty_operations pty_unix98_ops = { |
451 | .lookup = pts_unix98_lookup, | 465 | .lookup = pts_unix98_lookup, |
466 | .install = pty_install, | ||
467 | .remove = pty_remove, | ||
452 | .open = pty_open, | 468 | .open = pty_open, |
453 | .close = pty_close, | 469 | .close = pty_close, |
454 | .write = pty_write, | 470 | .write = pty_write, |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 47aa437effe2..888380f573dc 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1189,7 +1189,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | /** | 1191 | /** |
1192 | * pty_line_name - generate name for a tty | 1192 | * tty_line_name - generate name for a tty |
1193 | * @driver: the tty driver in use | 1193 | * @driver: the tty driver in use |
1194 | * @index: the minor number | 1194 | * @index: the minor number |
1195 | * @p: output buffer of at least 7 bytes | 1195 | * @p: output buffer of at least 7 bytes |
@@ -1222,13 +1222,51 @@ struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, int idx) | |||
1222 | if (driver->ops->lookup) | 1222 | if (driver->ops->lookup) |
1223 | return driver->ops->lookup(driver, idx); | 1223 | return driver->ops->lookup(driver, idx); |
1224 | 1224 | ||
1225 | tty = driver->ttys[idx]; | 1225 | tty = driver->ttys[idx]; |
1226 | return tty; | 1226 | return tty; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | /** | 1229 | /** |
1230 | * tty_reopen() - fast re-open of an open tty | 1230 | * tty_driver_install_tty() - install a tty entry in the driver |
1231 | * @tty - the tty to open | 1231 | * @driver: the driver for the tty |
1232 | * @tty: the tty | ||
1233 | * | ||
1234 | * Install a tty object into the driver tables. The tty->index field | ||
1235 | * will be set by the time this is called. | ||
1236 | * | ||
1237 | * Locking: tty_mutex for now | ||
1238 | */ | ||
1239 | static int tty_driver_install_tty(struct tty_driver *driver, | ||
1240 | struct tty_struct *tty) | ||
1241 | { | ||
1242 | if (driver->ops->install) | ||
1243 | return driver->ops->install(driver, tty); | ||
1244 | driver->ttys[tty->index] = tty; | ||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1248 | /** | ||
1249 | * tty_driver_remove_tty() - remove a tty from the driver tables | ||
1250 | * @driver: the driver for the tty | ||
1251 | * @idx: the minor number | ||
1252 | * | ||
1253 | * Remvoe a tty object from the driver tables. The tty->index field | ||
1254 | * will be set by the time this is called. | ||
1255 | * | ||
1256 | * Locking: tty_mutex for now | ||
1257 | */ | ||
1258 | static void tty_driver_remove_tty(struct tty_driver *driver, | ||
1259 | struct tty_struct *tty) | ||
1260 | { | ||
1261 | if (driver->ops->remove) | ||
1262 | driver->ops->remove(driver, tty); | ||
1263 | else | ||
1264 | driver->ttys[tty->index] = NULL; | ||
1265 | } | ||
1266 | |||
1267 | /* | ||
1268 | * tty_reopen() - fast re-open of an open tty | ||
1269 | * @tty - the tty to open | ||
1232 | * | 1270 | * |
1233 | * Return 0 on success, -errno on error. | 1271 | * Return 0 on success, -errno on error. |
1234 | * | 1272 | * |
@@ -1423,11 +1461,7 @@ int tty_init_dev(struct tty_driver *driver, int idx, | |||
1423 | * All structures have been allocated, so now we install them. | 1461 | * All structures have been allocated, so now we install them. |
1424 | * Failures after this point use release_tty to clean up, so | 1462 | * Failures after this point use release_tty to clean up, so |
1425 | * there's no need to null out the local pointers. | 1463 | * there's no need to null out the local pointers. |
1426 | * | ||
1427 | * FIXME: We want a 'driver->install method ? | ||
1428 | */ | 1464 | */ |
1429 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1430 | driver->ttys[idx] = tty; | ||
1431 | 1465 | ||
1432 | if (!*tp_loc) | 1466 | if (!*tp_loc) |
1433 | *tp_loc = tp; | 1467 | *tp_loc = tp; |
@@ -1441,6 +1475,9 @@ int tty_init_dev(struct tty_driver *driver, int idx, | |||
1441 | tty_driver_kref_get(driver); | 1475 | tty_driver_kref_get(driver); |
1442 | tty->count++; | 1476 | tty->count++; |
1443 | 1477 | ||
1478 | if (tty_driver_install_tty(driver, tty) < 0) | ||
1479 | goto release_mem_out; | ||
1480 | |||
1444 | /* | 1481 | /* |
1445 | * Structures all installed ... call the ldisc open routines. | 1482 | * Structures all installed ... call the ldisc open routines. |
1446 | * If we fail here just call release_tty to clean up. No need | 1483 | * If we fail here just call release_tty to clean up. No need |
@@ -1502,7 +1539,7 @@ EXPORT_SYMBOL(tty_free_termios); | |||
1502 | 1539 | ||
1503 | void tty_shutdown(struct tty_struct *tty) | 1540 | void tty_shutdown(struct tty_struct *tty) |
1504 | { | 1541 | { |
1505 | tty->driver->ttys[tty->index] = NULL; | 1542 | tty_driver_remove_tty(tty->driver, tty); |
1506 | tty_free_termios(tty); | 1543 | tty_free_termios(tty); |
1507 | } | 1544 | } |
1508 | EXPORT_SYMBOL(tty_shutdown); | 1545 | EXPORT_SYMBOL(tty_shutdown); |
@@ -1615,7 +1652,7 @@ void tty_release_dev(struct file *filp) | |||
1615 | "free (%s)\n", tty->name); | 1652 | "free (%s)\n", tty->name); |
1616 | return; | 1653 | return; |
1617 | } | 1654 | } |
1618 | if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1655 | if (!devpts) { |
1619 | if (tty != tty->driver->ttys[idx]) { | 1656 | if (tty != tty->driver->ttys[idx]) { |
1620 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | 1657 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1621 | "for (%s)\n", idx, tty->name); | 1658 | "for (%s)\n", idx, tty->name); |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index ba891dd23550..005d06ad46a6 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
@@ -15,6 +15,20 @@ | |||
15 | * | 15 | * |
16 | * Optional method. Default behaviour is to use the ttys array | 16 | * Optional method. Default behaviour is to use the ttys array |
17 | * | 17 | * |
18 | * int (*install)(struct tty_driver *self, struct tty_struct *tty) | ||
19 | * | ||
20 | * Install a new tty into the tty driver internal tables. Used in | ||
21 | * conjunction with lookup and remove methods. | ||
22 | * | ||
23 | * Optional method. Default behaviour is to use the ttys array | ||
24 | * | ||
25 | * void (*remove)(struct tty_driver *self, struct tty_struct *tty) | ||
26 | * | ||
27 | * Remove a closed tty from the tty driver internal tables. Used in | ||
28 | * conjunction with lookup and remove methods. | ||
29 | * | ||
30 | * Optional method. Default behaviour is to use the ttys array | ||
31 | * | ||
18 | * int (*open)(struct tty_struct * tty, struct file * filp); | 32 | * int (*open)(struct tty_struct * tty, struct file * filp); |
19 | * | 33 | * |
20 | * This routine is called when a particular tty device is opened. | 34 | * This routine is called when a particular tty device is opened. |
@@ -212,6 +226,8 @@ struct tty_driver; | |||
212 | 226 | ||
213 | struct tty_operations { | 227 | struct tty_operations { |
214 | struct tty_struct * (*lookup)(struct tty_driver *driver, int idx); | 228 | struct tty_struct * (*lookup)(struct tty_driver *driver, int idx); |
229 | int (*install)(struct tty_driver *driver, struct tty_struct *tty); | ||
230 | void (*remove)(struct tty_driver *driver, struct tty_struct *tty); | ||
215 | int (*open)(struct tty_struct * tty, struct file * filp); | 231 | int (*open)(struct tty_struct * tty, struct file * filp); |
216 | void (*close)(struct tty_struct * tty, struct file * filp); | 232 | void (*close)(struct tty_struct * tty, struct file * filp); |
217 | void (*shutdown)(struct tty_struct *tty); | 233 | void (*shutdown)(struct tty_struct *tty); |