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