aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorSukadev Bhattiprolu <sukadev@us.ibm.com>2008-10-13 05:41:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:42 -0400
commit23499705753ab8b4c6b0b64e6c424a370bd900a1 (patch)
treedb092164c37a2c2897275a37d61ef325a59808d9 /drivers/char/tty_io.c
parentd81ed10307027e1643a65ab5fe17cc01233d376d (diff)
tty: Move parts of tty_init_dev into new functions
Move the 'find-tty' and 'fast-track-open' parts of init_dev() to separate functions. Signed-off-by: Sukadev Bhattiprolu <sukadev@us.ibm.com> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c139
1 files changed, 87 insertions, 52 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index fdcc43c8ef3c..a5408496d301 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1204,6 +1204,80 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
1204 sprintf(p, "%s%d", driver->name, index + driver->name_base); 1204 sprintf(p, "%s%d", driver->name, index + driver->name_base);
1205} 1205}
1206 1206
1207/*
1208 * find_tty() - find an existing tty, if any
1209 * @driver: the driver for the tty
1210 * @idx: the minor number
1211 *
1212 * Return the tty, if found or ERR_PTR() otherwise.
1213 *
1214 * Locking: tty_mutex must be held. If tty is found, the mutex must
1215 * be held until the 'fast-open' is also done.
1216 */
1217struct tty_struct *find_tty(struct tty_driver *driver, int idx)
1218{
1219 struct tty_struct *tty;
1220
1221 /* check whether we're reopening an existing tty */
1222 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
1223 tty = devpts_get_tty(idx);
1224 /*
1225 * If we don't have a tty here on a slave open, it's because
1226 * the master already started the close process and there's
1227 * no relation between devpts file and tty anymore.
1228 */
1229 if (!tty && driver->subtype == PTY_TYPE_SLAVE)
1230 return ERR_PTR(-EIO);
1231
1232 /*
1233 * tty is safe on because we are called with tty_mutex held
1234 * and release_dev() won't change tty->count or tty->flags
1235 * without grabbing tty_mutex.
1236 */
1237 if (tty && driver->subtype == PTY_TYPE_MASTER)
1238 tty = tty->link;
1239 } else
1240 tty = driver->ttys[idx];
1241 return tty;
1242}
1243
1244/*
1245 * fast_tty_open() - fast re-open of an open tty
1246 * @tty - the tty to open
1247 *
1248 * Return 0 on success, -errno on error.
1249 *
1250 * Locking: tty_mutex must be held from the time the tty was found
1251 * till this open completes.
1252 */
1253static int fast_tty_open(struct tty_struct *tty)
1254{
1255 struct tty_driver *driver = tty->driver;
1256
1257 if (test_bit(TTY_CLOSING, &tty->flags))
1258 return -EIO;
1259
1260 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1261 driver->subtype == PTY_TYPE_MASTER) {
1262 /*
1263 * special case for PTY masters: only one open permitted,
1264 * and the slave side open count is incremented as well.
1265 */
1266 if (tty->count)
1267 return -EIO;
1268
1269 tty->link->count++;
1270 }
1271 tty->count++;
1272 tty->driver = driver; /* N.B. why do this every time?? */
1273
1274 /* FIXME */
1275 if (!test_bit(TTY_LDISC, &tty->flags))
1276 printk(KERN_ERR "fast_tty_open: no ldisc\n");
1277
1278 return 0;
1279}
1280
1207/** 1281/**
1208 * tty_init_dev - initialise a tty device 1282 * tty_init_dev - initialise a tty device
1209 * @driver: tty driver we are opening a device on 1283 * @driver: tty driver we are opening a device on
@@ -1238,29 +1312,21 @@ int tty_init_dev(struct tty_driver *driver, int idx,
1238 int retval = 0; 1312 int retval = 0;
1239 1313
1240 /* check whether we're reopening an existing tty */ 1314 /* check whether we're reopening an existing tty */
1241 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { 1315 tty = find_tty(driver, idx);
1242 tty = devpts_get_tty(idx); 1316 if (IS_ERR(tty)) {
1243 /* 1317 retval = PTR_ERR(tty);
1244 * If we don't have a tty here on a slave open, it's because 1318 goto end_init;
1245 * the master already started the close process and there's 1319 }
1246 * no relation between devpts file and tty anymore. 1320
1247 */ 1321 if (tty) {
1248 if (!tty && driver->subtype == PTY_TYPE_SLAVE) { 1322 retval = fast_tty_open(tty);
1249 retval = -EIO; 1323 if (retval)
1250 goto end_init; 1324 return retval;
1251 } 1325 *ret_tty = tty;
1252 /* 1326 return 0;
1253 * It's safe from now on because tty_init_dev() is called with
1254 * tty_mutex held and tty_release_dev() won't change tty->count
1255 * or tty->flags without having to grab tty_mutex
1256 */
1257 if (tty && driver->subtype == PTY_TYPE_MASTER)
1258 tty = tty->link;
1259 } else {
1260 tty = driver->ttys[idx];
1261 } 1327 }
1262 if (tty) goto fast_track;
1263 1328
1329 /* Check if pty master is being opened multiple times */
1264 if (driver->subtype == PTY_TYPE_MASTER && 1330 if (driver->subtype == PTY_TYPE_MASTER &&
1265 (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { 1331 (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
1266 retval = -EIO; 1332 retval = -EIO;
@@ -1400,37 +1466,6 @@ int tty_init_dev(struct tty_driver *driver, int idx,
1400 1466
1401 if (retval) 1467 if (retval)
1402 goto release_mem_out; 1468 goto release_mem_out;
1403 goto success;
1404
1405 /*
1406 * This fast open can be used if the tty is already open.
1407 * No memory is allocated, and the only failures are from
1408 * attempting to open a closing tty or attempting multiple
1409 * opens on a pty master.
1410 */
1411fast_track:
1412 if (test_bit(TTY_CLOSING, &tty->flags)) {
1413 retval = -EIO;
1414 goto end_init;
1415 }
1416 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1417 driver->subtype == PTY_TYPE_MASTER) {
1418 /*
1419 * special case for PTY masters: only one open permitted,
1420 * and the slave side open count is incremented as well.
1421 */
1422 if (tty->count) {
1423 retval = -EIO;
1424 goto end_init;
1425 }
1426 tty->link->count++;
1427 }
1428 tty->count++;
1429 tty->driver = driver; /* N.B. why do this every time?? */
1430
1431 /* FIXME */
1432 if (!test_bit(TTY_LDISC, &tty->flags))
1433 printk(KERN_ERR "tty_init_dev but no ldisc\n");
1434success: 1469success:
1435 *ret_tty = tty; 1470 *ret_tty = tty;
1436 1471