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