ipmi_poweroff.c (19027B)
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 27static void ipmi_po_smi_gone(int if_num); 28static 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 */ 36static int poweroff_powercycle; 37 38/* Which interface to use, -1 means the first we see. */ 39static int ifnum_to_use = -1; 40 41/* Our local state. */ 42static int ready; 43static struct ipmi_user *ipmi_user; 44static int ipmi_ifnum; 45static void (*specific_poweroff_func)(struct ipmi_user *user); 46 47/* Holds the old poweroff function so we can restore it on removal. */ 48static void (*old_poweroff_func)(void); 49 50static 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 63module_param_call(ifnum_to_use, set_param_ifnum, param_get_int, 64 &ifnum_to_use, 0644); 65MODULE_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 */ 70module_param(poweroff_powercycle, int, 0644); 71MODULE_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. */ 77static unsigned int mfg_id; 78static unsigned int prod_id; 79static unsigned char capabilities; 80static 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 */ 88static atomic_t dummy_count = ATOMIC_INIT(0); 89static void dummy_smi_free(struct ipmi_smi_msg *msg) 90{ 91 atomic_dec(&dummy_count); 92} 93static void dummy_recv_free(struct ipmi_recv_msg *msg) 94{ 95 atomic_dec(&dummy_count); 96} 97static struct ipmi_smi_msg halt_smi_msg = INIT_IPMI_SMI_MSG(dummy_smi_free); 98static 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 105static 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 113static const struct ipmi_user_hndl ipmi_poweroff_handler = { 114 .ipmi_recv_hndl = receive_handler 115}; 116 117 118static 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. */ 138static 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 178static void (*atca_oem_poweroff_hook)(struct ipmi_user *user); 179 180static 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 207static 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 242static 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 306static 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 312static 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} 421static 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 442static 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 458static int ipmi_chassis_detect(struct ipmi_user *user) 459{ 460 /* Chassis support, use it. */ 461 return (capabilities & 0x80); 462} 463 464static 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. */ 512struct poweroff_function { 513 char *platform_type; 514 int (*detect)(struct ipmi_user *user); 515 void (*poweroff_func)(struct ipmi_user *user); 516}; 517 518static 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. */ 541static 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. */ 552static 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 630static 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 643static 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 653static 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 662static struct ctl_table ipmi_dir_table[] = { 663 { .procname = "ipmi", 664 .mode = 0555, 665 .child = ipmi_table }, 666 { } 667}; 668 669static struct ctl_table ipmi_root_table[] = { 670 { .procname = "dev", 671 .mode = 0555, 672 .child = ipmi_dir_table }, 673 { } 674}; 675 676static struct ctl_table_header *ipmi_table_header; 677#endif /* CONFIG_PROC_FS */ 678 679/* 680 * Startup and shutdown functions. 681 */ 682static int __init ipmi_poweroff_init(void) 683{ 684 int rv; 685 686 pr_info("Copyright (C) 2004 MontaVista Software - IPMI Powerdown via sys_reboot\n"); 687 688 if (poweroff_powercycle) 689 pr_info("Power cycle is enabled\n"); 690 691#ifdef CONFIG_PROC_FS 692 ipmi_table_header = register_sysctl_table(ipmi_root_table); 693 if (!ipmi_table_header) { 694 pr_err("Unable to register powercycle sysctl\n"); 695 rv = -ENOMEM; 696 goto out_err; 697 } 698#endif 699 700 rv = ipmi_smi_watcher_register(&smi_watcher); 701 702#ifdef CONFIG_PROC_FS 703 if (rv) { 704 unregister_sysctl_table(ipmi_table_header); 705 pr_err("Unable to register SMI watcher: %d\n", rv); 706 goto out_err; 707 } 708 709 out_err: 710#endif 711 return rv; 712} 713 714#ifdef MODULE 715static void __exit ipmi_poweroff_cleanup(void) 716{ 717 int rv; 718 719#ifdef CONFIG_PROC_FS 720 unregister_sysctl_table(ipmi_table_header); 721#endif 722 723 ipmi_smi_watcher_unregister(&smi_watcher); 724 725 if (ready) { 726 rv = ipmi_destroy_user(ipmi_user); 727 if (rv) 728 pr_err("could not cleanup the IPMI user: 0x%x\n", rv); 729 pm_power_off = old_poweroff_func; 730 } 731} 732module_exit(ipmi_poweroff_cleanup); 733#endif 734 735module_init(ipmi_poweroff_init); 736MODULE_LICENSE("GPL"); 737MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); 738MODULE_DESCRIPTION("IPMI Poweroff extension to sys_reboot");