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); |
