diff options
| author | Corey Minyard <minyard@acm.org> | 2006-12-06 23:41:09 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 11:39:47 -0500 |
| commit | 7d8ba9669a28f650001093ebbb6ecc3b0a72926f (patch) | |
| tree | f48d6f635ad8b6593de0d1b1df746d13345b2aaf /drivers/char | |
| parent | b361e27bba261ba59c73df464fa640f7c0fe3553 (diff) | |
[PATCH] IPMI: add pigeonpoint poweroff
X86 boards generally use ACPI for the power management interactions with the
BMC. However, non-x86 boards need some help. This patch adds the help for
the Motorola PigeonPoint-based IPMCs.
Signed-off-by: Joseph Barnett <jbarnett@motorola.com>
Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
| -rw-r--r-- | drivers/char/ipmi/ipmi_poweroff.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 85f8071be1..8ce447ab6d 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
| @@ -176,6 +176,42 @@ static int ipmi_request_in_rc_mode(ipmi_user_t user, | |||
| 176 | #define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01 | 176 | #define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01 |
| 177 | #define IPMI_PICMG_ID 0 | 177 | #define IPMI_PICMG_ID 0 |
| 178 | 178 | ||
| 179 | #define IPMI_NETFN_OEM 0x2e | ||
| 180 | #define IPMI_ATCA_PPS_GRACEFUL_RESTART 0x11 | ||
| 181 | #define IPMI_ATCA_PPS_IANA "\x00\x40\x0A" | ||
| 182 | #define IPMI_MOTOROLA_MANUFACTURER_ID 0x0000A1 | ||
| 183 | #define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID 0x0051 | ||
| 184 | |||
| 185 | static void (*atca_oem_poweroff_hook)(ipmi_user_t user) = NULL; | ||
| 186 | |||
| 187 | static void pps_poweroff_atca (ipmi_user_t user) | ||
| 188 | { | ||
| 189 | struct ipmi_system_interface_addr smi_addr; | ||
| 190 | struct kernel_ipmi_msg send_msg; | ||
| 191 | int rv; | ||
| 192 | /* | ||
| 193 | * Configure IPMI address for local access | ||
| 194 | */ | ||
| 195 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
| 196 | smi_addr.channel = IPMI_BMC_CHANNEL; | ||
| 197 | smi_addr.lun = 0; | ||
| 198 | |||
| 199 | printk(KERN_INFO PFX "PPS powerdown hook used"); | ||
| 200 | |||
| 201 | send_msg.netfn = IPMI_NETFN_OEM; | ||
| 202 | send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; | ||
| 203 | send_msg.data = IPMI_ATCA_PPS_IANA; | ||
| 204 | send_msg.data_len = 3; | ||
| 205 | rv = ipmi_request_in_rc_mode(user, | ||
| 206 | (struct ipmi_addr *) &smi_addr, | ||
| 207 | &send_msg); | ||
| 208 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | ||
| 209 | printk(KERN_ERR PFX "Unable to send ATCA ," | ||
| 210 | " IPMI error 0x%x\n", rv); | ||
| 211 | } | ||
| 212 | return; | ||
| 213 | } | ||
| 214 | |||
| 179 | static int ipmi_atca_detect (ipmi_user_t user) | 215 | static int ipmi_atca_detect (ipmi_user_t user) |
| 180 | { | 216 | { |
| 181 | struct ipmi_system_interface_addr smi_addr; | 217 | struct ipmi_system_interface_addr smi_addr; |
| @@ -201,6 +237,13 @@ static int ipmi_atca_detect (ipmi_user_t user) | |||
| 201 | rv = ipmi_request_wait_for_response(user, | 237 | rv = ipmi_request_wait_for_response(user, |
| 202 | (struct ipmi_addr *) &smi_addr, | 238 | (struct ipmi_addr *) &smi_addr, |
| 203 | &send_msg); | 239 | &send_msg); |
| 240 | |||
| 241 | printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id); | ||
| 242 | if((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) | ||
| 243 | && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { | ||
| 244 | printk(KERN_INFO PFX "Installing Pigeon Point Systems Poweroff Hook\n"); | ||
| 245 | atca_oem_poweroff_hook = pps_poweroff_atca; | ||
| 246 | } | ||
| 204 | return !rv; | 247 | return !rv; |
| 205 | } | 248 | } |
| 206 | 249 | ||
| @@ -234,12 +277,19 @@ static void ipmi_poweroff_atca (ipmi_user_t user) | |||
| 234 | rv = ipmi_request_in_rc_mode(user, | 277 | rv = ipmi_request_in_rc_mode(user, |
| 235 | (struct ipmi_addr *) &smi_addr, | 278 | (struct ipmi_addr *) &smi_addr, |
| 236 | &send_msg); | 279 | &send_msg); |
| 237 | if (rv) { | 280 | /** At this point, the system may be shutting down, and most |
| 281 | ** serial drivers (if used) will have interrupts turned off | ||
| 282 | ** it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE | ||
| 283 | ** return code | ||
| 284 | **/ | ||
| 285 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | ||
| 238 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," | 286 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," |
| 239 | " IPMI error 0x%x\n", rv); | 287 | " IPMI error 0x%x\n", rv); |
| 240 | goto out; | 288 | goto out; |
| 241 | } | 289 | } |
| 242 | 290 | ||
| 291 | if(atca_oem_poweroff_hook) | ||
| 292 | return atca_oem_poweroff_hook(user); | ||
| 243 | out: | 293 | out: |
| 244 | return; | 294 | return; |
| 245 | } | 295 | } |
