aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2005-06-25 17:55:25 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:36 -0400
commit29d56cfe3ca599ddc3ae9156e7e469c044d97b96 (patch)
tree7790477f5b138c249725fe8ecf9dc07794e9d1eb
parentfc47a0d18a1994b4a18d2235fcde1b75dfa72552 (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>
-rw-r--r--arch/um/drivers/line.c19
-rw-r--r--arch/um/drivers/mconsole_kern.c36
-rw-r--r--arch/um/drivers/net_kern.c31
-rw-r--r--arch/um/drivers/ssl.c9
-rw-r--r--arch/um/drivers/stdio_console.c7
-rw-r--r--arch/um/drivers/ubd_kern.c37
-rw-r--r--arch/um/include/line.h3
-rw-r--r--arch/um/include/mconsole_kern.h3
-rw-r--r--arch/um/kernel/tt/gdb.c4
-rw-r--r--arch/um/kernel/tt/gdb_kern.c2
-rw-r--r--arch/um/kernel/tt/include/debug.h17
11 files changed, 113 insertions, 55 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
605int line_remove(struct line *lines, unsigned int num, char *str) 605int 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
620int 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)
419void mconsole_remove(struct mc_request *req) 419void 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
615static int net_remove(char *str) 615static 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
630static 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
644static struct mc_device net_mc = { 654static 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
50static int ssl_config(char *str); 50static int ssl_config(char *str);
51static int ssl_get_config(char *dev, char *str, int size, char **error_out); 51static int ssl_get_config(char *dev, char *str, int size, char **error_out);
52static int ssl_remove(char *str); 52static int ssl_remove(int n);
53 53
54static struct line_driver driver = { 54static 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
97static int ssl_remove(char *str) 98static 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
103int ssl_open(struct tty_struct *tty, struct file *filp) 104int 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
56static int con_config(char *str); 56static int con_config(char *str);
57static int con_get_config(char *dev, char *str, int size, char **error_out); 57static int con_get_config(char *dev, char *str, int size, char **error_out);
58static int con_remove(char *str); 58static int con_remove(int n);
59 59
60static struct line_driver driver = { 60static 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
102static int con_remove(char *str) 103static 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
107static int con_open(struct tty_struct *tty, struct file *filp) 108static 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
757static int ubd_remove(char *str) 757static 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
767static 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: 800out:
791 spin_unlock(&ubd_lock); 801 spin_unlock(&ubd_lock);
792 return(err); 802 return err;
793} 803}
794 804
795static struct mc_device ubd_mc = { 805static 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
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 4c5e92c04ccb..5323d22a6ca7 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -101,7 +101,8 @@ extern void lines_init(struct line *lines, int nlines);
101extern void close_lines(struct line *lines, int nlines); 101extern void close_lines(struct line *lines, int nlines);
102 102
103extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); 103extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
104extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str); 104extern int line_id(char **str, int *start_out, int *end_out);
105extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n);
105extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, 106extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
106 int size, char **error_out); 107 int size, char **error_out);
107 108
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h
index 61c274fcee5d..d86ee14260ce 100644
--- a/arch/um/include/mconsole_kern.h
+++ b/arch/um/include/mconsole_kern.h
@@ -20,7 +20,8 @@ struct mc_device {
20 char *name; 20 char *name;
21 int (*config)(char *); 21 int (*config)(char *);
22 int (*get_config)(char *, char *, int, char **); 22 int (*get_config)(char *, char *, int, char **);
23 int (*remove)(char *); 23 int (*id)(char **, int *, int *);
24 int (*remove)(int);
24}; 25};
25 26
26#define CONFIG_CHUNK(str, size, current, chunk, end) \ 27#define CONFIG_CHUNK(str, size, current, chunk, end) \
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
index 19a0ad7b35b3..37e22d71a0d9 100644
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -153,10 +153,10 @@ void remove_gdb_cb(void *unused)
153 exit_debugger_cb(NULL); 153 exit_debugger_cb(NULL);
154} 154}
155 155
156int gdb_remove(char *unused) 156int gdb_remove(int unused)
157{ 157{
158 initial_thread_cb(remove_gdb_cb, NULL); 158 initial_thread_cb(remove_gdb_cb, NULL);
159 return(0); 159 return 0;
160} 160}
161 161
162void signal_usr1(int sig) 162void signal_usr1(int sig)
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c
index 93fb121f86af..26506388a6aa 100644
--- a/arch/um/kernel/tt/gdb_kern.c
+++ b/arch/um/kernel/tt/gdb_kern.c
@@ -10,7 +10,7 @@
10#ifdef CONFIG_MCONSOLE 10#ifdef CONFIG_MCONSOLE
11 11
12extern int gdb_config(char *str); 12extern int gdb_config(char *str);
13extern int gdb_remove(char *unused); 13extern int gdb_remove(int n);
14 14
15static struct mc_device gdb_mc = { 15static struct mc_device gdb_mc = {
16 .name = "gdb", 16 .name = "gdb",
diff --git a/arch/um/kernel/tt/include/debug.h b/arch/um/kernel/tt/include/debug.h
index 8eff674107ca..738435461e13 100644
--- a/arch/um/kernel/tt/include/debug.h
+++ b/arch/um/kernel/tt/include/debug.h
@@ -4,8 +4,8 @@
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#ifndef __DEBUG_H 7#ifndef __UML_TT_DEBUG_H
8#define __DEBUG_H 8#define __UML_TT_DEBUG_H
9 9
10extern int debugger_proxy(int status, pid_t pid); 10extern int debugger_proxy(int status, pid_t pid);
11extern void child_proxy(pid_t pid, int status); 11extern void child_proxy(pid_t pid, int status);
@@ -13,17 +13,6 @@ extern void init_proxy (pid_t pid, int waiting, int status);
13extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); 13extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
14extern void fake_child_exit(void); 14extern void fake_child_exit(void);
15extern int gdb_config(char *str); 15extern int gdb_config(char *str);
16extern int gdb_remove(char *unused); 16extern int gdb_remove(int unused);
17 17
18#endif 18#endif
19
20/*
21 * Overrides for Emacs so that we follow Linus's tabbing style.
22 * Emacs will notice this stuff at the end of the file and automatically
23 * adjust the settings for this buffer only. This must remain at the end
24 * of the file.
25 * ---------------------------------------------------------------------------
26 * Local variables:
27 * c-file-style: "linux"
28 * End:
29 */