diff options
author | Jeff Dike <jdike@addtoit.com> | 2005-06-25 17:55:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-25 19:24:36 -0400 |
commit | 29d56cfe3ca599ddc3ae9156e7e469c044d97b96 (patch) | |
tree | 7790477f5b138c249725fe8ecf9dc07794e9d1eb /arch/um/drivers | |
parent | fc47a0d18a1994b4a18d2235fcde1b75dfa72552 (diff) |
[PATCH] uml: hot-unplug code cleanup
Clean up the hot-unplugging code. There is now an id procedure which is
called to figure out what device we're talking to. The error messages from
that are now done from mconsole_remove instead of the driver. remove is now
called with the device number, after it has been checked, so doesn't need to
do sanity checking on it.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r-- | arch/um/drivers/line.c | 19 | ||||
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 36 | ||||
-rw-r--r-- | arch/um/drivers/net_kern.c | 31 | ||||
-rw-r--r-- | arch/um/drivers/ssl.c | 9 | ||||
-rw-r--r-- | arch/um/drivers/stdio_console.c | 7 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 37 |
6 files changed, 103 insertions, 36 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 0f59736db329..2bb4c4f5dec4 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -602,11 +602,26 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | |||
602 | return n; | 602 | return n; |
603 | } | 603 | } |
604 | 604 | ||
605 | int line_remove(struct line *lines, unsigned int num, char *str) | 605 | int line_id(char **str, int *start_out, int *end_out) |
606 | { | ||
607 | char *end; | ||
608 | int n; | ||
609 | |||
610 | n = simple_strtoul(*str, &end, 0); | ||
611 | if((*end != '\0') || (end == *str)) | ||
612 | return -1; | ||
613 | |||
614 | *str = end; | ||
615 | *start_out = n; | ||
616 | *end_out = n; | ||
617 | return n; | ||
618 | } | ||
619 | |||
620 | int line_remove(struct line *lines, unsigned int num, int n) | ||
606 | { | 621 | { |
607 | char config[sizeof("conxxxx=none\0")]; | 622 | char config[sizeof("conxxxx=none\0")]; |
608 | 623 | ||
609 | sprintf(config, "%s=none", str); | 624 | sprintf(config, "%d=none", n); |
610 | return !line_setup(lines, num, config, 0); | 625 | return !line_setup(lines, num, config, 0); |
611 | } | 626 | } |
612 | 627 | ||
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d7c7adcc0a67..404de41a4f67 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -419,8 +419,9 @@ void mconsole_config(struct mc_request *req) | |||
419 | void mconsole_remove(struct mc_request *req) | 419 | void mconsole_remove(struct mc_request *req) |
420 | { | 420 | { |
421 | struct mc_device *dev; | 421 | struct mc_device *dev; |
422 | char *ptr = req->request.data; | 422 | char *ptr = req->request.data, *err_msg = ""; |
423 | int err; | 423 | char error[256]; |
424 | int err, start, end, n; | ||
424 | 425 | ||
425 | ptr += strlen("remove"); | 426 | ptr += strlen("remove"); |
426 | while(isspace(*ptr)) ptr++; | 427 | while(isspace(*ptr)) ptr++; |
@@ -429,8 +430,35 @@ void mconsole_remove(struct mc_request *req) | |||
429 | mconsole_reply(req, "Bad remove option", 1, 0); | 430 | mconsole_reply(req, "Bad remove option", 1, 0); |
430 | return; | 431 | return; |
431 | } | 432 | } |
432 | err = (*dev->remove)(&ptr[strlen(dev->name)]); | 433 | |
433 | mconsole_reply(req, "", err, 0); | 434 | ptr = &ptr[strlen(dev->name)]; |
435 | |||
436 | err = 1; | ||
437 | n = (*dev->id)(&ptr, &start, &end); | ||
438 | if(n < 0){ | ||
439 | err_msg = "Couldn't parse device number"; | ||
440 | goto out; | ||
441 | } | ||
442 | else if((n < start) || (n > end)){ | ||
443 | sprintf(error, "Invalid device number - must be between " | ||
444 | "%d and %d", start, end); | ||
445 | err_msg = error; | ||
446 | goto out; | ||
447 | } | ||
448 | |||
449 | err = (*dev->remove)(n); | ||
450 | switch(err){ | ||
451 | case -ENODEV: | ||
452 | err_msg = "Device doesn't exist"; | ||
453 | break; | ||
454 | case -EBUSY: | ||
455 | err_msg = "Device is currently open"; | ||
456 | break; | ||
457 | default: | ||
458 | break; | ||
459 | } | ||
460 | out: | ||
461 | mconsole_reply(req, err_msg, err, 0); | ||
434 | } | 462 | } |
435 | 463 | ||
436 | #ifdef CONFIG_MAGIC_SYSRQ | 464 | #ifdef CONFIG_MAGIC_SYSRQ |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 5388a7428691..1495007bf6c0 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -612,25 +612,35 @@ static int net_config(char *str) | |||
612 | return(err); | 612 | return(err); |
613 | } | 613 | } |
614 | 614 | ||
615 | static int net_remove(char *str) | 615 | static int net_id(char **str, int *start_out, int *end_out) |
616 | { | ||
617 | char *end; | ||
618 | int n; | ||
619 | |||
620 | n = simple_strtoul(*str, &end, 0); | ||
621 | if((*end != '\0') || (end == *str)) | ||
622 | return -1; | ||
623 | |||
624 | *start_out = n; | ||
625 | *end_out = n; | ||
626 | *str = end; | ||
627 | return n; | ||
628 | } | ||
629 | |||
630 | static int net_remove(int n) | ||
616 | { | 631 | { |
617 | struct uml_net *device; | 632 | struct uml_net *device; |
618 | struct net_device *dev; | 633 | struct net_device *dev; |
619 | struct uml_net_private *lp; | 634 | struct uml_net_private *lp; |
620 | char *end; | ||
621 | int n; | ||
622 | |||
623 | n = simple_strtoul(str, &end, 0); | ||
624 | if((*end != '\0') || (end == str)) | ||
625 | return(-1); | ||
626 | 635 | ||
627 | device = find_device(n); | 636 | device = find_device(n); |
628 | if(device == NULL) | 637 | if(device == NULL) |
629 | return(0); | 638 | return -ENODEV; |
630 | 639 | ||
631 | dev = device->dev; | 640 | dev = device->dev; |
632 | lp = dev->priv; | 641 | lp = dev->priv; |
633 | if(lp->fd > 0) return(-1); | 642 | if(lp->fd > 0) |
643 | return -EBUSY; | ||
634 | if(lp->remove != NULL) (*lp->remove)(&lp->user); | 644 | if(lp->remove != NULL) (*lp->remove)(&lp->user); |
635 | unregister_netdev(dev); | 645 | unregister_netdev(dev); |
636 | platform_device_unregister(&device->pdev); | 646 | platform_device_unregister(&device->pdev); |
@@ -638,13 +648,14 @@ static int net_remove(char *str) | |||
638 | list_del(&device->list); | 648 | list_del(&device->list); |
639 | kfree(device); | 649 | kfree(device); |
640 | free_netdev(dev); | 650 | free_netdev(dev); |
641 | return(0); | 651 | return 0; |
642 | } | 652 | } |
643 | 653 | ||
644 | static struct mc_device net_mc = { | 654 | static struct mc_device net_mc = { |
645 | .name = "eth", | 655 | .name = "eth", |
646 | .config = net_config, | 656 | .config = net_config, |
647 | .get_config = NULL, | 657 | .get_config = NULL, |
658 | .id = net_id, | ||
648 | .remove = net_remove, | 659 | .remove = net_remove, |
649 | }; | 660 | }; |
650 | 661 | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index b32a77010fbe..62e04ecfada8 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -49,7 +49,7 @@ static struct chan_opts opts = { | |||
49 | 49 | ||
50 | static int ssl_config(char *str); | 50 | static int ssl_config(char *str); |
51 | static int ssl_get_config(char *dev, char *str, int size, char **error_out); | 51 | static int ssl_get_config(char *dev, char *str, int size, char **error_out); |
52 | static int ssl_remove(char *str); | 52 | static int ssl_remove(int n); |
53 | 53 | ||
54 | static struct line_driver driver = { | 54 | static struct line_driver driver = { |
55 | .name = "UML serial line", | 55 | .name = "UML serial line", |
@@ -69,6 +69,7 @@ static struct line_driver driver = { | |||
69 | .name = "ssl", | 69 | .name = "ssl", |
70 | .config = ssl_config, | 70 | .config = ssl_config, |
71 | .get_config = ssl_get_config, | 71 | .get_config = ssl_get_config, |
72 | .id = line_id, | ||
72 | .remove = ssl_remove, | 73 | .remove = ssl_remove, |
73 | }, | 74 | }, |
74 | }; | 75 | }; |
@@ -94,10 +95,10 @@ static int ssl_get_config(char *dev, char *str, int size, char **error_out) | |||
94 | str, size, error_out)); | 95 | str, size, error_out)); |
95 | } | 96 | } |
96 | 97 | ||
97 | static int ssl_remove(char *str) | 98 | static int ssl_remove(int n) |
98 | { | 99 | { |
99 | return(line_remove(serial_lines, | 100 | return line_remove(serial_lines, |
100 | sizeof(serial_lines)/sizeof(serial_lines[0]), str)); | 101 | sizeof(serial_lines)/sizeof(serial_lines[0]), n); |
101 | } | 102 | } |
102 | 103 | ||
103 | int ssl_open(struct tty_struct *tty, struct file *filp) | 104 | int ssl_open(struct tty_struct *tty, struct file *filp) |
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index afbe1e71ed83..005aa6333b6e 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -55,7 +55,7 @@ static struct chan_opts opts = { | |||
55 | 55 | ||
56 | static int con_config(char *str); | 56 | static int con_config(char *str); |
57 | static int con_get_config(char *dev, char *str, int size, char **error_out); | 57 | static int con_get_config(char *dev, char *str, int size, char **error_out); |
58 | static int con_remove(char *str); | 58 | static int con_remove(int n); |
59 | 59 | ||
60 | static struct line_driver driver = { | 60 | static struct line_driver driver = { |
61 | .name = "UML console", | 61 | .name = "UML console", |
@@ -75,6 +75,7 @@ static struct line_driver driver = { | |||
75 | .name = "con", | 75 | .name = "con", |
76 | .config = con_config, | 76 | .config = con_config, |
77 | .get_config = con_get_config, | 77 | .get_config = con_get_config, |
78 | .id = line_id, | ||
78 | .remove = con_remove, | 79 | .remove = con_remove, |
79 | }, | 80 | }, |
80 | }; | 81 | }; |
@@ -99,9 +100,9 @@ static int con_get_config(char *dev, char *str, int size, char **error_out) | |||
99 | size, error_out)); | 100 | size, error_out)); |
100 | } | 101 | } |
101 | 102 | ||
102 | static int con_remove(char *str) | 103 | static int con_remove(int n) |
103 | { | 104 | { |
104 | return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str)); | 105 | return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n); |
105 | } | 106 | } |
106 | 107 | ||
107 | static int con_open(struct tty_struct *tty, struct file *filp) | 108 | static int con_open(struct tty_struct *tty, struct file *filp) |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 2a7f6892c55c..344b24d09a7c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -754,24 +754,34 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) | |||
754 | return(len); | 754 | return(len); |
755 | } | 755 | } |
756 | 756 | ||
757 | static int ubd_remove(char *str) | 757 | static int ubd_id(char **str, int *start_out, int *end_out) |
758 | { | ||
759 | int n; | ||
760 | |||
761 | n = parse_unit(str); | ||
762 | *start_out = 0; | ||
763 | *end_out = MAX_DEV - 1; | ||
764 | return n; | ||
765 | } | ||
766 | |||
767 | static int ubd_remove(int n) | ||
758 | { | 768 | { |
759 | struct ubd *dev; | 769 | struct ubd *dev; |
760 | int n, err = -ENODEV; | 770 | int err = -ENODEV; |
761 | 771 | ||
762 | n = parse_unit(&str); | 772 | spin_lock(&ubd_lock); |
763 | 773 | ||
764 | if((n < 0) || (n >= MAX_DEV)) | 774 | if(ubd_gendisk[n] == NULL) |
765 | return(err); | 775 | goto out; |
766 | 776 | ||
767 | dev = &ubd_dev[n]; | 777 | dev = &ubd_dev[n]; |
768 | if(dev->count > 0) | ||
769 | return(-EBUSY); /* you cannot remove a open disk */ | ||
770 | 778 | ||
771 | err = 0; | 779 | if(dev->file == NULL) |
772 | spin_lock(&ubd_lock); | 780 | goto out; |
773 | 781 | ||
774 | if(ubd_gendisk[n] == NULL) | 782 | /* you cannot remove a open disk */ |
783 | err = -EBUSY; | ||
784 | if(dev->count > 0) | ||
775 | goto out; | 785 | goto out; |
776 | 786 | ||
777 | del_gendisk(ubd_gendisk[n]); | 787 | del_gendisk(ubd_gendisk[n]); |
@@ -787,15 +797,16 @@ static int ubd_remove(char *str) | |||
787 | platform_device_unregister(&dev->pdev); | 797 | platform_device_unregister(&dev->pdev); |
788 | *dev = ((struct ubd) DEFAULT_UBD); | 798 | *dev = ((struct ubd) DEFAULT_UBD); |
789 | err = 0; | 799 | err = 0; |
790 | out: | 800 | out: |
791 | spin_unlock(&ubd_lock); | 801 | spin_unlock(&ubd_lock); |
792 | return(err); | 802 | return err; |
793 | } | 803 | } |
794 | 804 | ||
795 | static struct mc_device ubd_mc = { | 805 | static struct mc_device ubd_mc = { |
796 | .name = "ubd", | 806 | .name = "ubd", |
797 | .config = ubd_config, | 807 | .config = ubd_config, |
798 | .get_config = ubd_get_config, | 808 | .get_config = ubd_get_config, |
809 | .id = ubd_id, | ||
799 | .remove = ubd_remove, | 810 | .remove = ubd_remove, |
800 | }; | 811 | }; |
801 | 812 | ||