diff options
Diffstat (limited to 'arch/um/drivers/line.c')
-rw-r--r-- | arch/um/drivers/line.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 1a8d6591c20..015209a9881 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -485,6 +485,7 @@ static int setup_one_line(struct line *lines, int n, char *init, | |||
485 | const struct chan_opts *opts, char **error_out) | 485 | const struct chan_opts *opts, char **error_out) |
486 | { | 486 | { |
487 | struct line *line = &lines[n]; | 487 | struct line *line = &lines[n]; |
488 | struct tty_driver *driver = line->driver->driver; | ||
488 | int err = -EINVAL; | 489 | int err = -EINVAL; |
489 | 490 | ||
490 | mutex_lock(&line->count_lock); | 491 | mutex_lock(&line->count_lock); |
@@ -498,6 +499,7 @@ static int setup_one_line(struct line *lines, int n, char *init, | |||
498 | if (line->valid) { | 499 | if (line->valid) { |
499 | line->valid = 0; | 500 | line->valid = 0; |
500 | kfree(line->init_str); | 501 | kfree(line->init_str); |
502 | tty_unregister_device(driver, n); | ||
501 | parse_chan_pair(NULL, line, n, opts, error_out); | 503 | parse_chan_pair(NULL, line, n, opts, error_out); |
502 | err = 0; | 504 | err = 0; |
503 | } | 505 | } |
@@ -507,9 +509,19 @@ static int setup_one_line(struct line *lines, int n, char *init, | |||
507 | *error_out = "Failed to allocate memory"; | 509 | *error_out = "Failed to allocate memory"; |
508 | return -ENOMEM; | 510 | return -ENOMEM; |
509 | } | 511 | } |
512 | if (line->valid) | ||
513 | tty_unregister_device(driver, n); | ||
510 | line->init_str = new; | 514 | line->init_str = new; |
511 | line->valid = 1; | 515 | line->valid = 1; |
512 | err = parse_chan_pair(new, line, n, opts, error_out); | 516 | err = parse_chan_pair(new, line, n, opts, error_out); |
517 | if (!err) { | ||
518 | struct device *d = tty_register_device(driver, n, NULL); | ||
519 | if (IS_ERR(d)) { | ||
520 | *error_out = "Failed to register device"; | ||
521 | err = PTR_ERR(d); | ||
522 | parse_chan_pair(NULL, line, n, opts, error_out); | ||
523 | } | ||
524 | } | ||
513 | if (err) { | 525 | if (err) { |
514 | line->init_str = NULL; | 526 | line->init_str = NULL; |
515 | line->valid = 0; | 527 | line->valid = 0; |
@@ -640,15 +652,15 @@ int line_remove(struct line *lines, unsigned int num, int n, char **error_out) | |||
640 | return setup_one_line(lines, n, "none", NULL, error_out); | 652 | return setup_one_line(lines, n, "none", NULL, error_out); |
641 | } | 653 | } |
642 | 654 | ||
643 | struct tty_driver *register_lines(struct line_driver *line_driver, | 655 | int register_lines(struct line_driver *line_driver, |
644 | const struct tty_operations *ops, | 656 | const struct tty_operations *ops, |
645 | struct line *lines, int nlines) | 657 | struct line *lines, int nlines) |
646 | { | 658 | { |
647 | int i; | ||
648 | struct tty_driver *driver = alloc_tty_driver(nlines); | 659 | struct tty_driver *driver = alloc_tty_driver(nlines); |
660 | int err; | ||
649 | 661 | ||
650 | if (!driver) | 662 | if (!driver) |
651 | return NULL; | 663 | return -ENOMEM; |
652 | 664 | ||
653 | driver->driver_name = line_driver->name; | 665 | driver->driver_name = line_driver->name; |
654 | driver->name = line_driver->device_name; | 666 | driver->name = line_driver->device_name; |
@@ -656,24 +668,21 @@ struct tty_driver *register_lines(struct line_driver *line_driver, | |||
656 | driver->minor_start = line_driver->minor_start; | 668 | driver->minor_start = line_driver->minor_start; |
657 | driver->type = line_driver->type; | 669 | driver->type = line_driver->type; |
658 | driver->subtype = line_driver->subtype; | 670 | driver->subtype = line_driver->subtype; |
659 | driver->flags = TTY_DRIVER_REAL_RAW; | 671 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
660 | driver->init_termios = tty_std_termios; | 672 | driver->init_termios = tty_std_termios; |
661 | tty_set_operations(driver, ops); | 673 | tty_set_operations(driver, ops); |
662 | 674 | ||
663 | if (tty_register_driver(driver)) { | 675 | err = tty_register_driver(driver); |
676 | if (err) { | ||
664 | printk(KERN_ERR "register_lines : can't register %s driver\n", | 677 | printk(KERN_ERR "register_lines : can't register %s driver\n", |
665 | line_driver->name); | 678 | line_driver->name); |
666 | put_tty_driver(driver); | 679 | put_tty_driver(driver); |
667 | return NULL; | 680 | return err; |
668 | } | ||
669 | |||
670 | for(i = 0; i < nlines; i++) { | ||
671 | if (!lines[i].valid) | ||
672 | tty_unregister_device(driver, i); | ||
673 | } | 681 | } |
674 | 682 | ||
683 | line_driver->driver = driver; | ||
675 | mconsole_register_dev(&line_driver->mc); | 684 | mconsole_register_dev(&line_driver->mc); |
676 | return driver; | 685 | return 0; |
677 | } | 686 | } |
678 | 687 | ||
679 | static DEFINE_SPINLOCK(winch_handler_lock); | 688 | static DEFINE_SPINLOCK(winch_handler_lock); |