aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/manage.c')
-rw-r--r--drivers/xen/manage.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index e12bd3635f83..26e5e8507f03 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -168,7 +168,9 @@ out:
168#endif /* CONFIG_HIBERNATE_CALLBACKS */ 168#endif /* CONFIG_HIBERNATE_CALLBACKS */
169 169
170struct shutdown_handler { 170struct shutdown_handler {
171 const char *command; 171#define SHUTDOWN_CMD_SIZE 11
172 const char command[SHUTDOWN_CMD_SIZE];
173 bool flag;
172 void (*cb)(void); 174 void (*cb)(void);
173}; 175};
174 176
@@ -206,22 +208,22 @@ static void do_reboot(void)
206 ctrl_alt_del(); 208 ctrl_alt_del();
207} 209}
208 210
211static struct shutdown_handler shutdown_handlers[] = {
212 { "poweroff", true, do_poweroff },
213 { "halt", false, do_poweroff },
214 { "reboot", true, do_reboot },
215#ifdef CONFIG_HIBERNATE_CALLBACKS
216 { "suspend", true, do_suspend },
217#endif
218};
219
209static void shutdown_handler(struct xenbus_watch *watch, 220static void shutdown_handler(struct xenbus_watch *watch,
210 const char **vec, unsigned int len) 221 const char **vec, unsigned int len)
211{ 222{
212 char *str; 223 char *str;
213 struct xenbus_transaction xbt; 224 struct xenbus_transaction xbt;
214 int err; 225 int err;
215 static struct shutdown_handler handlers[] = { 226 int idx;
216 { "poweroff", do_poweroff },
217 { "halt", do_poweroff },
218 { "reboot", do_reboot },
219#ifdef CONFIG_HIBERNATE_CALLBACKS
220 { "suspend", do_suspend },
221#endif
222 {NULL, NULL},
223 };
224 static struct shutdown_handler *handler;
225 227
226 if (shutting_down != SHUTDOWN_INVALID) 228 if (shutting_down != SHUTDOWN_INVALID)
227 return; 229 return;
@@ -238,13 +240,13 @@ static void shutdown_handler(struct xenbus_watch *watch,
238 return; 240 return;
239 } 241 }
240 242
241 for (handler = &handlers[0]; handler->command; handler++) { 243 for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
242 if (strcmp(str, handler->command) == 0) 244 if (strcmp(str, shutdown_handlers[idx].command) == 0)
243 break; 245 break;
244 } 246 }
245 247
246 /* Only acknowledge commands which we are prepared to handle. */ 248 /* Only acknowledge commands which we are prepared to handle. */
247 if (handler->cb) 249 if (idx < ARRAY_SIZE(shutdown_handlers))
248 xenbus_write(xbt, "control", "shutdown", ""); 250 xenbus_write(xbt, "control", "shutdown", "");
249 251
250 err = xenbus_transaction_end(xbt, 0); 252 err = xenbus_transaction_end(xbt, 0);
@@ -253,8 +255,8 @@ static void shutdown_handler(struct xenbus_watch *watch,
253 goto again; 255 goto again;
254 } 256 }
255 257
256 if (handler->cb) { 258 if (idx < ARRAY_SIZE(shutdown_handlers)) {
257 handler->cb(); 259 shutdown_handlers[idx].cb();
258 } else { 260 } else {
259 pr_info("Ignoring shutdown request: %s\n", str); 261 pr_info("Ignoring shutdown request: %s\n", str);
260 shutting_down = SHUTDOWN_INVALID; 262 shutting_down = SHUTDOWN_INVALID;
@@ -310,6 +312,9 @@ static struct notifier_block xen_reboot_nb = {
310static int setup_shutdown_watcher(void) 312static int setup_shutdown_watcher(void)
311{ 313{
312 int err; 314 int err;
315 int idx;
316#define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
317 char node[FEATURE_PATH_SIZE];
313 318
314 err = register_xenbus_watch(&shutdown_watch); 319 err = register_xenbus_watch(&shutdown_watch);
315 if (err) { 320 if (err) {
@@ -326,6 +331,14 @@ static int setup_shutdown_watcher(void)
326 } 331 }
327#endif 332#endif
328 333
334 for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
335 if (!shutdown_handlers[idx].flag)
336 continue;
337 snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
338 shutdown_handlers[idx].command);
339 xenbus_printf(XBT_NIL, "control", node, "%u", 1);
340 }
341
329 return 0; 342 return 0;
330} 343}
331 344