diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:42:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:43 -0400 |
commit | bf970ee46e0fb363c8df4393229121d54330a98e (patch) | |
tree | 3beb09c369b3459e70689b5f9a35caacf063f116 /drivers/char/pty.c | |
parent | 73ec06fc5f5c8e1097a7a4a4ab2d7c6c3a007e81 (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.c | 126 |
1 files changed, 114 insertions, 12 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 | ||
230 | static 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; | ||
273 | free_mem_out: | ||
274 | module_put(o_tty->driver->owner); | ||
275 | free_tty_struct(o_tty); | ||
276 | return -ENOMEM; | ||
277 | } | ||
278 | |||
279 | |||
230 | static const struct tty_operations pty_ops = { | 280 | static 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) { } | |||
332 | int pty_limit = NR_UNIX98_PTY_DEFAULT; | 383 | int pty_limit = NR_UNIX98_PTY_DEFAULT; |
333 | static int pty_limit_min = 0; | 384 | static int pty_limit_min = 0; |
334 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 385 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
386 | static int pty_count = 0; | ||
335 | 387 | ||
336 | static struct cdev ptmx_cdev; | 388 | static 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 | ||
429 | static void pty_shutdown(struct tty_struct *tty) | 482 | static 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 | ||
439 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | 492 | static 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; |
537 | free_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 | ||
444 | static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) | 548 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
445 | { | 549 | { |
550 | pty_count--; | ||
446 | } | 551 | } |
447 | 552 | ||
448 | static const struct tty_operations ptm_unix98_ops = { | 553 | static 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 | ||
464 | static const struct tty_operations pty_unix98_ops = { | 569 | static 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 */ |