xref: /linux/drivers/char/ipmi/ipmi_poweroff.c (revision ccea15f45eb0ab12d658f88b5d4be005cb2bb1a7)
1 /*
2  * ipmi_poweroff.c
3  *
4  * MontaVista IPMI Poweroff extension to sys_reboot
5  *
6  * Author: MontaVista Software, Inc.
7  *         Steven Dake <sdake@mvista.com>
8  *         Corey Minyard <cminyard@mvista.com>
9  *         source@mvista.com
10  *
11  * Copyright 2002,2004 MontaVista Software Inc.
12  *
13  *  This program is free software; you can redistribute it and/or modify it
14  *  under the terms of the GNU General Public License as published by the
15  *  Free Software Foundation; either version 2 of the License, or (at your
16  *  option) any later version.
17  *
18  *
19  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
28  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *  You should have received a copy of the GNU General Public License along
31  *  with this program; if not, write to the Free Software Foundation, Inc.,
32  *  675 Mass Ave, Cambridge, MA 02139, USA.
33  */
34 #include <linux/config.h>
35 #include <linux/module.h>
36 #include <linux/moduleparam.h>
37 #include <linux/proc_fs.h>
38 #include <linux/string.h>
39 #include <linux/completion.h>
40 #include <linux/pm.h>
41 #include <linux/kdev_t.h>
42 #include <linux/ipmi.h>
43 #include <linux/ipmi_smi.h>
44 
45 #define PFX "IPMI poweroff: "
46 
47 /* Definitions for controlling power off (if the system supports it).  It
48  * conveniently matches the IPMI chassis control values. */
49 #define IPMI_CHASSIS_POWER_DOWN		0	/* power down, the default. */
50 #define IPMI_CHASSIS_POWER_CYCLE	0x02	/* power cycle */
51 
52 /* the IPMI data command */
53 static int poweroff_powercycle;
54 
55 /* parameter definition to allow user to flag power cycle */
56 module_param(poweroff_powercycle, int, 0644);
57 MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
58 
59 /* Stuff from the get device id command. */
60 static unsigned int mfg_id;
61 static unsigned int prod_id;
62 static unsigned char capabilities;
63 static unsigned char ipmi_version;
64 
65 /* We use our own messages for this operation, we don't let the system
66    allocate them, since we may be in a panic situation.  The whole
67    thing is single-threaded, anyway, so multiple messages are not
68    required. */
69 static void dummy_smi_free(struct ipmi_smi_msg *msg)
70 {
71 }
72 static void dummy_recv_free(struct ipmi_recv_msg *msg)
73 {
74 }
75 static struct ipmi_smi_msg halt_smi_msg =
76 {
77 	.done = dummy_smi_free
78 };
79 static struct ipmi_recv_msg halt_recv_msg =
80 {
81 	.done = dummy_recv_free
82 };
83 
84 
85 /*
86  * Code to send a message and wait for the reponse.
87  */
88 
89 static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
90 {
91 	struct completion *comp = recv_msg->user_msg_data;
92 
93 	if (comp)
94 		complete(comp);
95 }
96 
97 static struct ipmi_user_hndl ipmi_poweroff_handler =
98 {
99 	.ipmi_recv_hndl = receive_handler
100 };
101 
102 
103 static int ipmi_request_wait_for_response(ipmi_user_t            user,
104 					  struct ipmi_addr       *addr,
105 					  struct kernel_ipmi_msg *send_msg)
106 {
107 	int               rv;
108 	struct completion comp;
109 
110 	init_completion(&comp);
111 
112 	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
113 				      &halt_smi_msg, &halt_recv_msg, 0);
114 	if (rv)
115 		return rv;
116 
117 	wait_for_completion(&comp);
118 
119 	return halt_recv_msg.msg.data[0];
120 }
121 
122 /* We are in run-to-completion mode, no completion is desired. */
123 static int ipmi_request_in_rc_mode(ipmi_user_t            user,
124 				   struct ipmi_addr       *addr,
125 				   struct kernel_ipmi_msg *send_msg)
126 {
127 	int rv;
128 
129 	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
130 				      &halt_smi_msg, &halt_recv_msg, 0);
131 	if (rv)
132 		return rv;
133 
134 	return halt_recv_msg.msg.data[0];
135 }
136 
137 /*
138  * ATCA Support
139  */
140 
141 #define IPMI_NETFN_ATCA			0x2c
142 #define IPMI_ATCA_SET_POWER_CMD		0x11
143 #define IPMI_ATCA_GET_ADDR_INFO_CMD	0x01
144 #define IPMI_PICMG_ID			0
145 
146 static int ipmi_atca_detect (ipmi_user_t user)
147 {
148 	struct ipmi_system_interface_addr smi_addr;
149 	struct kernel_ipmi_msg            send_msg;
150 	int                               rv;
151 	unsigned char                     data[1];
152 
153         /*
154          * Configure IPMI address for local access
155          */
156         smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
157         smi_addr.channel = IPMI_BMC_CHANNEL;
158         smi_addr.lun = 0;
159 
160 	/*
161 	 * Use get address info to check and see if we are ATCA
162 	 */
163 	send_msg.netfn = IPMI_NETFN_ATCA;
164 	send_msg.cmd = IPMI_ATCA_GET_ADDR_INFO_CMD;
165 	data[0] = IPMI_PICMG_ID;
166 	send_msg.data = data;
167 	send_msg.data_len = sizeof(data);
168 	rv = ipmi_request_wait_for_response(user,
169 					    (struct ipmi_addr *) &smi_addr,
170 					    &send_msg);
171 	return !rv;
172 }
173 
174 static void ipmi_poweroff_atca (ipmi_user_t user)
175 {
176 	struct ipmi_system_interface_addr smi_addr;
177 	struct kernel_ipmi_msg            send_msg;
178 	int                               rv;
179 	unsigned char                     data[4];
180 
181         /*
182          * Configure IPMI address for local access
183          */
184         smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
185         smi_addr.channel = IPMI_BMC_CHANNEL;
186         smi_addr.lun = 0;
187 
188 	printk(KERN_INFO PFX "Powering down via ATCA power command\n");
189 
190 	/*
191 	 * Power down
192 	 */
193 	send_msg.netfn = IPMI_NETFN_ATCA;
194 	send_msg.cmd = IPMI_ATCA_SET_POWER_CMD;
195 	data[0] = IPMI_PICMG_ID;
196 	data[1] = 0; /* FRU id */
197 	data[2] = 0; /* Power Level */
198 	data[3] = 0; /* Don't change saved presets */
199 	send_msg.data = data;
200 	send_msg.data_len = sizeof (data);
201 	rv = ipmi_request_in_rc_mode(user,
202 				     (struct ipmi_addr *) &smi_addr,
203 				     &send_msg);
204 	if (rv) {
205 		printk(KERN_ERR PFX "Unable to send ATCA powerdown message,"
206 		       " IPMI error 0x%x\n", rv);
207 		goto out;
208 	}
209 
210  out:
211 	return;
212 }
213 
214 /*
215  * CPI1 Support
216  */
217 
218 #define IPMI_NETFN_OEM_1				0xf8
219 #define OEM_GRP_CMD_SET_RESET_STATE		0x84
220 #define OEM_GRP_CMD_SET_POWER_STATE		0x82
221 #define IPMI_NETFN_OEM_8				0xf8
222 #define OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL	0x80
223 #define OEM_GRP_CMD_GET_SLOT_GA			0xa3
224 #define IPMI_NETFN_SENSOR_EVT			0x10
225 #define IPMI_CMD_GET_EVENT_RECEIVER		0x01
226 
227 #define IPMI_CPI1_PRODUCT_ID		0x000157
228 #define IPMI_CPI1_MANUFACTURER_ID	0x0108
229 
230 static int ipmi_cpi1_detect (ipmi_user_t user)
231 {
232 	return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID)
233 		&& (prod_id == IPMI_CPI1_PRODUCT_ID));
234 }
235 
236 static void ipmi_poweroff_cpi1 (ipmi_user_t user)
237 {
238 	struct ipmi_system_interface_addr smi_addr;
239 	struct ipmi_ipmb_addr             ipmb_addr;
240 	struct kernel_ipmi_msg            send_msg;
241 	int                               rv;
242 	unsigned char                     data[1];
243 	int                               slot;
244 	unsigned char                     hotswap_ipmb;
245 	unsigned char                     aer_addr;
246 	unsigned char                     aer_lun;
247 
248         /*
249          * Configure IPMI address for local access
250          */
251         smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
252         smi_addr.channel = IPMI_BMC_CHANNEL;
253         smi_addr.lun = 0;
254 
255 	printk(KERN_INFO PFX "Powering down via CPI1 power command\n");
256 
257 	/*
258 	 * Get IPMI ipmb address
259 	 */
260 	send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
261 	send_msg.cmd = OEM_GRP_CMD_GET_SLOT_GA;
262 	send_msg.data = NULL;
263 	send_msg.data_len = 0;
264 	rv = ipmi_request_in_rc_mode(user,
265 				     (struct ipmi_addr *) &smi_addr,
266 				     &send_msg);
267 	if (rv)
268 		goto out;
269 	slot = halt_recv_msg.msg.data[1];
270 	hotswap_ipmb = (slot > 9) ? (0xb0 + 2 * slot) : (0xae + 2 * slot);
271 
272 	/*
273 	 * Get active event receiver
274 	 */
275 	send_msg.netfn = IPMI_NETFN_SENSOR_EVT >> 2;
276 	send_msg.cmd = IPMI_CMD_GET_EVENT_RECEIVER;
277 	send_msg.data = NULL;
278 	send_msg.data_len = 0;
279 	rv = ipmi_request_in_rc_mode(user,
280 				     (struct ipmi_addr *) &smi_addr,
281 				     &send_msg);
282 	if (rv)
283 		goto out;
284 	aer_addr = halt_recv_msg.msg.data[1];
285 	aer_lun = halt_recv_msg.msg.data[2];
286 
287 	/*
288 	 * Setup IPMB address target instead of local target
289 	 */
290 	ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
291 	ipmb_addr.channel = 0;
292 	ipmb_addr.slave_addr = aer_addr;
293 	ipmb_addr.lun = aer_lun;
294 
295 	/*
296 	 * Send request hotswap control to remove blade from dpv
297 	 */
298 	send_msg.netfn = IPMI_NETFN_OEM_8 >> 2;
299 	send_msg.cmd = OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL;
300 	send_msg.data = &hotswap_ipmb;
301 	send_msg.data_len = 1;
302 	ipmi_request_in_rc_mode(user,
303 				(struct ipmi_addr *) &ipmb_addr,
304 				&send_msg);
305 
306 	/*
307 	 * Set reset asserted
308 	 */
309 	send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
310 	send_msg.cmd = OEM_GRP_CMD_SET_RESET_STATE;
311 	send_msg.data = data;
312 	data[0] = 1; /* Reset asserted state */
313 	send_msg.data_len = 1;
314 	rv = ipmi_request_in_rc_mode(user,
315 				     (struct ipmi_addr *) &smi_addr,
316 				     &send_msg);
317 	if (rv)
318 		goto out;
319 
320 	/*
321 	 * Power down
322 	 */
323 	send_msg.netfn = IPMI_NETFN_OEM_1 >> 2;
324 	send_msg.cmd = OEM_GRP_CMD_SET_POWER_STATE;
325 	send_msg.data = data;
326 	data[0] = 1; /* Power down state */
327 	send_msg.data_len = 1;
328 	rv = ipmi_request_in_rc_mode(user,
329 				     (struct ipmi_addr *) &smi_addr,
330 				     &send_msg);
331 	if (rv)
332 		goto out;
333 
334  out:
335 	return;
336 }
337 
338 /*
339  * ipmi_dell_chassis_detect()
340  * Dell systems with IPMI < 1.5 don't set the chassis capability bit
341  * but they can handle a chassis poweroff or powercycle command.
342  */
343 
344 #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00}
345 static int ipmi_dell_chassis_detect (ipmi_user_t user)
346 {
347 	const char ipmi_version_major = ipmi_version & 0xF;
348 	const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
349 	const char mfr[3] = DELL_IANA_MFR_ID;
350 	if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
351 	    ipmi_version_major <= 1 &&
352 	    ipmi_version_minor < 5)
353 		return 1;
354 	return 0;
355 }
356 
357 /*
358  * Standard chassis support
359  */
360 
361 #define IPMI_NETFN_CHASSIS_REQUEST	0
362 #define IPMI_CHASSIS_CONTROL_CMD	0x02
363 
364 static int ipmi_chassis_detect (ipmi_user_t user)
365 {
366 	/* Chassis support, use it. */
367 	return (capabilities & 0x80);
368 }
369 
370 static void ipmi_poweroff_chassis (ipmi_user_t user)
371 {
372 	struct ipmi_system_interface_addr smi_addr;
373 	struct kernel_ipmi_msg            send_msg;
374 	int                               rv;
375 	unsigned char                     data[1];
376 
377         /*
378          * Configure IPMI address for local access
379          */
380         smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
381         smi_addr.channel = IPMI_BMC_CHANNEL;
382         smi_addr.lun = 0;
383 
384  powercyclefailed:
385 	printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
386 		(poweroff_powercycle ? "cycle" : "down"));
387 
388 	/*
389 	 * Power down
390 	 */
391 	send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
392 	send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
393 	if (poweroff_powercycle)
394 		data[0] = IPMI_CHASSIS_POWER_CYCLE;
395 	else
396 		data[0] = IPMI_CHASSIS_POWER_DOWN;
397 	send_msg.data = data;
398 	send_msg.data_len = sizeof(data);
399 	rv = ipmi_request_in_rc_mode(user,
400 				     (struct ipmi_addr *) &smi_addr,
401 				     &send_msg);
402 	if (rv) {
403 		if (poweroff_powercycle) {
404 			/* power cycle failed, default to power down */
405 			printk(KERN_ERR PFX "Unable to send chassis power " \
406 			       "cycle message, IPMI error 0x%x\n", rv);
407 			poweroff_powercycle = 0;
408 			goto powercyclefailed;
409 		}
410 
411 		printk(KERN_ERR PFX "Unable to send chassis power " \
412 		       "down message, IPMI error 0x%x\n", rv);
413 	}
414 }
415 
416 
417 /* Table of possible power off functions. */
418 struct poweroff_function {
419 	char *platform_type;
420 	int  (*detect)(ipmi_user_t user);
421 	void (*poweroff_func)(ipmi_user_t user);
422 };
423 
424 static struct poweroff_function poweroff_functions[] = {
425 	{ .platform_type	= "ATCA",
426 	  .detect		= ipmi_atca_detect,
427 	  .poweroff_func	= ipmi_poweroff_atca },
428 	{ .platform_type	= "CPI1",
429 	  .detect		= ipmi_cpi1_detect,
430 	  .poweroff_func	= ipmi_poweroff_cpi1 },
431 	{ .platform_type	= "chassis",
432 	  .detect		= ipmi_dell_chassis_detect,
433 	  .poweroff_func	= ipmi_poweroff_chassis },
434 	/* Chassis should generally be last, other things should override
435 	   it. */
436 	{ .platform_type	= "chassis",
437 	  .detect		= ipmi_chassis_detect,
438 	  .poweroff_func	= ipmi_poweroff_chassis },
439 };
440 #define NUM_PO_FUNCS (sizeof(poweroff_functions) \
441 		      / sizeof(struct poweroff_function))
442 
443 
444 /* Our local state. */
445 static int ready = 0;
446 static ipmi_user_t ipmi_user;
447 static void (*specific_poweroff_func)(ipmi_user_t user) = NULL;
448 
449 /* Holds the old poweroff function so we can restore it on removal. */
450 static void (*old_poweroff_func)(void);
451 
452 
453 /* Called on a powerdown request. */
454 static void ipmi_poweroff_function (void)
455 {
456 	if (!ready)
457 		return;
458 
459 	/* Use run-to-completion mode, since interrupts may be off. */
460 	ipmi_user_set_run_to_completion(ipmi_user, 1);
461 	specific_poweroff_func(ipmi_user);
462 	ipmi_user_set_run_to_completion(ipmi_user, 0);
463 }
464 
465 /* Wait for an IPMI interface to be installed, the first one installed
466    will be grabbed by this code and used to perform the powerdown. */
467 static void ipmi_po_new_smi(int if_num, struct device *device)
468 {
469 	struct ipmi_system_interface_addr smi_addr;
470 	struct kernel_ipmi_msg            send_msg;
471 	int                               rv;
472 	int                               i;
473 
474 	if (ready)
475 		return;
476 
477 	rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
478 			      &ipmi_user);
479 	if (rv) {
480 		printk(KERN_ERR PFX "could not create IPMI user, error %d\n",
481 		       rv);
482 		return;
483 	}
484 
485         /*
486          * Do a get device ide and store some results, since this is
487 	 * used by several functions.
488          */
489         smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
490         smi_addr.channel = IPMI_BMC_CHANNEL;
491         smi_addr.lun = 0;
492 
493 	send_msg.netfn = IPMI_NETFN_APP_REQUEST;
494 	send_msg.cmd = IPMI_GET_DEVICE_ID_CMD;
495 	send_msg.data = NULL;
496 	send_msg.data_len = 0;
497 	rv = ipmi_request_wait_for_response(ipmi_user,
498 					    (struct ipmi_addr *) &smi_addr,
499 					    &send_msg);
500 	if (rv) {
501 		printk(KERN_ERR PFX "Unable to send IPMI get device id info,"
502 		       " IPMI error 0x%x\n", rv);
503 		goto out_err;
504 	}
505 
506 	if (halt_recv_msg.msg.data_len < 12) {
507 		printk(KERN_ERR PFX "(chassis) IPMI get device id info too,"
508 		       " short, was %d bytes, needed %d bytes\n",
509 		       halt_recv_msg.msg.data_len, 12);
510 		goto out_err;
511 	}
512 
513 	mfg_id = (halt_recv_msg.msg.data[7]
514 		  | (halt_recv_msg.msg.data[8] << 8)
515 		  | (halt_recv_msg.msg.data[9] << 16));
516 	prod_id = (halt_recv_msg.msg.data[10]
517 		   | (halt_recv_msg.msg.data[11] << 8));
518 	capabilities = halt_recv_msg.msg.data[6];
519 	ipmi_version = halt_recv_msg.msg.data[5];
520 
521 
522 	/* Scan for a poweroff method */
523 	for (i = 0; i < NUM_PO_FUNCS; i++) {
524 		if (poweroff_functions[i].detect(ipmi_user))
525 			goto found;
526 	}
527 
528  out_err:
529 	printk(KERN_ERR PFX "Unable to find a poweroff function that"
530 	       " will work, giving up\n");
531 	ipmi_destroy_user(ipmi_user);
532 	return;
533 
534  found:
535 	printk(KERN_INFO PFX "Found a %s style poweroff function\n",
536 	       poweroff_functions[i].platform_type);
537 	specific_poweroff_func = poweroff_functions[i].poweroff_func;
538 	old_poweroff_func = pm_power_off;
539 	pm_power_off = ipmi_poweroff_function;
540 	ready = 1;
541 }
542 
543 static void ipmi_po_smi_gone(int if_num)
544 {
545 	/* This can never be called, because once poweroff driver is
546 	   registered, the interface can't go away until the power
547 	   driver is unregistered. */
548 }
549 
550 static struct ipmi_smi_watcher smi_watcher =
551 {
552 	.owner    = THIS_MODULE,
553 	.new_smi  = ipmi_po_new_smi,
554 	.smi_gone = ipmi_po_smi_gone
555 };
556 
557 
558 #ifdef CONFIG_PROC_FS
559 #include <linux/sysctl.h>
560 
561 static ctl_table ipmi_table[] = {
562 	{ .ctl_name	= DEV_IPMI_POWEROFF_POWERCYCLE,
563 	  .procname	= "poweroff_powercycle",
564 	  .data		= &poweroff_powercycle,
565 	  .maxlen	= sizeof(poweroff_powercycle),
566 	  .mode		= 0644,
567 	  .proc_handler	= &proc_dointvec },
568 	{ }
569 };
570 
571 static ctl_table ipmi_dir_table[] = {
572 	{ .ctl_name	= DEV_IPMI,
573 	  .procname	= "ipmi",
574 	  .mode		= 0555,
575 	  .child	= ipmi_table },
576 	{ }
577 };
578 
579 static ctl_table ipmi_root_table[] = {
580 	{ .ctl_name	= CTL_DEV,
581 	  .procname	= "dev",
582 	  .mode		= 0555,
583 	  .child	= ipmi_dir_table },
584 	{ }
585 };
586 
587 static struct ctl_table_header *ipmi_table_header;
588 #endif /* CONFIG_PROC_FS */
589 
590 /*
591  * Startup and shutdown functions.
592  */
593 static int ipmi_poweroff_init (void)
594 {
595 	int rv;
596 
597 	printk ("Copyright (C) 2004 MontaVista Software -"
598 		" IPMI Powerdown via sys_reboot.\n");
599 
600 	if (poweroff_powercycle)
601 		printk(KERN_INFO PFX "Power cycle is enabled.\n");
602 
603 #ifdef CONFIG_PROC_FS
604 	ipmi_table_header = register_sysctl_table(ipmi_root_table, 1);
605 	if (!ipmi_table_header) {
606 		printk(KERN_ERR PFX "Unable to register powercycle sysctl\n");
607 		rv = -ENOMEM;
608 		goto out_err;
609 	}
610 #endif
611 
612 	rv = ipmi_smi_watcher_register(&smi_watcher);
613 
614 #ifdef CONFIG_PROC_FS
615 	if (rv) {
616 		unregister_sysctl_table(ipmi_table_header);
617 		printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
618 		goto out_err;
619 	}
620 #endif
621 
622  out_err:
623 	return rv;
624 }
625 
626 #ifdef MODULE
627 static __exit void ipmi_poweroff_cleanup(void)
628 {
629 	int rv;
630 
631 #ifdef CONFIG_PROC_FS
632 	unregister_sysctl_table(ipmi_table_header);
633 #endif
634 
635 	ipmi_smi_watcher_unregister(&smi_watcher);
636 
637 	if (ready) {
638 		rv = ipmi_destroy_user(ipmi_user);
639 		if (rv)
640 			printk(KERN_ERR PFX "could not cleanup the IPMI"
641 			       " user: 0x%x\n", rv);
642 		pm_power_off = old_poweroff_func;
643 	}
644 }
645 module_exit(ipmi_poweroff_cleanup);
646 #endif
647 
648 module_init(ipmi_poweroff_init);
649 MODULE_LICENSE("GPL");
650 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
651 MODULE_DESCRIPTION("IPMI Poweroff extension to sys_reboot");
652