xref: /linux/drivers/char/ipmi/ipmi_poweroff.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * ipmi_poweroff.c
4  *
5  * MontaVista IPMI Poweroff extension to sys_reboot
6  *
7  * Author: MontaVista Software, Inc.
8  *         Steven Dake <sdake@mvista.com>
9  *         Corey Minyard <cminyard@mvista.com>
10  *         source@mvista.com
11  *
12  * Copyright 2002,2004 MontaVista Software Inc.
13  */
14 
15 #define pr_fmt(fmt) "IPMI poweroff: " fmt
16 
17 #include <linux/module.h>
18 #include <linux/moduleparam.h>
19 #include <linux/proc_fs.h>
20 #include <linux/string.h>
21 #include <linux/completion.h>
22 #include <linux/pm.h>
23 #include <linux/kdev_t.h>
24 #include <linux/ipmi.h>
25 #include <linux/ipmi_smi.h>
26 
27 static void ipmi_po_smi_gone(int if_num);
28 static void ipmi_po_new_smi(int if_num, struct device *device);
29 
30 /* Definitions for controlling power off (if the system supports it).  It
31  * conveniently matches the IPMI chassis control values. */
32 #define IPMI_CHASSIS_POWER_DOWN		0	/* power down, the default. */
33 #define IPMI_CHASSIS_POWER_CYCLE	0x02	/* power cycle */
34 
35 /* the IPMI data command */
36 static int poweroff_powercycle;
37 
38 /* Which interface to use, -1 means the first we see. */
39 static int ifnum_to_use = -1;
40 
41 /* Our local state. */
42 static int ready;
43 static struct ipmi_user *ipmi_user;
44 static int ipmi_ifnum;
45 static void (*specific_poweroff_func)(struct ipmi_user *user);
46 
47 /* Holds the old poweroff function so we can restore it on removal. */
48 static void (*old_poweroff_func)(void);
49 
set_param_ifnum(const char * val,const struct kernel_param * kp)50 static int set_param_ifnum(const char *val, const struct kernel_param *kp)
51 {
52 	int rv = param_set_int(val, kp);
53 	if (rv)
54 		return rv;
55 	if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum))
56 		return 0;
57 
58 	ipmi_po_smi_gone(ipmi_ifnum);
59 	ipmi_po_new_smi(ifnum_to_use, NULL);
60 	return 0;
61 }
62 
63 module_param_call(ifnum_to_use, set_param_ifnum, param_get_int,
64 		  &ifnum_to_use, 0644);
65 MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
66 		 "timer.  Setting to -1 defaults to the first registered "
67 		 "interface");
68 
69 /* parameter definition to allow user to flag power cycle */
70 module_param(poweroff_powercycle, int, 0644);
71 MODULE_PARM_DESC(poweroff_powercycle,
72 		 " Set to non-zero to enable power cycle instead of power"
73 		 " down. Power cycle is contingent on hardware support,"
74 		 " otherwise it defaults back to power down.");
75 
76 /* Stuff from the get device id command. */
77 static unsigned int mfg_id;
78 static unsigned int prod_id;
79 static unsigned char capabilities;
80 static unsigned char ipmi_version;
81 
82 /*
83  * We use our own messages for this operation, we don't let the system
84  * allocate them, since we may be in a panic situation.  The whole
85  * thing is single-threaded, anyway, so multiple messages are not
86  * required.
87  */
88 static atomic_t dummy_count = ATOMIC_INIT(0);
dummy_smi_free(struct ipmi_smi_msg * msg)89 static void dummy_smi_free(struct ipmi_smi_msg *msg)
90 {
91 	atomic_dec(&dummy_count);
92 }
dummy_recv_free(struct ipmi_recv_msg * msg)93 static void dummy_recv_free(struct ipmi_recv_msg *msg)
94 {
95 	atomic_dec(&dummy_count);
96 }
97 static struct ipmi_smi_msg halt_smi_msg = INIT_IPMI_SMI_MSG(dummy_smi_free);
98 static struct ipmi_recv_msg halt_recv_msg = INIT_IPMI_RECV_MSG(dummy_recv_free);
99 
100 
101 /*
102  * Code to send a message and wait for the response.
103  */
104 
receive_handler(struct ipmi_recv_msg * recv_msg,void * handler_data)105 static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
106 {
107 	struct completion *comp = recv_msg->user_msg_data;
108 
109 	if (comp)
110 		complete(comp);
111 }
112 
113 static const struct ipmi_user_hndl ipmi_poweroff_handler = {
114 	.ipmi_recv_hndl = receive_handler
115 };
116 
117 
ipmi_request_wait_for_response(struct ipmi_user * user,struct ipmi_addr * addr,struct kernel_ipmi_msg * send_msg)118 static int ipmi_request_wait_for_response(struct ipmi_user       *user,
119 					  struct ipmi_addr       *addr,
120 					  struct kernel_ipmi_msg *send_msg)
121 {
122 	int               rv;
123 	struct completion comp;
124 
125 	init_completion(&comp);
126 
127 	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
128 				      &halt_smi_msg, &halt_recv_msg, 0);
129 	if (rv)
130 		return rv;
131 
132 	wait_for_completion(&comp);
133 
134 	return halt_recv_msg.msg.data[0];
135 }
136 
137 /* Wait for message to complete, spinning. */
ipmi_request_in_rc_mode(struct ipmi_user * user,struct ipmi_addr * addr,struct kernel_ipmi_msg * send_msg)138 static int ipmi_request_in_rc_mode(struct ipmi_user       *user,
139 				   struct ipmi_addr       *addr,
140 				   struct kernel_ipmi_msg *send_msg)
141 {
142 	int rv;
143 
144 	atomic_set(&dummy_count, 2);
145 	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
146 				      &halt_smi_msg, &halt_recv_msg, 0);
147 	if (rv) {
148 		atomic_set(&dummy_count, 0);
149 		return rv;
150 	}
151 
152 	/*
153 	 * Spin until our message is done.
154 	 */
155 	while (atomic_read(&dummy_count) > 0) {
156 		ipmi_poll_interface(user);
157 		cpu_relax();
158 	}
159 
160 	return halt_recv_msg.msg.data[0];
161 }
162 
163 /*
164  * ATCA Support
165  */
166 
167 #define IPMI_NETFN_ATCA			0x2c
168 #define IPMI_ATCA_SET_POWER_CMD		0x11
169 #define IPMI_ATCA_GET_ADDR_INFO_CMD	0x01
170 #define IPMI_PICMG_ID			0
171 
172 #define IPMI_NETFN_OEM				0x2e
173 #define IPMI_ATCA_PPS_GRACEFUL_RESTART		0x11
174 #define IPMI_ATCA_PPS_IANA			"\x00\x40\x0A"
175 #define IPMI_MOTOROLA_MANUFACTURER_ID		0x0000A1
176 #define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID	0x0051
177 
178 static void (*atca_oem_poweroff_hook)(struct ipmi_user *user);
179 
pps_poweroff_atca(struct ipmi_user * user)180 static void pps_poweroff_atca(struct ipmi_user *user)
181 {
182 	struct ipmi_system_interface_addr smi_addr;
183 	struct kernel_ipmi_msg            send_msg;
184 	int                               rv;
185 	/*
186 	 * Configure IPMI address for local access
187 	 */
188 	smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
189 	smi_addr.channel = IPMI_BMC_CHANNEL;
190 	smi_addr.lun = 0;
191 
192 	pr_info("PPS powerdown hook used\n");
193 
194 	send_msg.netfn = IPMI_NETFN_OEM;
195 	send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART;
196 	send_msg.data = IPMI_ATCA_PPS_IANA;
197 	send_msg.data_len = 3;
198 	rv = ipmi_request_in_rc_mode(user,
199 				     (struct ipmi_addr *) &smi_addr,
200 				     &send_msg);
201 	if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE)
202 		pr_err("Unable to send ATCA, IPMI error 0x%x\n", rv);
203 
204 	return;
205 }
206 
ipmi_atca_detect(struct ipmi_user * user)207 static int ipmi_atca_detect(struct ipmi_user *user)
208 {
209 	struct ipmi_system_interface_addr smi_addr;
210 	struct kernel_ipmi_msg            send_msg;
211 	int                               rv;
212 	unsigned char                     data[1];
213 
214 	/*
215 	 * Configure IPMI address for local access
216 	 */
217 	smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
218 	smi_addr.channel = IPMI_BMC_CHANNEL;
219 	smi_addr.lun = 0;
220 
221 	/*
222 	 * Use get address info to check and see if we are ATCA
223 	 */
224 	send_msg.netfn = IPMI_NETFN_ATCA;
225 	send_msg.cmd = IPMI_ATCA_GET_ADDR_INFO_CMD;
226 	data[0] = IPMI_PICMG_ID;
227 	send_msg.data = data;
228 	send_msg.data_len = sizeof(data);
229 	rv = ipmi_request_wait_for_response(user,
230 					    (struct ipmi_addr *) &smi_addr,
231 					    &send_msg);
232 
233 	pr_info("ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id);
234 	if ((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID)
235 	    && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) {
236 		pr_info("Installing Pigeon Point Systems Poweroff Hook\n");
237 		atca_oem_poweroff_hook = pps_poweroff_atca;
238 	}
239 	return !rv;
240 }
241 
ipmi_poweroff_atca(struct ipmi_user * user)242 static void ipmi_poweroff_atca(struct ipmi_user *user)
243 {
244 	struct ipmi_system_interface_addr smi_addr;
245 	struct kernel_ipmi_msg            send_msg;
246 	int                               rv;
247 	unsigned char                     data[4];
248 
249 	/*
250 	 * Configure IPMI address for local access
251 	 */
252 	smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
253 	smi_addr.channel = IPMI_BMC_CHANNEL;
254 	smi_addr.lun = 0;
255 
256 	pr_info("Powering down via ATCA power command\n");
257 
258 	/*
259 	 * Power down
260 	 */
261 	send_msg.netfn = IPMI_NETFN_ATCA;
262 	send_msg.cmd = IPMI_ATCA_SET_POWER_CMD;
263 	data[0] = IPMI_PICMG_ID;
264 	data[1] = 0; /* FRU id */
265 	data[2] = 0; /* Power Level */
266 	data[3] = 0; /* Don't change saved presets */
267 	send_msg.data = data;
268 	send_msg.data_len = sizeof(data);
269 	rv = ipmi_request_in_rc_mode(user,
270 				     (struct ipmi_addr *) &smi_addr,
271 				     &send_msg);
272 	/*
273 	 * At this point, the system may be shutting down, and most
274 	 * serial drivers (if used) will have interrupts turned off
275 	 * it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE
276 	 * return code
277 	 */
278 	if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) {
279 		pr_err("Unable to send ATCA powerdown message, IPMI error 0x%x\n",
280 		       rv);
281 		goto out;
282 	}
283 
284 	if (atca_oem_poweroff_hook)
285 		atca_oem_poweroff_hook(user);
286  out:
287 	return;
288 }
289 
290 /*
291  * CPI1 Support
292  */
293 
294 #define IPMI_NETFN_OEM_1				0xf8
295 #define OEM_GRP_CMD_SET_RESET_STATE		0x84
296 #define OEM_GRP_CMD_SET_POWER_STATE		0x82
297 #define IPMI_NETFN_OEM_8				0xf8
298 #define OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL	0x80
299 #define OEM_GRP_CMD_GET_SLOT_GA			0xa3
300 #define IPMI_NETFN_SENSOR_EVT			0x10
301 #define IPMI_CMD_GET_EVENT_RECEIVER		0x01
302 
303 #define IPMI_CPI1_PRODUCT_ID		0x000157
304 #define IPMI_CPI1_MANUFACTURER_ID	0x0108
305 
ipmi_cpi1_detect(struct ipmi_user * user)306 static int ipmi_cpi1_detect(struct ipmi_user *user)
307 {
308 	return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID)
309 		&& (prod_id == IPMI_CPI1_PRODUCT_ID));
310 }
311 
ipmi_poweroff_cpi1(struct ipmi_user * user)312 static void ipmi_poweroff_cpi1(struct ipmi_user *user)
313 {
314 	struct ipmi_system_interface_addr smi_addr;
315 	struct ipmi_ipmb_addr             ipmb_addr;
316 	struct kernel_ipmi_msg            send_msg;
317 	int                               rv;
318 	unsigned char                     data[1];
319 	int                               slot;
320 	unsigned char                     hotswap_ipmb;
321 	unsigned char                     aer_addr;
322 	unsigned char                     aer_lun;
323 
324 	/*
325 	 * Configure IPMI address for local access
326 	 */
327 	smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
328 	smi_addr.channel = IPMI_BMC_CHANNEL;
329 	smi_addr.lun = 0;
330 
331 	pr_info("Powering down via CPI1 power command\n");
332 
333 	/*
334 	 * Get IPMI ipmb address
335 	 */
336 	send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
337 	send_msg.cmd = OEM_GRP_CMD_GET_SLOT_GA;
338 	send_msg.data = NULL;
339 	send_msg.data_len = 0;
340 	rv = ipmi_request_in_rc_mode(user,
341 				     (struct ipmi_addr *) &smi_addr,
342 				     &send_msg);
343 	if (rv)
344 		goto out;
345 	slot = halt_recv_msg.msg.data[1];
346 	hotswap_ipmb = (slot > 9) ? (0xb0 + 2 * slot) : (0xae + 2 * slot);
347 
348 	/*
349 	 * Get active event receiver
350 	 */
351 	send_msg.netfn = IPMI_NETFN_SENSOR_EVT >> 2;
352 	send_msg.cmd = IPMI_CMD_GET_EVENT_RECEIVER;
353 	send_msg.data = NULL;
354 	send_msg.data_len = 0;
355 	rv = ipmi_request_in_rc_mode(user,
356 				     (struct ipmi_addr *) &smi_addr,
357 				     &send_msg);
358 	if (rv)
359 		goto out;
360 	aer_addr = halt_recv_msg.msg.data[1];
361 	aer_lun = halt_recv_msg.msg.data[2];
362 
363 	/*
364 	 * Setup IPMB address target instead of local target
365 	 */
366 	ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
367 	ipmb_addr.channel = 0;
368 	ipmb_addr.slave_addr = aer_addr;
369 	ipmb_addr.lun = aer_lun;
370 
371 	/*
372 	 * Send request hotswap control to remove blade from dpv
373 	 */
374 	send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
375 	send_msg.cmd = OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL;
376 	send_msg.data = &hotswap_ipmb;
377 	send_msg.data_len = 1;
378 	ipmi_request_in_rc_mode(user,
379 				(struct ipmi_addr *) &ipmb_addr,
380 				&send_msg);
381 
382 	/*
383 	 * Set reset asserted
384 	 */
385 	send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
386 	send_msg.cmd = OEM_GRP_CMD_SET_RESET_STATE;
387 	send_msg.data = data;
388 	data[0] = 1; /* Reset asserted state */
389 	send_msg.data_len = 1;
390 	rv = ipmi_request_in_rc_mode(user,
391 				     (struct ipmi_addr *) &smi_addr,
392 				     &send_msg);
393 	if (rv)
394 		goto out;
395 
396 	/*
397 	 * Power down
398 	 */
399 	send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
400 	send_msg.cmd = OEM_GRP_CMD_SET_POWER_STATE;
401 	send_msg.data = data;
402 	data[0] = 1; /* Power down state */
403 	send_msg.data_len = 1;
404 	rv = ipmi_request_in_rc_mode(user,
405 				     (struct ipmi_addr *) &smi_addr,
406 				     &send_msg);
407 	if (rv)
408 		goto out;
409 
410  out:
411 	return;
412 }
413 
414 /*
415  * ipmi_dell_chassis_detect()
416  * Dell systems with IPMI < 1.5 don't set the chassis capability bit
417  * but they can handle a chassis poweroff or powercycle command.
418  */
419 
420 #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00}
ipmi_dell_chassis_detect(struct ipmi_user * user)421 static int ipmi_dell_chassis_detect(struct ipmi_user *user)
422 {
423 	const char ipmi_version_major = ipmi_version & 0xF;
424 	const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
425 	const char mfr[3] = DELL_IANA_MFR_ID;
426 	if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
427 	    ipmi_version_major <= 1 &&
428 	    ipmi_version_minor < 5)
429 		return 1;
430 	return 0;
431 }
432 
433 /*
434  * ipmi_hp_chassis_detect()
435  * HP PA-RISC servers rp3410/rp3440, the C8000 workstation and the rx2600 and
436  * zx6000 machines support IPMI vers 1 and don't set the chassis capability bit
437  * but they can handle a chassis poweroff or powercycle command.
438  */
439 
440 #define HP_IANA_MFR_ID 0x0b
441 #define HP_BMC_PROD_ID 0x8201
ipmi_hp_chassis_detect(struct ipmi_user * user)442 static int ipmi_hp_chassis_detect(struct ipmi_user *user)
443 {
444 	if (mfg_id == HP_IANA_MFR_ID
445 		&& prod_id == HP_BMC_PROD_ID
446 		&& ipmi_version == 1)
447 		return 1;
448 	return 0;
449 }
450 
451 /*
452  * Standard chassis support
453  */
454 
455 #define IPMI_NETFN_CHASSIS_REQUEST	0
456 #define IPMI_CHASSIS_CONTROL_CMD	0x02
457 
ipmi_chassis_detect(struct ipmi_user * user)458 static int ipmi_chassis_detect(struct ipmi_user *user)
459 {
460 	/* Chassis support, use it. */
461 	return (capabilities & 0x80);
462 }
463 
ipmi_poweroff_chassis(struct ipmi_user * user)464 static void ipmi_poweroff_chassis(struct ipmi_user *user)
465 {
466 	struct ipmi_system_interface_addr smi_addr;
467 	struct kernel_ipmi_msg            send_msg;
468 	int                               rv;
469 	unsigned char                     data[1];
470 
471 	/*
472 	 * Configure IPMI address for local access
473 	 */
474 	smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
475 	smi_addr.channel = IPMI_BMC_CHANNEL;
476 	smi_addr.lun = 0;
477 
478  powercyclefailed:
479 	pr_info("Powering %s via IPMI chassis control command\n",
480 		(poweroff_powercycle ? "cycle" : "down"));
481 
482 	/*
483 	 * Power down
484 	 */
485 	send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
486 	send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
487 	if (poweroff_powercycle)
488 		data[0] = IPMI_CHASSIS_POWER_CYCLE;
489 	else
490 		data[0] = IPMI_CHASSIS_POWER_DOWN;
491 	send_msg.data = data;
492 	send_msg.data_len = sizeof(data);
493 	rv = ipmi_request_in_rc_mode(user,
494 				     (struct ipmi_addr *) &smi_addr,
495 				     &send_msg);
496 	if (rv) {
497 		if (poweroff_powercycle) {
498 			/* power cycle failed, default to power down */
499 			pr_err("Unable to send chassis power cycle message, IPMI error 0x%x\n",
500 			       rv);
501 			poweroff_powercycle = 0;
502 			goto powercyclefailed;
503 		}
504 
505 		pr_err("Unable to send chassis power down message, IPMI error 0x%x\n",
506 		       rv);
507 	}
508 }
509 
510 
511 /* Table of possible power off functions. */
512 struct poweroff_function {
513 	char *platform_type;
514 	int  (*detect)(struct ipmi_user *user);
515 	void (*poweroff_func)(struct ipmi_user *user);
516 };
517 
518 static struct poweroff_function poweroff_functions[] = {
519 	{ .platform_type	= "ATCA",
520 	  .detect		= ipmi_atca_detect,
521 	  .poweroff_func	= ipmi_poweroff_atca },
522 	{ .platform_type	= "CPI1",
523 	  .detect		= ipmi_cpi1_detect,
524 	  .poweroff_func	= ipmi_poweroff_cpi1 },
525 	{ .platform_type	= "chassis",
526 	  .detect		= ipmi_dell_chassis_detect,
527 	  .poweroff_func	= ipmi_poweroff_chassis },
528 	{ .platform_type	= "chassis",
529 	  .detect		= ipmi_hp_chassis_detect,
530 	  .poweroff_func	= ipmi_poweroff_chassis },
531 	/* Chassis should generally be last, other things should override
532 	   it. */
533 	{ .platform_type	= "chassis",
534 	  .detect		= ipmi_chassis_detect,
535 	  .poweroff_func	= ipmi_poweroff_chassis },
536 };
537 #define NUM_PO_FUNCS ARRAY_SIZE(poweroff_functions)
538 
539 
540 /* Called on a powerdown request. */
ipmi_poweroff_function(void)541 static void ipmi_poweroff_function(void)
542 {
543 	if (!ready)
544 		return;
545 
546 	/* Use run-to-completion mode, since interrupts may be off. */
547 	specific_poweroff_func(ipmi_user);
548 }
549 
550 /* Wait for an IPMI interface to be installed, the first one installed
551    will be grabbed by this code and used to perform the powerdown. */
ipmi_po_new_smi(int if_num,struct device * device)552 static void ipmi_po_new_smi(int if_num, struct device *device)
553 {
554 	struct ipmi_system_interface_addr smi_addr;
555 	struct kernel_ipmi_msg            send_msg;
556 	int                               rv;
557 	int                               i;
558 
559 	if (ready)
560 		return;
561 
562 	if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num))
563 		return;
564 
565 	rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
566 			      &ipmi_user);
567 	if (rv) {
568 		pr_err("could not create IPMI user, error %d\n", rv);
569 		return;
570 	}
571 
572 	ipmi_ifnum = if_num;
573 
574 	/*
575 	 * Do a get device ide and store some results, since this is
576 	 * used by several functions.
577 	 */
578 	smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
579 	smi_addr.channel = IPMI_BMC_CHANNEL;
580 	smi_addr.lun = 0;
581 
582 	send_msg.netfn = IPMI_NETFN_APP_REQUEST;
583 	send_msg.cmd = IPMI_GET_DEVICE_ID_CMD;
584 	send_msg.data = NULL;
585 	send_msg.data_len = 0;
586 	rv = ipmi_request_wait_for_response(ipmi_user,
587 					    (struct ipmi_addr *) &smi_addr,
588 					    &send_msg);
589 	if (rv) {
590 		pr_err("Unable to send IPMI get device id info, IPMI error 0x%x\n",
591 		       rv);
592 		goto out_err;
593 	}
594 
595 	if (halt_recv_msg.msg.data_len < 12) {
596 		pr_err("(chassis) IPMI get device id info too short, was %d bytes, needed %d bytes\n",
597 		       halt_recv_msg.msg.data_len, 12);
598 		goto out_err;
599 	}
600 
601 	mfg_id = (halt_recv_msg.msg.data[7]
602 		  | (halt_recv_msg.msg.data[8] << 8)
603 		  | (halt_recv_msg.msg.data[9] << 16));
604 	prod_id = (halt_recv_msg.msg.data[10]
605 		   | (halt_recv_msg.msg.data[11] << 8));
606 	capabilities = halt_recv_msg.msg.data[6];
607 	ipmi_version = halt_recv_msg.msg.data[5];
608 
609 
610 	/* Scan for a poweroff method */
611 	for (i = 0; i < NUM_PO_FUNCS; i++) {
612 		if (poweroff_functions[i].detect(ipmi_user))
613 			goto found;
614 	}
615 
616  out_err:
617 	pr_err("Unable to find a poweroff function that will work, giving up\n");
618 	ipmi_destroy_user(ipmi_user);
619 	return;
620 
621  found:
622 	pr_info("Found a %s style poweroff function\n",
623 		poweroff_functions[i].platform_type);
624 	specific_poweroff_func = poweroff_functions[i].poweroff_func;
625 	old_poweroff_func = pm_power_off;
626 	pm_power_off = ipmi_poweroff_function;
627 	ready = 1;
628 }
629 
ipmi_po_smi_gone(int if_num)630 static void ipmi_po_smi_gone(int if_num)
631 {
632 	if (!ready)
633 		return;
634 
635 	if (ipmi_ifnum != if_num)
636 		return;
637 
638 	ready = 0;
639 	ipmi_destroy_user(ipmi_user);
640 	pm_power_off = old_poweroff_func;
641 }
642 
643 static struct ipmi_smi_watcher smi_watcher = {
644 	.owner    = THIS_MODULE,
645 	.new_smi  = ipmi_po_new_smi,
646 	.smi_gone = ipmi_po_smi_gone
647 };
648 
649 
650 #ifdef CONFIG_PROC_FS
651 #include <linux/sysctl.h>
652 
653 static struct ctl_table ipmi_table[] = {
654 	{ .procname	= "poweroff_powercycle",
655 	  .data		= &poweroff_powercycle,
656 	  .maxlen	= sizeof(poweroff_powercycle),
657 	  .mode		= 0644,
658 	  .proc_handler	= proc_dointvec },
659 };
660 
661 static struct ctl_table_header *ipmi_table_header;
662 #endif /* CONFIG_PROC_FS */
663 
664 /*
665  * Startup and shutdown functions.
666  */
ipmi_poweroff_init(void)667 static int __init ipmi_poweroff_init(void)
668 {
669 	int rv;
670 
671 	pr_info("Copyright (C) 2004 MontaVista Software - IPMI Powerdown via sys_reboot\n");
672 
673 	if (poweroff_powercycle)
674 		pr_info("Power cycle is enabled\n");
675 
676 #ifdef CONFIG_PROC_FS
677 	ipmi_table_header = register_sysctl("dev/ipmi", ipmi_table);
678 	if (!ipmi_table_header) {
679 		pr_err("Unable to register powercycle sysctl\n");
680 		rv = -ENOMEM;
681 		goto out_err;
682 	}
683 #endif
684 
685 	rv = ipmi_smi_watcher_register(&smi_watcher);
686 
687 #ifdef CONFIG_PROC_FS
688 	if (rv) {
689 		unregister_sysctl_table(ipmi_table_header);
690 		pr_err("Unable to register SMI watcher: %d\n", rv);
691 		goto out_err;
692 	}
693 
694  out_err:
695 #endif
696 	return rv;
697 }
698 
699 #ifdef MODULE
ipmi_poweroff_cleanup(void)700 static void __exit ipmi_poweroff_cleanup(void)
701 {
702 	int rv;
703 
704 #ifdef CONFIG_PROC_FS
705 	unregister_sysctl_table(ipmi_table_header);
706 #endif
707 
708 	ipmi_smi_watcher_unregister(&smi_watcher);
709 
710 	if (ready) {
711 		rv = ipmi_destroy_user(ipmi_user);
712 		if (rv)
713 			pr_err("could not cleanup the IPMI user: 0x%x\n", rv);
714 		pm_power_off = old_poweroff_func;
715 	}
716 }
717 module_exit(ipmi_poweroff_cleanup);
718 #endif
719 
720 module_init(ipmi_poweroff_init);
721 MODULE_LICENSE("GPL");
722 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
723 MODULE_DESCRIPTION("IPMI Poweroff extension to sys_reboot");
724