aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/pty.c126
-rw-r--r--drivers/char/tty_io.c198
-rw-r--r--include/linux/tty.h5
3 files changed, 187 insertions, 142 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index c98450023030..c5a192dd00db 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -227,7 +227,58 @@ static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios
227 tty->termios->c_cflag |= (CS8 | CREAD); 227 tty->termios->c_cflag |= (CS8 | CREAD);
228} 228}
229 229
230static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
231{
232 struct tty_struct *o_tty;
233 int idx = tty->index;
234 int retval;
235
236 o_tty = alloc_tty_struct();
237 if (!o_tty)
238 return -ENOMEM;
239 if (!try_module_get(driver->other->owner)) {
240 /* This cannot in fact currently happen */
241 free_tty_struct(o_tty);
242 return -ENOMEM;
243 }
244 initialize_tty_struct(o_tty, driver->other, idx);
245
246 /* We always use new tty termios data so we can do this
247 the easy way .. */
248 retval = tty_init_termios(tty);
249 if (retval)
250 goto free_mem_out;
251
252 retval = tty_init_termios(o_tty);
253 if (retval) {
254 tty_free_termios(tty);
255 goto free_mem_out;
256 }
257
258 /*
259 * Everything allocated ... set up the o_tty structure.
260 */
261 driver->other->ttys[idx] = o_tty;
262 tty_driver_kref_get(driver->other);
263 if (driver->subtype == PTY_TYPE_MASTER)
264 o_tty->count++;
265 /* Establish the links in both directions */
266 tty->link = o_tty;
267 o_tty->link = tty;
268
269 tty_driver_kref_get(driver);
270 tty->count++;
271 driver->ttys[idx] = tty;
272 return 0;
273free_mem_out:
274 module_put(o_tty->driver->owner);
275 free_tty_struct(o_tty);
276 return -ENOMEM;
277}
278
279
230static const struct tty_operations pty_ops = { 280static const struct tty_operations pty_ops = {
281 .install = pty_install,
231 .open = pty_open, 282 .open = pty_open,
232 .close = pty_close, 283 .close = pty_close,
233 .write = pty_write, 284 .write = pty_write,
@@ -332,6 +383,7 @@ static inline void legacy_pty_init(void) { }
332int pty_limit = NR_UNIX98_PTY_DEFAULT; 383int pty_limit = NR_UNIX98_PTY_DEFAULT;
333static int pty_limit_min = 0; 384static int pty_limit_min = 0;
334static int pty_limit_max = NR_UNIX98_PTY_MAX; 385static int pty_limit_max = NR_UNIX98_PTY_MAX;
386static int pty_count = 0;
335 387
336static struct cdev ptmx_cdev; 388static struct cdev ptmx_cdev;
337 389
@@ -351,6 +403,7 @@ static struct ctl_table pty_table[] = {
351 .procname = "nr", 403 .procname = "nr",
352 .maxlen = sizeof(int), 404 .maxlen = sizeof(int),
353 .mode = 0444, 405 .mode = 0444,
406 .data = &pty_count,
354 .proc_handler = &proc_dointvec, 407 .proc_handler = &proc_dointvec,
355 }, { 408 }, {
356 .ctl_name = 0 409 .ctl_name = 0
@@ -426,7 +479,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, int idx)
426 return tty; 479 return tty;
427} 480}
428 481
429static void pty_shutdown(struct tty_struct *tty) 482static void pty_unix98_shutdown(struct tty_struct *tty)
430{ 483{
431 /* We have our own method as we don't use the tty index */ 484 /* We have our own method as we don't use the tty index */
432 kfree(tty->termios); 485 kfree(tty->termios);
@@ -436,19 +489,71 @@ static void pty_shutdown(struct tty_struct *tty)
436/* We have no need to install and remove our tty objects as devpts does all 489/* We have no need to install and remove our tty objects as devpts does all
437 the work for us */ 490 the work for us */
438 491
439static int pty_install(struct tty_driver *driver, struct tty_struct *tty) 492static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
440{ 493{
494 struct tty_struct *o_tty;
495 int idx = tty->index;
496
497 o_tty = alloc_tty_struct();
498 if (!o_tty)
499 return -ENOMEM;
500 if (!try_module_get(driver->other->owner)) {
501 /* This cannot in fact currently happen */
502 free_tty_struct(o_tty);
503 return -ENOMEM;
504 }
505 initialize_tty_struct(o_tty, driver->other, idx);
506
507 tty->termios = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
508 if (tty->termios == NULL)
509 goto free_mem_out;
510 *tty->termios = driver->init_termios;
511 tty->termios_locked = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
512 if (tty->termios_locked == NULL)
513 goto free_mem_out;
514 o_tty->termios = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
515 if (o_tty->termios == NULL)
516 goto free_mem_out;
517 *o_tty->termios = driver->other->init_termios;
518 o_tty->termios_locked = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
519 if (o_tty->termios_locked == NULL)
520 goto free_mem_out;
521
522 tty_driver_kref_get(driver->other);
523 if (driver->subtype == PTY_TYPE_MASTER)
524 o_tty->count++;
525 /* Establish the links in both directions */
526 tty->link = o_tty;
527 o_tty->link = tty;
528 /*
529 * All structures have been allocated, so now we install them.
530 * Failures after this point use release_tty to clean up, so
531 * there's no need to null out the local pointers.
532 */
533 tty_driver_kref_get(driver);
534 tty->count++;
535 pty_count++;
441 return 0; 536 return 0;
537free_mem_out:
538 kfree(o_tty->termios);
539 module_put(o_tty->driver->owner);
540 free_tty_struct(o_tty);
541 kfree(tty->termios_locked);
542 kfree(tty->termios);
543 free_tty_struct(tty);
544 module_put(driver->owner);
545 return -ENOMEM;
442} 546}
443 547
444static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) 548static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
445{ 549{
550 pty_count--;
446} 551}
447 552
448static const struct tty_operations ptm_unix98_ops = { 553static const struct tty_operations ptm_unix98_ops = {
449 .lookup = ptm_unix98_lookup, 554 .lookup = ptm_unix98_lookup,
450 .install = pty_install, 555 .install = pty_unix98_install,
451 .remove = pty_remove, 556 .remove = pty_unix98_remove,
452 .open = pty_open, 557 .open = pty_open,
453 .close = pty_close, 558 .close = pty_close,
454 .write = pty_write, 559 .write = pty_write,
@@ -458,13 +563,13 @@ static const struct tty_operations ptm_unix98_ops = {
458 .unthrottle = pty_unthrottle, 563 .unthrottle = pty_unthrottle,
459 .set_termios = pty_set_termios, 564 .set_termios = pty_set_termios,
460 .ioctl = pty_unix98_ioctl, 565 .ioctl = pty_unix98_ioctl,
461 .shutdown = pty_shutdown 566 .shutdown = pty_unix98_shutdown
462}; 567};
463 568
464static const struct tty_operations pty_unix98_ops = { 569static const struct tty_operations pty_unix98_ops = {
465 .lookup = pts_unix98_lookup, 570 .lookup = pts_unix98_lookup,
466 .install = pty_install, 571 .install = pty_unix98_install,
467 .remove = pty_remove, 572 .remove = pty_unix98_remove,
468 .open = pty_open, 573 .open = pty_open,
469 .close = pty_close, 574 .close = pty_close,
470 .write = pty_write, 575 .write = pty_write,
@@ -473,6 +578,7 @@ static const struct tty_operations pty_unix98_ops = {
473 .chars_in_buffer = pty_chars_in_buffer, 578 .chars_in_buffer = pty_chars_in_buffer,
474 .unthrottle = pty_unthrottle, 579 .unthrottle = pty_unthrottle,
475 .set_termios = pty_set_termios, 580 .set_termios = pty_set_termios,
581 .shutdown = pty_unix98_shutdown
476}; 582};
477 583
478/** 584/**
@@ -589,10 +695,6 @@ static void __init unix98_pty_init(void)
589 if (tty_register_driver(pts_driver)) 695 if (tty_register_driver(pts_driver))
590 panic("Couldn't register Unix98 pts driver"); 696 panic("Couldn't register Unix98 pts driver");
591 697
592 /* FIXME: WTF */
593#if 0
594 pty_table[1].data = &ptm_driver->refcount;
595#endif
596 register_sysctl_table(pty_root_table); 698 register_sysctl_table(pty_root_table);
597 699
598 /* Now create the /dev/ptmx special device */ 700 /* Now create the /dev/ptmx special device */
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/**
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 54523a37e956..3c7c75794a4a 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -401,9 +401,14 @@ extern dev_t tty_devnum(struct tty_struct *tty);
401extern void proc_clear_tty(struct task_struct *p); 401extern void proc_clear_tty(struct task_struct *p);
402extern struct tty_struct *get_current_tty(void); 402extern struct tty_struct *get_current_tty(void);
403extern void tty_default_fops(struct file_operations *fops); 403extern void tty_default_fops(struct file_operations *fops);
404extern struct tty_struct *alloc_tty_struct(void);
405extern void free_tty_struct(struct tty_struct *tty);
406extern void initialize_tty_struct(struct tty_struct *tty,
407 struct tty_driver *driver, int idx);
404extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, 408extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
405 int first_ok); 409 int first_ok);
406extern void tty_release_dev(struct file *filp); 410extern void tty_release_dev(struct file *filp);
411extern int tty_init_termios(struct tty_struct *tty);
407 412
408extern struct mutex tty_mutex; 413extern struct mutex tty_mutex;
409 414