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