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