34 #include <linux/module.h>
37 #include <linux/string.h>
40 #include <linux/kdev_t.h>
41 #include <linux/ipmi.h>
44 #define PFX "IPMI poweroff: "
46 static void ipmi_po_smi_gone(
int if_num);
47 static void ipmi_po_new_smi(
int if_num,
struct device *
device);
51 #define IPMI_CHASSIS_POWER_DOWN 0
52 #define IPMI_CHASSIS_POWER_CYCLE 0x02
55 static int poweroff_powercycle;
58 static int ifnum_to_use = -1;
63 static int ipmi_ifnum;
67 static void (*old_poweroff_func)(
void);
74 if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum))
77 ipmi_po_smi_gone(ipmi_ifnum);
78 ipmi_po_new_smi(ifnum_to_use,
NULL);
84 MODULE_PARM_DESC(ifnum_to_use,
"The interface number to use for the watchdog "
85 "timer. Setting to -1 defaults to the first registered "
91 " Set to non-zero to enable power cycle instead of power"
92 " down. Power cycle is contingent on hardware support,"
93 " otherwise it defaults back to power down.");
96 static unsigned int mfg_id;
97 static unsigned int prod_id;
99 static unsigned char ipmi_version;
117 .done = dummy_smi_free
120 .done = dummy_recv_free
128 static void receive_handler(
struct ipmi_recv_msg *recv_msg,
void *handler_data)
137 .ipmi_recv_hndl = receive_handler
148 init_completion(&comp);
151 &halt_smi_msg, &halt_recv_msg, 0);
157 return halt_recv_msg.
msg.data[0];
161 static int ipmi_request_in_rc_mode(
ipmi_user_t user,
169 &halt_smi_msg, &halt_recv_msg, 0);
183 return halt_recv_msg.
msg.data[0];
190 #define IPMI_NETFN_ATCA 0x2c
191 #define IPMI_ATCA_SET_POWER_CMD 0x11
192 #define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01
193 #define IPMI_PICMG_ID 0
195 #define IPMI_NETFN_OEM 0x2e
196 #define IPMI_ATCA_PPS_GRACEFUL_RESTART 0x11
197 #define IPMI_ATCA_PPS_IANA "\x00\x40\x0A"
198 #define IPMI_MOTOROLA_MANUFACTURER_ID 0x0000A1
199 #define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID 0x0051
221 rv = ipmi_request_in_rc_mode(user,
226 " IPMI error 0x%x\n", rv);
236 unsigned char data[1];
253 rv = ipmi_request_wait_for_response(user,
262 "Installing Pigeon Point Systems Poweroff Hook\n");
263 atca_oem_poweroff_hook = pps_poweroff_atca;
273 unsigned char data[4];
295 rv = ipmi_request_in_rc_mode(user,
306 " IPMI error 0x%x\n", rv);
310 if (atca_oem_poweroff_hook)
311 atca_oem_poweroff_hook(user);
320 #define IPMI_NETFN_OEM_1 0xf8
321 #define OEM_GRP_CMD_SET_RESET_STATE 0x84
322 #define OEM_GRP_CMD_SET_POWER_STATE 0x82
323 #define IPMI_NETFN_OEM_8 0xf8
324 #define OEM_GRP_CMD_REQUEST_HOTSWAP_CTRL 0x80
325 #define OEM_GRP_CMD_GET_SLOT_GA 0xa3
326 #define IPMI_NETFN_SENSOR_EVT 0x10
327 #define IPMI_CMD_GET_EVENT_RECEIVER 0x01
329 #define IPMI_CPI1_PRODUCT_ID 0x000157
330 #define IPMI_CPI1_MANUFACTURER_ID 0x0108
344 unsigned char data[1];
346 unsigned char hotswap_ipmb;
347 unsigned char aer_addr;
348 unsigned char aer_lun;
366 rv = ipmi_request_in_rc_mode(user,
371 slot = halt_recv_msg.
msg.data[1];
372 hotswap_ipmb = (slot > 9) ? (0xb0 + 2 * slot) : (0xae + 2 *
slot);
381 rv = ipmi_request_in_rc_mode(user,
386 aer_addr = halt_recv_msg.
msg.data[1];
387 aer_lun = halt_recv_msg.
msg.data[2];
393 ipmb_addr.channel = 0;
394 ipmb_addr.slave_addr = aer_addr;
395 ipmb_addr.lun = aer_lun;
402 send_msg.
data = &hotswap_ipmb;
404 ipmi_request_in_rc_mode(user,
416 rv = ipmi_request_in_rc_mode(user,
430 rv = ipmi_request_in_rc_mode(user,
446 #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00}
447 static int ipmi_dell_chassis_detect(
ipmi_user_t user)
453 ipmi_version_major <= 1 &&
454 ipmi_version_minor < 5)
463 #define IPMI_NETFN_CHASSIS_REQUEST 0
464 #define IPMI_CHASSIS_CONTROL_CMD 0x02
472 static void ipmi_poweroff_chassis(
ipmi_user_t user)
477 unsigned char data[1];
488 (poweroff_powercycle ?
"cycle" :
"down"));
495 if (poweroff_powercycle)
501 rv = ipmi_request_in_rc_mode(user,
505 if (poweroff_powercycle) {
508 "cycle message, IPMI error 0x%x\n", rv);
509 poweroff_powercycle = 0;
510 goto powercyclefailed;
514 "down message, IPMI error 0x%x\n", rv);
527 { .platform_type =
"ATCA",
528 .detect = ipmi_atca_detect,
529 .poweroff_func = ipmi_poweroff_atca },
530 { .platform_type =
"CPI1",
531 .detect = ipmi_cpi1_detect,
532 .poweroff_func = ipmi_poweroff_cpi1 },
533 { .platform_type =
"chassis",
534 .detect = ipmi_dell_chassis_detect,
535 .poweroff_func = ipmi_poweroff_chassis },
538 { .platform_type =
"chassis",
539 .detect = ipmi_chassis_detect,
540 .poweroff_func = ipmi_poweroff_chassis },
542 #define NUM_PO_FUNCS (sizeof(poweroff_functions) \
543 / sizeof(struct poweroff_function))
547 static void ipmi_poweroff_function(
void)
553 specific_poweroff_func(ipmi_user);
558 static void ipmi_po_new_smi(
int if_num,
struct device *
device)
568 if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num))
593 rv = ipmi_request_wait_for_response(ipmi_user,
598 " IPMI error 0x%x\n", rv);
602 if (halt_recv_msg.
msg.data_len < 12) {
604 " short, was %d bytes, needed %d bytes\n",
605 halt_recv_msg.
msg.data_len, 12);
610 | (halt_recv_msg.
msg.data[8] << 8)
611 | (halt_recv_msg.
msg.data[9] << 16));
612 prod_id = (halt_recv_msg.
msg.data[10]
613 | (halt_recv_msg.
msg.data[11] << 8));
615 ipmi_version = halt_recv_msg.
msg.data[5];
620 if (poweroff_functions[i].detect(ipmi_user))
626 " will work, giving up\n");
632 poweroff_functions[i].platform_type);
639 static void ipmi_po_smi_gone(
int if_num)
644 if (ipmi_ifnum != if_num)
654 .new_smi = ipmi_po_new_smi,
655 .smi_gone = ipmi_po_smi_gone
659 #ifdef CONFIG_PROC_FS
660 #include <linux/sysctl.h>
663 { .
procname =
"poweroff_powercycle",
664 .data = &poweroff_powercycle,
665 .maxlen =
sizeof(poweroff_powercycle),
674 .child = ipmi_table },
681 .child = ipmi_dir_table },
691 static int __init ipmi_poweroff_init(
void)
696 " IPMI Powerdown via sys_reboot.\n");
698 if (poweroff_powercycle)
701 #ifdef CONFIG_PROC_FS
703 if (!ipmi_table_header) {
712 #ifdef CONFIG_PROC_FS
725 static void __exit ipmi_poweroff_cleanup(
void)
729 #ifdef CONFIG_PROC_FS
739 " user: 0x%x\n", rv);