diff options
author | Sukadev Bhattiprolu <sukadev@us.ibm.com> | 2008-10-13 05:41:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:42 -0400 |
commit | 23499705753ab8b4c6b0b64e6c424a370bd900a1 (patch) | |
tree | db092164c37a2c2897275a37d61ef325a59808d9 /drivers/char/tty_io.c | |
parent | d81ed10307027e1643a65ab5fe17cc01233d376d (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.c | 139 |
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 | */ | ||
1217 | struct 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 | */ | ||
1253 | static 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 | */ | ||
1411 | fast_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"); | ||
1434 | success: | 1469 | success: |
1435 | *ret_tty = tty; | 1470 | *ret_tty = tty; |
1436 | 1471 | ||