aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/pty.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/pty.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/pty.c')
-rw-r--r--drivers/char/pty.c126
1 files changed, 114 insertions, 12 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index c9845002303..c5a192dd00d 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 */