aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:42:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:43 -0400
commitbf970ee46e0fb363c8df4393229121d54330a98e (patch)
tree3beb09c369b3459e70689b5f9a35caacf063f116 /drivers/char/tty_io.c
parent73ec06fc5f5c8e1097a7a4a4ab2d7c6c3a007e81 (diff)
tty: extract the pty init time special cases
The majority of the remaining init_dev code is pty special cases. We refactor this code into the driver->install method. 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.c198
1 files changed, 68 insertions, 130 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index b0ad4880c3a8..e881e9ed08de 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -136,8 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
136DEFINE_MUTEX(tty_mutex); 136DEFINE_MUTEX(tty_mutex);
137EXPORT_SYMBOL(tty_mutex); 137EXPORT_SYMBOL(tty_mutex);
138 138
139static void initialize_tty_struct(struct tty_struct *tty);
140
141static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); 139static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
142static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); 140static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
143ssize_t redirected_tty_write(struct file *, const char __user *, 141ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -166,7 +164,7 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
166 * Locking: none 164 * Locking: none
167 */ 165 */
168 166
169static struct tty_struct *alloc_tty_struct(void) 167struct tty_struct *alloc_tty_struct(void)
170{ 168{
171 return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); 169 return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
172} 170}
@@ -180,7 +178,7 @@ static struct tty_struct *alloc_tty_struct(void)
180 * Locking: none. Must be called after tty is definitely unused 178 * Locking: none. Must be called after tty is definitely unused
181 */ 179 */
182 180
183static inline void free_tty_struct(struct tty_struct *tty) 181void free_tty_struct(struct tty_struct *tty)
184{ 182{
185 kfree(tty->write_buf); 183 kfree(tty->write_buf);
186 tty_buffer_free_all(tty); 184 tty_buffer_free_all(tty);
@@ -1227,22 +1225,70 @@ struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, int idx)
1227} 1225}
1228 1226
1229/** 1227/**
1228 * tty_init_termios - helper for termios setup
1229 * @tty: the tty to set up
1230 *
1231 * Initialise the termios structures for this tty. Thus runs under
1232 * the tty_mutex currently so we can be relaxed about ordering.
1233 */
1234
1235int tty_init_termios(struct tty_struct *tty)
1236{
1237 struct ktermios *tp, *ltp;
1238 int idx = tty->index;
1239
1240 tp = tty->driver->termios[idx];
1241 ltp = tty->driver->termios_locked[idx];
1242 if (tp == NULL) {
1243 WARN_ON(ltp != NULL);
1244 tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
1245 ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
1246 if (tp == NULL || ltp == NULL) {
1247 kfree(tp);
1248 kfree(ltp);
1249 return -ENOMEM;
1250 }
1251 memcpy(tp, &tty->driver->init_termios,
1252 sizeof(struct ktermios));
1253 tty->driver->termios[idx] = tp;
1254 tty->driver->termios_locked[idx] = ltp;
1255 }
1256 tty->termios = tp;
1257 tty->termios_locked = ltp;
1258
1259 /* Compatibility until drivers always set this */
1260 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1261 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1262 return 0;
1263}
1264
1265/**
1230 * tty_driver_install_tty() - install a tty entry in the driver 1266 * tty_driver_install_tty() - install a tty entry in the driver
1231 * @driver: the driver for the tty 1267 * @driver: the driver for the tty
1232 * @tty: the tty 1268 * @tty: the tty
1233 * 1269 *
1234 * Install a tty object into the driver tables. The tty->index field 1270 * Install a tty object into the driver tables. The tty->index field
1235 * will be set by the time this is called. 1271 * will be set by the time this is called. This method is responsible
1272 * for ensuring any need additional structures are allocated and
1273 * configured.
1236 * 1274 *
1237 * Locking: tty_mutex for now 1275 * Locking: tty_mutex for now
1238 */ 1276 */
1239static int tty_driver_install_tty(struct tty_driver *driver, 1277static int tty_driver_install_tty(struct tty_driver *driver,
1240 struct tty_struct *tty) 1278 struct tty_struct *tty)
1241{ 1279{
1280 int idx = tty->index;
1281
1242 if (driver->ops->install) 1282 if (driver->ops->install)
1243 return driver->ops->install(driver, tty); 1283 return driver->ops->install(driver, tty);
1244 driver->ttys[tty->index] = tty; 1284
1245 return 0; 1285 if (tty_init_termios(tty) == 0) {
1286 tty_driver_kref_get(driver);
1287 tty->count++;
1288 driver->ttys[idx] = tty;
1289 return 0;
1290 }
1291 return -ENOMEM;
1246} 1292}
1247 1293
1248/** 1294/**
@@ -1327,9 +1373,7 @@ static int tty_reopen(struct tty_struct *tty)
1327struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, 1373struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
1328 int first_ok) 1374 int first_ok)
1329{ 1375{
1330 struct tty_struct *tty, *o_tty; 1376 struct tty_struct *tty;
1331 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
1332 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
1333 int retval; 1377 int retval;
1334 1378
1335 /* check whether we're reopening an existing tty */ 1379 /* check whether we're reopening an existing tty */
@@ -1361,118 +1405,17 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
1361 if (!try_module_get(driver->owner)) 1405 if (!try_module_get(driver->owner))
1362 return ERR_PTR(-ENODEV); 1406 return ERR_PTR(-ENODEV);
1363 1407
1364 o_tty = NULL;
1365 tp = o_tp = NULL;
1366 ltp = o_ltp = NULL;
1367
1368 tty = alloc_tty_struct(); 1408 tty = alloc_tty_struct();
1369 if (!tty) 1409 if (!tty)
1370 goto fail_no_mem; 1410 goto fail_no_mem;
1371 initialize_tty_struct(tty); 1411 initialize_tty_struct(tty, driver, idx);
1372 tty->driver = driver;
1373 tty->ops = driver->ops;
1374 tty->index = idx;
1375 tty_line_name(driver, idx, tty->name);
1376
1377 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
1378 tp_loc = &tty->termios;
1379 ltp_loc = &tty->termios_locked;
1380 } else {
1381 tp_loc = &driver->termios[idx];
1382 ltp_loc = &driver->termios_locked[idx];
1383 }
1384
1385 if (!*tp_loc) {
1386 tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
1387 if (!tp)
1388 goto free_mem_out;
1389 *tp = driver->init_termios;
1390 }
1391
1392 if (!*ltp_loc) {
1393 ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
1394 if (!ltp)
1395 goto free_mem_out;
1396 }
1397
1398 if (driver->type == TTY_DRIVER_TYPE_PTY) {
1399 o_tty = alloc_tty_struct();
1400 if (!o_tty)
1401 goto free_mem_out;
1402 if (!try_module_get(driver->other->owner)) {
1403 /* This cannot in fact currently happen */
1404 free_tty_struct(o_tty);
1405 o_tty = NULL;
1406 goto free_mem_out;
1407 }
1408 initialize_tty_struct(o_tty);
1409 o_tty->driver = driver->other;
1410 o_tty->ops = driver->ops;
1411 o_tty->index = idx;
1412 tty_line_name(driver->other, idx, o_tty->name);
1413
1414 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
1415 o_tp_loc = &o_tty->termios;
1416 o_ltp_loc = &o_tty->termios_locked;
1417 } else {
1418 o_tp_loc = &driver->other->termios[idx];
1419 o_ltp_loc = &driver->other->termios_locked[idx];
1420 }
1421
1422 if (!*o_tp_loc) {
1423 o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
1424 if (!o_tp)
1425 goto free_mem_out;
1426 *o_tp = driver->other->init_termios;
1427 }
1428
1429 if (!*o_ltp_loc) {
1430 o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
1431 if (!o_ltp)
1432 goto free_mem_out;
1433 }
1434
1435 /*
1436 * Everything allocated ... set up the o_tty structure.
1437 */
1438 if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM))
1439 driver->other->ttys[idx] = o_tty;
1440 if (!*o_tp_loc)
1441 *o_tp_loc = o_tp;
1442 if (!*o_ltp_loc)
1443 *o_ltp_loc = o_ltp;
1444 o_tty->termios = *o_tp_loc;
1445 o_tty->termios_locked = *o_ltp_loc;
1446 tty_driver_kref_get(driver->other);
1447 if (driver->subtype == PTY_TYPE_MASTER)
1448 o_tty->count++;
1449
1450 /* Establish the links in both directions */
1451 tty->link = o_tty;
1452 o_tty->link = tty;
1453 }
1454
1455 /*
1456 * All structures have been allocated, so now we install them.
1457 * Failures after this point use release_tty to clean up, so
1458 * there's no need to null out the local pointers.
1459 */
1460
1461 if (!*tp_loc)
1462 *tp_loc = tp;
1463 if (!*ltp_loc)
1464 *ltp_loc = ltp;
1465 tty->termios = *tp_loc;
1466 tty->termios_locked = *ltp_loc;
1467 /* Compatibility until drivers always set this */
1468 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1469 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1470 tty_driver_kref_get(driver);
1471 tty->count++;
1472 1412
1473 retval = tty_driver_install_tty(driver, tty); 1413 retval = tty_driver_install_tty(driver, tty);
1474 if (retval < 0) 1414 if (retval < 0) {
1475 goto release_mem_out; 1415 free_tty_struct(tty);
1416 module_put(driver->owner);
1417 return ERR_PTR(retval);
1418 }
1476 1419
1477 /* 1420 /*
1478 * Structures all installed ... call the ldisc open routines. 1421 * Structures all installed ... call the ldisc open routines.
@@ -1480,22 +1423,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
1480 * to decrement the use counts, as release_tty doesn't care. 1423 * to decrement the use counts, as release_tty doesn't care.
1481 */ 1424 */
1482 1425
1483 retval = tty_ldisc_setup(tty, o_tty); 1426 retval = tty_ldisc_setup(tty, tty->link);
1484 if (retval) 1427 if (retval)
1485 goto release_mem_out; 1428 goto release_mem_out;
1486 return tty; 1429 return tty;
1487 1430
1488 /* Release locally allocated memory ... nothing placed in slots */
1489free_mem_out:
1490 kfree(o_tp);
1491 if (o_tty) {
1492 module_put(o_tty->driver->owner);
1493 free_tty_struct(o_tty);
1494 }
1495 kfree(ltp);
1496 kfree(tp);
1497 free_tty_struct(tty);
1498
1499fail_no_mem: 1431fail_no_mem:
1500 module_put(driver->owner); 1432 module_put(driver->owner);
1501 return ERR_PTR(-ENOMEM); 1433 return ERR_PTR(-ENOMEM);
@@ -2852,7 +2784,8 @@ EXPORT_SYMBOL(do_SAK);
2852 * Locking: none - tty in question must not be exposed at this point 2784 * Locking: none - tty in question must not be exposed at this point
2853 */ 2785 */
2854 2786
2855static void initialize_tty_struct(struct tty_struct *tty) 2787void initialize_tty_struct(struct tty_struct *tty,
2788 struct tty_driver *driver, int idx)
2856{ 2789{
2857 memset(tty, 0, sizeof(struct tty_struct)); 2790 memset(tty, 0, sizeof(struct tty_struct));
2858 kref_init(&tty->kref); 2791 kref_init(&tty->kref);
@@ -2873,6 +2806,11 @@ static void initialize_tty_struct(struct tty_struct *tty)
2873 spin_lock_init(&tty->ctrl_lock); 2806 spin_lock_init(&tty->ctrl_lock);
2874 INIT_LIST_HEAD(&tty->tty_files); 2807 INIT_LIST_HEAD(&tty->tty_files);
2875 INIT_WORK(&tty->SAK_work, do_SAK_work); 2808 INIT_WORK(&tty->SAK_work, do_SAK_work);
2809
2810 tty->driver = driver;
2811 tty->ops = driver->ops;
2812 tty->index = idx;
2813 tty_line_name(driver, idx, tty->name);
2876} 2814}
2877 2815
2878/** 2816/**