aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/line.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/line.c')
-rw-r--r--arch/um/drivers/line.c66
1 files changed, 39 insertions, 27 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 799fca3644e9..e620ed46ed3f 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -549,14 +549,16 @@ void close_lines(struct line *lines, int nlines)
549 close_chan(&lines[i].chan_list, 0); 549 close_chan(&lines[i].chan_list, 0);
550} 550}
551 551
552static void setup_one_line(struct line *lines, int n, char *init, int init_prio) 552static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
553 char **error_out)
553{ 554{
554 struct line *line = &lines[n]; 555 struct line *line = &lines[n];
556 int err = -EINVAL;
555 557
556 spin_lock(&line->count_lock); 558 spin_lock(&line->count_lock);
557 559
558 if(line->tty != NULL){ 560 if(line->tty != NULL){
559 printk("line_setup - device %d is open\n", n); 561 *error_out = "Device is already open";
560 goto out; 562 goto out;
561 } 563 }
562 564
@@ -569,18 +571,22 @@ static void setup_one_line(struct line *lines, int n, char *init, int init_prio)
569 line->valid = 1; 571 line->valid = 1;
570 } 572 }
571 } 573 }
574 err = 0;
572out: 575out:
573 spin_unlock(&line->count_lock); 576 spin_unlock(&line->count_lock);
577 return err;
574} 578}
575 579
576/* Common setup code for both startup command line and mconsole initialization. 580/* Common setup code for both startup command line and mconsole initialization.
577 * @lines contains the array (of size @num) to modify; 581 * @lines contains the array (of size @num) to modify;
578 * @init is the setup string; 582 * @init is the setup string;
583 * @error_out is an error string in the case of failure;
579 */ 584 */
580 585
581int line_setup(struct line *lines, unsigned int num, char *init) 586int line_setup(struct line *lines, unsigned int num, char *init,
587 char **error_out)
582{ 588{
583 int i, n; 589 int i, n, err;
584 char *end; 590 char *end;
585 591
586 if(*init == '=') { 592 if(*init == '=') {
@@ -591,52 +597,56 @@ int line_setup(struct line *lines, unsigned int num, char *init)
591 else { 597 else {
592 n = simple_strtoul(init, &end, 0); 598 n = simple_strtoul(init, &end, 0);
593 if(*end != '='){ 599 if(*end != '='){
594 printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 600 *error_out = "Couldn't parse device number";
595 init); 601 return -EINVAL;
596 return 0;
597 } 602 }
598 init = end; 603 init = end;
599 } 604 }
600 init++; 605 init++;
601 606
602 if (n >= (signed int) num) { 607 if (n >= (signed int) num) {
603 printk("line_setup - %d out of range ((0 ... %d) allowed)\n", 608 *error_out = "Device number out of range";
604 n, num - 1); 609 return -EINVAL;
605 return 0; 610 }
611 else if (n >= 0){
612 err = setup_one_line(lines, n, init, INIT_ONE, error_out);
613 if(err)
614 return err;
606 } 615 }
607 else if (n >= 0)
608 setup_one_line(lines, n, init, INIT_ONE);
609 else { 616 else {
610 for(i = 0; i < num; i++) 617 for(i = 0; i < num; i++){
611 setup_one_line(lines, i, init, INIT_ALL); 618 err = setup_one_line(lines, i, init, INIT_ALL,
619 error_out);
620 if(err)
621 return err;
622 }
612 } 623 }
613 return n == -1 ? num : n; 624 return n == -1 ? num : n;
614} 625}
615 626
616int line_config(struct line *lines, unsigned int num, char *str, 627int line_config(struct line *lines, unsigned int num, char *str,
617 const struct chan_opts *opts) 628 const struct chan_opts *opts, char **error_out)
618{ 629{
619 struct line *line; 630 struct line *line;
620 char *new; 631 char *new;
621 int n; 632 int n;
622 633
623 if(*str == '='){ 634 if(*str == '='){
624 printk("line_config - can't configure all devices from " 635 *error_out = "Can't configure all devices from mconsole";
625 "mconsole\n"); 636 return -EINVAL;
626 return 1;
627 } 637 }
628 638
629 new = kstrdup(str, GFP_KERNEL); 639 new = kstrdup(str, GFP_KERNEL);
630 if(new == NULL){ 640 if(new == NULL){
631 printk("line_config - kstrdup failed\n"); 641 *error_out = "Failed to allocate memory";
632 return 1; 642 return -ENOMEM;
633 } 643 }
634 n = line_setup(lines, num, new); 644 n = line_setup(lines, num, new, error_out);
635 if(n < 0) 645 if(n < 0)
636 return 1; 646 return n;
637 647
638 line = &lines[n]; 648 line = &lines[n];
639 return parse_chan_pair(line->init_str, line, n, opts); 649 return parse_chan_pair(line->init_str, line, n, opts, error_out);
640} 650}
641 651
642int line_get_config(char *name, struct line *lines, unsigned int num, char *str, 652int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
@@ -685,13 +695,13 @@ int line_id(char **str, int *start_out, int *end_out)
685 return n; 695 return n;
686} 696}
687 697
688int line_remove(struct line *lines, unsigned int num, int n) 698int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
689{ 699{
690 int err; 700 int err;
691 char config[sizeof("conxxxx=none\0")]; 701 char config[sizeof("conxxxx=none\0")];
692 702
693 sprintf(config, "%d=none", n); 703 sprintf(config, "%d=none", n);
694 err = line_setup(lines, num, config); 704 err = line_setup(lines, num, config, error_out);
695 if(err >= 0) 705 if(err >= 0)
696 err = 0; 706 err = 0;
697 return err; 707 return err;
@@ -740,6 +750,7 @@ static LIST_HEAD(winch_handlers);
740void lines_init(struct line *lines, int nlines, struct chan_opts *opts) 750void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
741{ 751{
742 struct line *line; 752 struct line *line;
753 char *error;
743 int i; 754 int i;
744 755
745 for(i = 0; i < nlines; i++){ 756 for(i = 0; i < nlines; i++){
@@ -754,8 +765,9 @@ void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
754 if(line->init_str == NULL) 765 if(line->init_str == NULL)
755 printk("lines_init - kstrdup returned NULL\n"); 766 printk("lines_init - kstrdup returned NULL\n");
756 767
757 if(parse_chan_pair(line->init_str, line, i, opts)){ 768 if(parse_chan_pair(line->init_str, line, i, opts, &error)){
758 printk("parse_chan_pair failed for device %d\n", i); 769 printk("parse_chan_pair failed for device %d : %s\n",
770 i, error);
759 line->valid = 0; 771 line->valid = 0;
760 } 772 }
761 } 773 }