diff options
-rw-r--r-- | drivers/xen/manage.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index b2a8d7856ce3..972bf783a182 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -172,12 +172,39 @@ out: | |||
172 | } | 172 | } |
173 | #endif /* CONFIG_PM_SLEEP */ | 173 | #endif /* CONFIG_PM_SLEEP */ |
174 | 174 | ||
175 | struct shutdown_handler { | ||
176 | const char *command; | ||
177 | void (*cb)(void); | ||
178 | }; | ||
179 | |||
180 | static void do_poweroff(void) | ||
181 | { | ||
182 | shutting_down = SHUTDOWN_POWEROFF; | ||
183 | orderly_poweroff(false); | ||
184 | } | ||
185 | |||
186 | static void do_reboot(void) | ||
187 | { | ||
188 | shutting_down = SHUTDOWN_POWEROFF; /* ? */ | ||
189 | ctrl_alt_del(); | ||
190 | } | ||
191 | |||
175 | static void shutdown_handler(struct xenbus_watch *watch, | 192 | static void shutdown_handler(struct xenbus_watch *watch, |
176 | const char **vec, unsigned int len) | 193 | const char **vec, unsigned int len) |
177 | { | 194 | { |
178 | char *str; | 195 | char *str; |
179 | struct xenbus_transaction xbt; | 196 | struct xenbus_transaction xbt; |
180 | int err; | 197 | int err; |
198 | static struct shutdown_handler handlers[] = { | ||
199 | { "poweroff", do_poweroff }, | ||
200 | { "halt", do_poweroff }, | ||
201 | { "reboot", do_reboot }, | ||
202 | #ifdef CONFIG_PM_SLEEP | ||
203 | { "suspend", do_suspend }, | ||
204 | #endif | ||
205 | {NULL, NULL}, | ||
206 | }; | ||
207 | static struct shutdown_handler *handler; | ||
181 | 208 | ||
182 | if (shutting_down != SHUTDOWN_INVALID) | 209 | if (shutting_down != SHUTDOWN_INVALID) |
183 | return; | 210 | return; |
@@ -194,7 +221,14 @@ static void shutdown_handler(struct xenbus_watch *watch, | |||
194 | return; | 221 | return; |
195 | } | 222 | } |
196 | 223 | ||
197 | xenbus_write(xbt, "control", "shutdown", ""); | 224 | for (handler = &handlers[0]; handler->command; handler++) { |
225 | if (strcmp(str, handler->command) == 0) | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | /* Only acknowledge commands which we are prepared to handle. */ | ||
230 | if (handler->cb) | ||
231 | xenbus_write(xbt, "control", "shutdown", ""); | ||
198 | 232 | ||
199 | err = xenbus_transaction_end(xbt, 0); | 233 | err = xenbus_transaction_end(xbt, 0); |
200 | if (err == -EAGAIN) { | 234 | if (err == -EAGAIN) { |
@@ -202,17 +236,8 @@ static void shutdown_handler(struct xenbus_watch *watch, | |||
202 | goto again; | 236 | goto again; |
203 | } | 237 | } |
204 | 238 | ||
205 | if (strcmp(str, "poweroff") == 0 || | 239 | if (handler->cb) { |
206 | strcmp(str, "halt") == 0) { | 240 | handler->cb(); |
207 | shutting_down = SHUTDOWN_POWEROFF; | ||
208 | orderly_poweroff(false); | ||
209 | } else if (strcmp(str, "reboot") == 0) { | ||
210 | shutting_down = SHUTDOWN_POWEROFF; /* ? */ | ||
211 | ctrl_alt_del(); | ||
212 | #ifdef CONFIG_PM_SLEEP | ||
213 | } else if (strcmp(str, "suspend") == 0) { | ||
214 | do_suspend(); | ||
215 | #endif | ||
216 | } else { | 241 | } else { |
217 | printk(KERN_INFO "Ignoring shutdown request: %s\n", str); | 242 | printk(KERN_INFO "Ignoring shutdown request: %s\n", str); |
218 | shutting_down = SHUTDOWN_INVALID; | 243 | shutting_down = SHUTDOWN_INVALID; |