diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_poweroff.c | 184 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 244 |
2 files changed, 227 insertions, 201 deletions
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index b065a53d1ca8..f776df788794 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -87,7 +87,10 @@ MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " | |||
87 | 87 | ||
88 | /* parameter definition to allow user to flag power cycle */ | 88 | /* parameter definition to allow user to flag power cycle */ |
89 | module_param(poweroff_powercycle, int, 0644); | 89 | module_param(poweroff_powercycle, int, 0644); |
90 | MODULE_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."); | 90 | MODULE_PARM_DESC(poweroff_powercycle, |
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."); | ||
91 | 94 | ||
92 | /* Stuff from the get device id command. */ | 95 | /* Stuff from the get device id command. */ |
93 | static unsigned int mfg_id; | 96 | static unsigned int mfg_id; |
@@ -95,10 +98,12 @@ static unsigned int prod_id; | |||
95 | static unsigned char capabilities; | 98 | static unsigned char capabilities; |
96 | static unsigned char ipmi_version; | 99 | static unsigned char ipmi_version; |
97 | 100 | ||
98 | /* We use our own messages for this operation, we don't let the system | 101 | /* |
99 | allocate them, since we may be in a panic situation. The whole | 102 | * We use our own messages for this operation, we don't let the system |
100 | thing is single-threaded, anyway, so multiple messages are not | 103 | * allocate them, since we may be in a panic situation. The whole |
101 | required. */ | 104 | * thing is single-threaded, anyway, so multiple messages are not |
105 | * required. | ||
106 | */ | ||
102 | static atomic_t dummy_count = ATOMIC_INIT(0); | 107 | static atomic_t dummy_count = ATOMIC_INIT(0); |
103 | static void dummy_smi_free(struct ipmi_smi_msg *msg) | 108 | static void dummy_smi_free(struct ipmi_smi_msg *msg) |
104 | { | 109 | { |
@@ -108,12 +113,10 @@ static void dummy_recv_free(struct ipmi_recv_msg *msg) | |||
108 | { | 113 | { |
109 | atomic_dec(&dummy_count); | 114 | atomic_dec(&dummy_count); |
110 | } | 115 | } |
111 | static struct ipmi_smi_msg halt_smi_msg = | 116 | static struct ipmi_smi_msg halt_smi_msg = { |
112 | { | ||
113 | .done = dummy_smi_free | 117 | .done = dummy_smi_free |
114 | }; | 118 | }; |
115 | static struct ipmi_recv_msg halt_recv_msg = | 119 | static struct ipmi_recv_msg halt_recv_msg = { |
116 | { | ||
117 | .done = dummy_recv_free | 120 | .done = dummy_recv_free |
118 | }; | 121 | }; |
119 | 122 | ||
@@ -130,8 +133,7 @@ static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data) | |||
130 | complete(comp); | 133 | complete(comp); |
131 | } | 134 | } |
132 | 135 | ||
133 | static struct ipmi_user_hndl ipmi_poweroff_handler = | 136 | static struct ipmi_user_hndl ipmi_poweroff_handler = { |
134 | { | ||
135 | .ipmi_recv_hndl = receive_handler | 137 | .ipmi_recv_hndl = receive_handler |
136 | }; | 138 | }; |
137 | 139 | ||
@@ -198,47 +200,47 @@ static int ipmi_request_in_rc_mode(ipmi_user_t user, | |||
198 | 200 | ||
199 | static void (*atca_oem_poweroff_hook)(ipmi_user_t user); | 201 | static void (*atca_oem_poweroff_hook)(ipmi_user_t user); |
200 | 202 | ||
201 | static void pps_poweroff_atca (ipmi_user_t user) | 203 | static void pps_poweroff_atca(ipmi_user_t user) |
202 | { | 204 | { |
203 | struct ipmi_system_interface_addr smi_addr; | 205 | struct ipmi_system_interface_addr smi_addr; |
204 | struct kernel_ipmi_msg send_msg; | 206 | struct kernel_ipmi_msg send_msg; |
205 | int rv; | 207 | int rv; |
206 | /* | 208 | /* |
207 | * Configure IPMI address for local access | 209 | * Configure IPMI address for local access |
208 | */ | 210 | */ |
209 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 211 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
210 | smi_addr.channel = IPMI_BMC_CHANNEL; | 212 | smi_addr.channel = IPMI_BMC_CHANNEL; |
211 | smi_addr.lun = 0; | 213 | smi_addr.lun = 0; |
212 | 214 | ||
213 | printk(KERN_INFO PFX "PPS powerdown hook used"); | 215 | printk(KERN_INFO PFX "PPS powerdown hook used"); |
214 | 216 | ||
215 | send_msg.netfn = IPMI_NETFN_OEM; | 217 | send_msg.netfn = IPMI_NETFN_OEM; |
216 | send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; | 218 | send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; |
217 | send_msg.data = IPMI_ATCA_PPS_IANA; | 219 | send_msg.data = IPMI_ATCA_PPS_IANA; |
218 | send_msg.data_len = 3; | 220 | send_msg.data_len = 3; |
219 | rv = ipmi_request_in_rc_mode(user, | 221 | rv = ipmi_request_in_rc_mode(user, |
220 | (struct ipmi_addr *) &smi_addr, | 222 | (struct ipmi_addr *) &smi_addr, |
221 | &send_msg); | 223 | &send_msg); |
222 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | 224 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { |
223 | printk(KERN_ERR PFX "Unable to send ATCA ," | 225 | printk(KERN_ERR PFX "Unable to send ATCA ," |
224 | " IPMI error 0x%x\n", rv); | 226 | " IPMI error 0x%x\n", rv); |
225 | } | 227 | } |
226 | return; | 228 | return; |
227 | } | 229 | } |
228 | 230 | ||
229 | static int ipmi_atca_detect (ipmi_user_t user) | 231 | static int ipmi_atca_detect(ipmi_user_t user) |
230 | { | 232 | { |
231 | struct ipmi_system_interface_addr smi_addr; | 233 | struct ipmi_system_interface_addr smi_addr; |
232 | struct kernel_ipmi_msg send_msg; | 234 | struct kernel_ipmi_msg send_msg; |
233 | int rv; | 235 | int rv; |
234 | unsigned char data[1]; | 236 | unsigned char data[1]; |
235 | 237 | ||
236 | /* | 238 | /* |
237 | * Configure IPMI address for local access | 239 | * Configure IPMI address for local access |
238 | */ | 240 | */ |
239 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 241 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
240 | smi_addr.channel = IPMI_BMC_CHANNEL; | 242 | smi_addr.channel = IPMI_BMC_CHANNEL; |
241 | smi_addr.lun = 0; | 243 | smi_addr.lun = 0; |
242 | 244 | ||
243 | /* | 245 | /* |
244 | * Use get address info to check and see if we are ATCA | 246 | * Use get address info to check and see if we are ATCA |
@@ -252,28 +254,30 @@ static int ipmi_atca_detect (ipmi_user_t user) | |||
252 | (struct ipmi_addr *) &smi_addr, | 254 | (struct ipmi_addr *) &smi_addr, |
253 | &send_msg); | 255 | &send_msg); |
254 | 256 | ||
255 | printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id); | 257 | printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", |
256 | if((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) | 258 | mfg_id, prod_id); |
257 | && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { | 259 | if ((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) |
258 | printk(KERN_INFO PFX "Installing Pigeon Point Systems Poweroff Hook\n"); | 260 | && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { |
261 | printk(KERN_INFO PFX | ||
262 | "Installing Pigeon Point Systems Poweroff Hook\n"); | ||
259 | atca_oem_poweroff_hook = pps_poweroff_atca; | 263 | atca_oem_poweroff_hook = pps_poweroff_atca; |
260 | } | 264 | } |
261 | return !rv; | 265 | return !rv; |
262 | } | 266 | } |
263 | 267 | ||
264 | static void ipmi_poweroff_atca (ipmi_user_t user) | 268 | static void ipmi_poweroff_atca(ipmi_user_t user) |
265 | { | 269 | { |
266 | struct ipmi_system_interface_addr smi_addr; | 270 | struct ipmi_system_interface_addr smi_addr; |
267 | struct kernel_ipmi_msg send_msg; | 271 | struct kernel_ipmi_msg send_msg; |
268 | int rv; | 272 | int rv; |
269 | unsigned char data[4]; | 273 | unsigned char data[4]; |
270 | 274 | ||
271 | /* | 275 | /* |
272 | * Configure IPMI address for local access | 276 | * Configure IPMI address for local access |
273 | */ | 277 | */ |
274 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 278 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
275 | smi_addr.channel = IPMI_BMC_CHANNEL; | 279 | smi_addr.channel = IPMI_BMC_CHANNEL; |
276 | smi_addr.lun = 0; | 280 | smi_addr.lun = 0; |
277 | 281 | ||
278 | printk(KERN_INFO PFX "Powering down via ATCA power command\n"); | 282 | printk(KERN_INFO PFX "Powering down via ATCA power command\n"); |
279 | 283 | ||
@@ -287,22 +291,23 @@ static void ipmi_poweroff_atca (ipmi_user_t user) | |||
287 | data[2] = 0; /* Power Level */ | 291 | data[2] = 0; /* Power Level */ |
288 | data[3] = 0; /* Don't change saved presets */ | 292 | data[3] = 0; /* Don't change saved presets */ |
289 | send_msg.data = data; | 293 | send_msg.data = data; |
290 | send_msg.data_len = sizeof (data); | 294 | send_msg.data_len = sizeof(data); |
291 | rv = ipmi_request_in_rc_mode(user, | 295 | rv = ipmi_request_in_rc_mode(user, |
292 | (struct ipmi_addr *) &smi_addr, | 296 | (struct ipmi_addr *) &smi_addr, |
293 | &send_msg); | 297 | &send_msg); |
294 | /** At this point, the system may be shutting down, and most | 298 | /* |
295 | ** serial drivers (if used) will have interrupts turned off | 299 | * At this point, the system may be shutting down, and most |
296 | ** it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE | 300 | * serial drivers (if used) will have interrupts turned off |
297 | ** return code | 301 | * it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE |
298 | **/ | 302 | * return code |
299 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | 303 | */ |
304 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | ||
300 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," | 305 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," |
301 | " IPMI error 0x%x\n", rv); | 306 | " IPMI error 0x%x\n", rv); |
302 | goto out; | 307 | goto out; |
303 | } | 308 | } |
304 | 309 | ||
305 | if(atca_oem_poweroff_hook) | 310 | if (atca_oem_poweroff_hook) |
306 | return atca_oem_poweroff_hook(user); | 311 | return atca_oem_poweroff_hook(user); |
307 | out: | 312 | out: |
308 | return; | 313 | return; |
@@ -324,13 +329,13 @@ static void ipmi_poweroff_atca (ipmi_user_t user) | |||
324 | #define IPMI_CPI1_PRODUCT_ID 0x000157 | 329 | #define IPMI_CPI1_PRODUCT_ID 0x000157 |
325 | #define IPMI_CPI1_MANUFACTURER_ID 0x0108 | 330 | #define IPMI_CPI1_MANUFACTURER_ID 0x0108 |
326 | 331 | ||
327 | static int ipmi_cpi1_detect (ipmi_user_t user) | 332 | static int ipmi_cpi1_detect(ipmi_user_t user) |
328 | { | 333 | { |
329 | return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID) | 334 | return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID) |
330 | && (prod_id == IPMI_CPI1_PRODUCT_ID)); | 335 | && (prod_id == IPMI_CPI1_PRODUCT_ID)); |
331 | } | 336 | } |
332 | 337 | ||
333 | static void ipmi_poweroff_cpi1 (ipmi_user_t user) | 338 | static void ipmi_poweroff_cpi1(ipmi_user_t user) |
334 | { | 339 | { |
335 | struct ipmi_system_interface_addr smi_addr; | 340 | struct ipmi_system_interface_addr smi_addr; |
336 | struct ipmi_ipmb_addr ipmb_addr; | 341 | struct ipmi_ipmb_addr ipmb_addr; |
@@ -342,12 +347,12 @@ static void ipmi_poweroff_cpi1 (ipmi_user_t user) | |||
342 | unsigned char aer_addr; | 347 | unsigned char aer_addr; |
343 | unsigned char aer_lun; | 348 | unsigned char aer_lun; |
344 | 349 | ||
345 | /* | 350 | /* |
346 | * Configure IPMI address for local access | 351 | * Configure IPMI address for local access |
347 | */ | 352 | */ |
348 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 353 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
349 | smi_addr.channel = IPMI_BMC_CHANNEL; | 354 | smi_addr.channel = IPMI_BMC_CHANNEL; |
350 | smi_addr.lun = 0; | 355 | smi_addr.lun = 0; |
351 | 356 | ||
352 | printk(KERN_INFO PFX "Powering down via CPI1 power command\n"); | 357 | printk(KERN_INFO PFX "Powering down via CPI1 power command\n"); |
353 | 358 | ||
@@ -439,7 +444,7 @@ static void ipmi_poweroff_cpi1 (ipmi_user_t user) | |||
439 | */ | 444 | */ |
440 | 445 | ||
441 | #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00} | 446 | #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00} |
442 | static int ipmi_dell_chassis_detect (ipmi_user_t user) | 447 | static int ipmi_dell_chassis_detect(ipmi_user_t user) |
443 | { | 448 | { |
444 | const char ipmi_version_major = ipmi_version & 0xF; | 449 | const char ipmi_version_major = ipmi_version & 0xF; |
445 | const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; | 450 | const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; |
@@ -458,25 +463,25 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user) | |||
458 | #define IPMI_NETFN_CHASSIS_REQUEST 0 | 463 | #define IPMI_NETFN_CHASSIS_REQUEST 0 |
459 | #define IPMI_CHASSIS_CONTROL_CMD 0x02 | 464 | #define IPMI_CHASSIS_CONTROL_CMD 0x02 |
460 | 465 | ||
461 | static int ipmi_chassis_detect (ipmi_user_t user) | 466 | static int ipmi_chassis_detect(ipmi_user_t user) |
462 | { | 467 | { |
463 | /* Chassis support, use it. */ | 468 | /* Chassis support, use it. */ |
464 | return (capabilities & 0x80); | 469 | return (capabilities & 0x80); |
465 | } | 470 | } |
466 | 471 | ||
467 | static void ipmi_poweroff_chassis (ipmi_user_t user) | 472 | static void ipmi_poweroff_chassis(ipmi_user_t user) |
468 | { | 473 | { |
469 | struct ipmi_system_interface_addr smi_addr; | 474 | struct ipmi_system_interface_addr smi_addr; |
470 | struct kernel_ipmi_msg send_msg; | 475 | struct kernel_ipmi_msg send_msg; |
471 | int rv; | 476 | int rv; |
472 | unsigned char data[1]; | 477 | unsigned char data[1]; |
473 | 478 | ||
474 | /* | 479 | /* |
475 | * Configure IPMI address for local access | 480 | * Configure IPMI address for local access |
476 | */ | 481 | */ |
477 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 482 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
478 | smi_addr.channel = IPMI_BMC_CHANNEL; | 483 | smi_addr.channel = IPMI_BMC_CHANNEL; |
479 | smi_addr.lun = 0; | 484 | smi_addr.lun = 0; |
480 | 485 | ||
481 | powercyclefailed: | 486 | powercyclefailed: |
482 | printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n", | 487 | printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n", |
@@ -539,7 +544,7 @@ static struct poweroff_function poweroff_functions[] = { | |||
539 | 544 | ||
540 | 545 | ||
541 | /* Called on a powerdown request. */ | 546 | /* Called on a powerdown request. */ |
542 | static void ipmi_poweroff_function (void) | 547 | static void ipmi_poweroff_function(void) |
543 | { | 548 | { |
544 | if (!ready) | 549 | if (!ready) |
545 | return; | 550 | return; |
@@ -573,13 +578,13 @@ static void ipmi_po_new_smi(int if_num, struct device *device) | |||
573 | 578 | ||
574 | ipmi_ifnum = if_num; | 579 | ipmi_ifnum = if_num; |
575 | 580 | ||
576 | /* | 581 | /* |
577 | * Do a get device ide and store some results, since this is | 582 | * Do a get device ide and store some results, since this is |
578 | * used by several functions. | 583 | * used by several functions. |
579 | */ | 584 | */ |
580 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 585 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
581 | smi_addr.channel = IPMI_BMC_CHANNEL; | 586 | smi_addr.channel = IPMI_BMC_CHANNEL; |
582 | smi_addr.lun = 0; | 587 | smi_addr.lun = 0; |
583 | 588 | ||
584 | send_msg.netfn = IPMI_NETFN_APP_REQUEST; | 589 | send_msg.netfn = IPMI_NETFN_APP_REQUEST; |
585 | send_msg.cmd = IPMI_GET_DEVICE_ID_CMD; | 590 | send_msg.cmd = IPMI_GET_DEVICE_ID_CMD; |
@@ -644,8 +649,7 @@ static void ipmi_po_smi_gone(int if_num) | |||
644 | pm_power_off = old_poweroff_func; | 649 | pm_power_off = old_poweroff_func; |
645 | } | 650 | } |
646 | 651 | ||
647 | static struct ipmi_smi_watcher smi_watcher = | 652 | static struct ipmi_smi_watcher smi_watcher = { |
648 | { | ||
649 | .owner = THIS_MODULE, | 653 | .owner = THIS_MODULE, |
650 | .new_smi = ipmi_po_new_smi, | 654 | .new_smi = ipmi_po_new_smi, |
651 | .smi_gone = ipmi_po_smi_gone | 655 | .smi_gone = ipmi_po_smi_gone |
@@ -687,12 +691,12 @@ static struct ctl_table_header *ipmi_table_header; | |||
687 | /* | 691 | /* |
688 | * Startup and shutdown functions. | 692 | * Startup and shutdown functions. |
689 | */ | 693 | */ |
690 | static int ipmi_poweroff_init (void) | 694 | static int ipmi_poweroff_init(void) |
691 | { | 695 | { |
692 | int rv; | 696 | int rv; |
693 | 697 | ||
694 | printk (KERN_INFO "Copyright (C) 2004 MontaVista Software -" | 698 | printk(KERN_INFO "Copyright (C) 2004 MontaVista Software -" |
695 | " IPMI Powerdown via sys_reboot.\n"); | 699 | " IPMI Powerdown via sys_reboot.\n"); |
696 | 700 | ||
697 | if (poweroff_powercycle) | 701 | if (poweroff_powercycle) |
698 | printk(KERN_INFO PFX "Power cycle is enabled.\n"); | 702 | printk(KERN_INFO PFX "Power cycle is enabled.\n"); |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 8f45ca9235ad..1b9a87047817 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -54,13 +54,15 @@ | |||
54 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
55 | 55 | ||
56 | #ifdef CONFIG_X86 | 56 | #ifdef CONFIG_X86 |
57 | /* This is ugly, but I've determined that x86 is the only architecture | 57 | /* |
58 | that can reasonably support the IPMI NMI watchdog timeout at this | 58 | * This is ugly, but I've determined that x86 is the only architecture |
59 | time. If another architecture adds this capability somehow, it | 59 | * that can reasonably support the IPMI NMI watchdog timeout at this |
60 | will have to be a somewhat different mechanism and I have no idea | 60 | * time. If another architecture adds this capability somehow, it |
61 | how it will work. So in the unlikely event that another | 61 | * will have to be a somewhat different mechanism and I have no idea |
62 | architecture supports this, we can figure out a good generic | 62 | * how it will work. So in the unlikely event that another |
63 | mechanism for it at that time. */ | 63 | * architecture supports this, we can figure out a good generic |
64 | * mechanism for it at that time. | ||
65 | */ | ||
64 | #include <asm/kdebug.h> | 66 | #include <asm/kdebug.h> |
65 | #define HAVE_DIE_NMI | 67 | #define HAVE_DIE_NMI |
66 | #endif | 68 | #endif |
@@ -95,9 +97,8 @@ | |||
95 | /* Operations that can be performed on a pretimout. */ | 97 | /* Operations that can be performed on a pretimout. */ |
96 | #define WDOG_PREOP_NONE 0 | 98 | #define WDOG_PREOP_NONE 0 |
97 | #define WDOG_PREOP_PANIC 1 | 99 | #define WDOG_PREOP_PANIC 1 |
98 | #define WDOG_PREOP_GIVE_DATA 2 /* Cause data to be available to | 100 | /* Cause data to be available to read. Doesn't work in NMI mode. */ |
99 | read. Doesn't work in NMI | 101 | #define WDOG_PREOP_GIVE_DATA 2 |
100 | mode. */ | ||
101 | 102 | ||
102 | /* Actions to perform on a full timeout. */ | 103 | /* Actions to perform on a full timeout. */ |
103 | #define WDOG_SET_TIMEOUT_ACT(byte, use) \ | 104 | #define WDOG_SET_TIMEOUT_ACT(byte, use) \ |
@@ -108,8 +109,10 @@ | |||
108 | #define WDOG_TIMEOUT_POWER_DOWN 2 | 109 | #define WDOG_TIMEOUT_POWER_DOWN 2 |
109 | #define WDOG_TIMEOUT_POWER_CYCLE 3 | 110 | #define WDOG_TIMEOUT_POWER_CYCLE 3 |
110 | 111 | ||
111 | /* Byte 3 of the get command, byte 4 of the get response is the | 112 | /* |
112 | pre-timeout in seconds. */ | 113 | * Byte 3 of the get command, byte 4 of the get response is the |
114 | * pre-timeout in seconds. | ||
115 | */ | ||
113 | 116 | ||
114 | /* Bits for setting byte 4 of the set command, byte 5 of the get response. */ | 117 | /* Bits for setting byte 4 of the set command, byte 5 of the get response. */ |
115 | #define WDOG_EXPIRE_CLEAR_BIOS_FRB2 (1 << 1) | 118 | #define WDOG_EXPIRE_CLEAR_BIOS_FRB2 (1 << 1) |
@@ -118,11 +121,13 @@ | |||
118 | #define WDOG_EXPIRE_CLEAR_SMS_OS (1 << 4) | 121 | #define WDOG_EXPIRE_CLEAR_SMS_OS (1 << 4) |
119 | #define WDOG_EXPIRE_CLEAR_OEM (1 << 5) | 122 | #define WDOG_EXPIRE_CLEAR_OEM (1 << 5) |
120 | 123 | ||
121 | /* Setting/getting the watchdog timer value. This is for bytes 5 and | 124 | /* |
122 | 6 (the timeout time) of the set command, and bytes 6 and 7 (the | 125 | * Setting/getting the watchdog timer value. This is for bytes 5 and |
123 | timeout time) and 8 and 9 (the current countdown value) of the | 126 | * 6 (the timeout time) of the set command, and bytes 6 and 7 (the |
124 | response. The timeout value is given in seconds (in the command it | 127 | * timeout time) and 8 and 9 (the current countdown value) of the |
125 | is 100ms intervals). */ | 128 | * response. The timeout value is given in seconds (in the command it |
129 | * is 100ms intervals). | ||
130 | */ | ||
126 | #define WDOG_SET_TIMEOUT(byte1, byte2, val) \ | 131 | #define WDOG_SET_TIMEOUT(byte1, byte2, val) \ |
127 | (byte1) = (((val) * 10) & 0xff), (byte2) = (((val) * 10) >> 8) | 132 | (byte1) = (((val) * 10) & 0xff), (byte2) = (((val) * 10) >> 8) |
128 | #define WDOG_GET_TIMEOUT(byte1, byte2) \ | 133 | #define WDOG_GET_TIMEOUT(byte1, byte2) \ |
@@ -184,8 +189,10 @@ static int ipmi_set_timeout(int do_heartbeat); | |||
184 | static void ipmi_register_watchdog(int ipmi_intf); | 189 | static void ipmi_register_watchdog(int ipmi_intf); |
185 | static void ipmi_unregister_watchdog(int ipmi_intf); | 190 | static void ipmi_unregister_watchdog(int ipmi_intf); |
186 | 191 | ||
187 | /* If true, the driver will start running as soon as it is configured | 192 | /* |
188 | and ready. */ | 193 | * If true, the driver will start running as soon as it is configured |
194 | * and ready. | ||
195 | */ | ||
189 | static int start_now; | 196 | static int start_now; |
190 | 197 | ||
191 | static int set_param_int(const char *val, struct kernel_param *kp) | 198 | static int set_param_int(const char *val, struct kernel_param *kp) |
@@ -309,10 +316,12 @@ static int ipmi_ignore_heartbeat; | |||
309 | /* Is someone using the watchdog? Only one user is allowed. */ | 316 | /* Is someone using the watchdog? Only one user is allowed. */ |
310 | static unsigned long ipmi_wdog_open; | 317 | static unsigned long ipmi_wdog_open; |
311 | 318 | ||
312 | /* If set to 1, the heartbeat command will set the state to reset and | 319 | /* |
313 | start the timer. The timer doesn't normally run when the driver is | 320 | * If set to 1, the heartbeat command will set the state to reset and |
314 | first opened until the heartbeat is set the first time, this | 321 | * start the timer. The timer doesn't normally run when the driver is |
315 | variable is used to accomplish this. */ | 322 | * first opened until the heartbeat is set the first time, this |
323 | * variable is used to accomplish this. | ||
324 | */ | ||
316 | static int ipmi_start_timer_on_heartbeat; | 325 | static int ipmi_start_timer_on_heartbeat; |
317 | 326 | ||
318 | /* IPMI version of the BMC. */ | 327 | /* IPMI version of the BMC. */ |
@@ -329,10 +338,12 @@ static int nmi_handler_registered; | |||
329 | 338 | ||
330 | static int ipmi_heartbeat(void); | 339 | static int ipmi_heartbeat(void); |
331 | 340 | ||
332 | /* We use a mutex to make sure that only one thing can send a set | 341 | /* |
333 | timeout at one time, because we only have one copy of the data. | 342 | * We use a mutex to make sure that only one thing can send a set |
334 | The mutex is claimed when the set_timeout is sent and freed | 343 | * timeout at one time, because we only have one copy of the data. |
335 | when both messages are free. */ | 344 | * The mutex is claimed when the set_timeout is sent and freed |
345 | * when both messages are free. | ||
346 | */ | ||
336 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); | 347 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); |
337 | static DEFINE_MUTEX(set_timeout_lock); | 348 | static DEFINE_MUTEX(set_timeout_lock); |
338 | static DECLARE_COMPLETION(set_timeout_wait); | 349 | static DECLARE_COMPLETION(set_timeout_wait); |
@@ -346,15 +357,13 @@ static void set_timeout_free_recv(struct ipmi_recv_msg *msg) | |||
346 | if (atomic_dec_and_test(&set_timeout_tofree)) | 357 | if (atomic_dec_and_test(&set_timeout_tofree)) |
347 | complete(&set_timeout_wait); | 358 | complete(&set_timeout_wait); |
348 | } | 359 | } |
349 | static struct ipmi_smi_msg set_timeout_smi_msg = | 360 | static struct ipmi_smi_msg set_timeout_smi_msg = { |
350 | { | ||
351 | .done = set_timeout_free_smi | 361 | .done = set_timeout_free_smi |
352 | }; | 362 | }; |
353 | static struct ipmi_recv_msg set_timeout_recv_msg = | 363 | static struct ipmi_recv_msg set_timeout_recv_msg = { |
354 | { | ||
355 | .done = set_timeout_free_recv | 364 | .done = set_timeout_free_recv |
356 | }; | 365 | }; |
357 | 366 | ||
358 | static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | 367 | static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, |
359 | struct ipmi_recv_msg *recv_msg, | 368 | struct ipmi_recv_msg *recv_msg, |
360 | int *send_heartbeat_now) | 369 | int *send_heartbeat_now) |
@@ -373,13 +382,14 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | |||
373 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); | 382 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); |
374 | 383 | ||
375 | if ((ipmi_version_major > 1) | 384 | if ((ipmi_version_major > 1) |
376 | || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) | 385 | || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { |
377 | { | ||
378 | /* This is an IPMI 1.5-only feature. */ | 386 | /* This is an IPMI 1.5-only feature. */ |
379 | data[0] |= WDOG_DONT_STOP_ON_SET; | 387 | data[0] |= WDOG_DONT_STOP_ON_SET; |
380 | } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { | 388 | } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { |
381 | /* In ipmi 1.0, setting the timer stops the watchdog, we | 389 | /* |
382 | need to start it back up again. */ | 390 | * In ipmi 1.0, setting the timer stops the watchdog, we |
391 | * need to start it back up again. | ||
392 | */ | ||
383 | hbnow = 1; | 393 | hbnow = 1; |
384 | } | 394 | } |
385 | 395 | ||
@@ -465,12 +475,10 @@ static void panic_recv_free(struct ipmi_recv_msg *msg) | |||
465 | atomic_dec(&panic_done_count); | 475 | atomic_dec(&panic_done_count); |
466 | } | 476 | } |
467 | 477 | ||
468 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = | 478 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = { |
469 | { | ||
470 | .done = panic_smi_free | 479 | .done = panic_smi_free |
471 | }; | 480 | }; |
472 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = | 481 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = { |
473 | { | ||
474 | .done = panic_recv_free | 482 | .done = panic_recv_free |
475 | }; | 483 | }; |
476 | 484 | ||
@@ -480,8 +488,10 @@ static void panic_halt_ipmi_heartbeat(void) | |||
480 | struct ipmi_system_interface_addr addr; | 488 | struct ipmi_system_interface_addr addr; |
481 | int rv; | 489 | int rv; |
482 | 490 | ||
483 | /* Don't reset the timer if we have the timer turned off, that | 491 | /* |
484 | re-enables the watchdog. */ | 492 | * Don't reset the timer if we have the timer turned off, that |
493 | * re-enables the watchdog. | ||
494 | */ | ||
485 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 495 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
486 | return; | 496 | return; |
487 | 497 | ||
@@ -505,19 +515,19 @@ static void panic_halt_ipmi_heartbeat(void) | |||
505 | atomic_add(2, &panic_done_count); | 515 | atomic_add(2, &panic_done_count); |
506 | } | 516 | } |
507 | 517 | ||
508 | static struct ipmi_smi_msg panic_halt_smi_msg = | 518 | static struct ipmi_smi_msg panic_halt_smi_msg = { |
509 | { | ||
510 | .done = panic_smi_free | 519 | .done = panic_smi_free |
511 | }; | 520 | }; |
512 | static struct ipmi_recv_msg panic_halt_recv_msg = | 521 | static struct ipmi_recv_msg panic_halt_recv_msg = { |
513 | { | ||
514 | .done = panic_recv_free | 522 | .done = panic_recv_free |
515 | }; | 523 | }; |
516 | 524 | ||
517 | /* Special call, doesn't claim any locks. This is only to be called | 525 | /* |
518 | at panic or halt time, in run-to-completion mode, when the caller | 526 | * Special call, doesn't claim any locks. This is only to be called |
519 | is the only CPU and the only thing that will be going is these IPMI | 527 | * at panic or halt time, in run-to-completion mode, when the caller |
520 | calls. */ | 528 | * is the only CPU and the only thing that will be going is these IPMI |
529 | * calls. | ||
530 | */ | ||
521 | static void panic_halt_ipmi_set_timeout(void) | 531 | static void panic_halt_ipmi_set_timeout(void) |
522 | { | 532 | { |
523 | int send_heartbeat_now; | 533 | int send_heartbeat_now; |
@@ -540,10 +550,12 @@ static void panic_halt_ipmi_set_timeout(void) | |||
540 | ipmi_poll_interface(watchdog_user); | 550 | ipmi_poll_interface(watchdog_user); |
541 | } | 551 | } |
542 | 552 | ||
543 | /* We use a semaphore to make sure that only one thing can send a | 553 | /* |
544 | heartbeat at one time, because we only have one copy of the data. | 554 | * We use a mutex to make sure that only one thing can send a |
545 | The semaphore is claimed when the set_timeout is sent and freed | 555 | * heartbeat at one time, because we only have one copy of the data. |
546 | when both messages are free. */ | 556 | * The semaphore is claimed when the set_timeout is sent and freed |
557 | * when both messages are free. | ||
558 | */ | ||
547 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); | 559 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); |
548 | static DEFINE_MUTEX(heartbeat_lock); | 560 | static DEFINE_MUTEX(heartbeat_lock); |
549 | static DECLARE_COMPLETION(heartbeat_wait); | 561 | static DECLARE_COMPLETION(heartbeat_wait); |
@@ -557,15 +569,13 @@ static void heartbeat_free_recv(struct ipmi_recv_msg *msg) | |||
557 | if (atomic_dec_and_test(&heartbeat_tofree)) | 569 | if (atomic_dec_and_test(&heartbeat_tofree)) |
558 | complete(&heartbeat_wait); | 570 | complete(&heartbeat_wait); |
559 | } | 571 | } |
560 | static struct ipmi_smi_msg heartbeat_smi_msg = | 572 | static struct ipmi_smi_msg heartbeat_smi_msg = { |
561 | { | ||
562 | .done = heartbeat_free_smi | 573 | .done = heartbeat_free_smi |
563 | }; | 574 | }; |
564 | static struct ipmi_recv_msg heartbeat_recv_msg = | 575 | static struct ipmi_recv_msg heartbeat_recv_msg = { |
565 | { | ||
566 | .done = heartbeat_free_recv | 576 | .done = heartbeat_free_recv |
567 | }; | 577 | }; |
568 | 578 | ||
569 | static int ipmi_heartbeat(void) | 579 | static int ipmi_heartbeat(void) |
570 | { | 580 | { |
571 | struct kernel_ipmi_msg msg; | 581 | struct kernel_ipmi_msg msg; |
@@ -580,10 +590,12 @@ static int ipmi_heartbeat(void) | |||
580 | ipmi_watchdog_state = action_val; | 590 | ipmi_watchdog_state = action_val; |
581 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 591 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
582 | } else if (pretimeout_since_last_heartbeat) { | 592 | } else if (pretimeout_since_last_heartbeat) { |
583 | /* A pretimeout occurred, make sure we set the timeout. | 593 | /* |
584 | We don't want to set the action, though, we want to | 594 | * A pretimeout occurred, make sure we set the timeout. |
585 | leave that alone (thus it can't be combined with the | 595 | * We don't want to set the action, though, we want to |
586 | above operation. */ | 596 | * leave that alone (thus it can't be combined with the |
597 | * above operation. | ||
598 | */ | ||
587 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 599 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
588 | } | 600 | } |
589 | 601 | ||
@@ -591,8 +603,10 @@ static int ipmi_heartbeat(void) | |||
591 | 603 | ||
592 | atomic_set(&heartbeat_tofree, 2); | 604 | atomic_set(&heartbeat_tofree, 2); |
593 | 605 | ||
594 | /* Don't reset the timer if we have the timer turned off, that | 606 | /* |
595 | re-enables the watchdog. */ | 607 | * Don't reset the timer if we have the timer turned off, that |
608 | * re-enables the watchdog. | ||
609 | */ | ||
596 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { | 610 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { |
597 | mutex_unlock(&heartbeat_lock); | 611 | mutex_unlock(&heartbeat_lock); |
598 | return 0; | 612 | return 0; |
@@ -625,10 +639,12 @@ static int ipmi_heartbeat(void) | |||
625 | wait_for_completion(&heartbeat_wait); | 639 | wait_for_completion(&heartbeat_wait); |
626 | 640 | ||
627 | if (heartbeat_recv_msg.msg.data[0] != 0) { | 641 | if (heartbeat_recv_msg.msg.data[0] != 0) { |
628 | /* Got an error in the heartbeat response. It was already | 642 | /* |
629 | reported in ipmi_wdog_msg_handler, but we should return | 643 | * Got an error in the heartbeat response. It was already |
630 | an error here. */ | 644 | * reported in ipmi_wdog_msg_handler, but we should return |
631 | rv = -EINVAL; | 645 | * an error here. |
646 | */ | ||
647 | rv = -EINVAL; | ||
632 | } | 648 | } |
633 | 649 | ||
634 | mutex_unlock(&heartbeat_lock); | 650 | mutex_unlock(&heartbeat_lock); |
@@ -636,8 +652,7 @@ static int ipmi_heartbeat(void) | |||
636 | return rv; | 652 | return rv; |
637 | } | 653 | } |
638 | 654 | ||
639 | static struct watchdog_info ident = | 655 | static struct watchdog_info ident = { |
640 | { | ||
641 | .options = 0, /* WDIOF_SETTIMEOUT, */ | 656 | .options = 0, /* WDIOF_SETTIMEOUT, */ |
642 | .firmware_version = 1, | 657 | .firmware_version = 1, |
643 | .identity = "IPMI" | 658 | .identity = "IPMI" |
@@ -650,7 +665,7 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, | |||
650 | int i; | 665 | int i; |
651 | int val; | 666 | int val; |
652 | 667 | ||
653 | switch(cmd) { | 668 | switch (cmd) { |
654 | case WDIOC_GETSUPPORT: | 669 | case WDIOC_GETSUPPORT: |
655 | i = copy_to_user(argp, &ident, sizeof(ident)); | 670 | i = copy_to_user(argp, &ident, sizeof(ident)); |
656 | return i ? -EFAULT : 0; | 671 | return i ? -EFAULT : 0; |
@@ -690,15 +705,13 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, | |||
690 | i = copy_from_user(&val, argp, sizeof(int)); | 705 | i = copy_from_user(&val, argp, sizeof(int)); |
691 | if (i) | 706 | if (i) |
692 | return -EFAULT; | 707 | return -EFAULT; |
693 | if (val & WDIOS_DISABLECARD) | 708 | if (val & WDIOS_DISABLECARD) { |
694 | { | ||
695 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 709 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
696 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | 710 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); |
697 | ipmi_start_timer_on_heartbeat = 0; | 711 | ipmi_start_timer_on_heartbeat = 0; |
698 | } | 712 | } |
699 | 713 | ||
700 | if (val & WDIOS_ENABLECARD) | 714 | if (val & WDIOS_ENABLECARD) { |
701 | { | ||
702 | ipmi_watchdog_state = action_val; | 715 | ipmi_watchdog_state = action_val; |
703 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 716 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
704 | } | 717 | } |
@@ -724,13 +737,13 @@ static ssize_t ipmi_write(struct file *file, | |||
724 | int rv; | 737 | int rv; |
725 | 738 | ||
726 | if (len) { | 739 | if (len) { |
727 | if (!nowayout) { | 740 | if (!nowayout) { |
728 | size_t i; | 741 | size_t i; |
729 | 742 | ||
730 | /* In case it was set long ago */ | 743 | /* In case it was set long ago */ |
731 | expect_close = 0; | 744 | expect_close = 0; |
732 | 745 | ||
733 | for (i = 0; i != len; i++) { | 746 | for (i = 0; i != len; i++) { |
734 | char c; | 747 | char c; |
735 | 748 | ||
736 | if (get_user(c, buf + i)) | 749 | if (get_user(c, buf + i)) |
@@ -758,15 +771,17 @@ static ssize_t ipmi_read(struct file *file, | |||
758 | if (count <= 0) | 771 | if (count <= 0) |
759 | return 0; | 772 | return 0; |
760 | 773 | ||
761 | /* Reading returns if the pretimeout has gone off, and it only does | 774 | /* |
762 | it once per pretimeout. */ | 775 | * Reading returns if the pretimeout has gone off, and it only does |
776 | * it once per pretimeout. | ||
777 | */ | ||
763 | spin_lock(&ipmi_read_lock); | 778 | spin_lock(&ipmi_read_lock); |
764 | if (!data_to_read) { | 779 | if (!data_to_read) { |
765 | if (file->f_flags & O_NONBLOCK) { | 780 | if (file->f_flags & O_NONBLOCK) { |
766 | rv = -EAGAIN; | 781 | rv = -EAGAIN; |
767 | goto out; | 782 | goto out; |
768 | } | 783 | } |
769 | 784 | ||
770 | init_waitqueue_entry(&wait, current); | 785 | init_waitqueue_entry(&wait, current); |
771 | add_wait_queue(&read_q, &wait); | 786 | add_wait_queue(&read_q, &wait); |
772 | while (!data_to_read) { | 787 | while (!data_to_read) { |
@@ -776,7 +791,7 @@ static ssize_t ipmi_read(struct file *file, | |||
776 | spin_lock(&ipmi_read_lock); | 791 | spin_lock(&ipmi_read_lock); |
777 | } | 792 | } |
778 | remove_wait_queue(&read_q, &wait); | 793 | remove_wait_queue(&read_q, &wait); |
779 | 794 | ||
780 | if (signal_pending(current)) { | 795 | if (signal_pending(current)) { |
781 | rv = -ERESTARTSYS; | 796 | rv = -ERESTARTSYS; |
782 | goto out; | 797 | goto out; |
@@ -799,25 +814,27 @@ static ssize_t ipmi_read(struct file *file, | |||
799 | 814 | ||
800 | static int ipmi_open(struct inode *ino, struct file *filep) | 815 | static int ipmi_open(struct inode *ino, struct file *filep) |
801 | { | 816 | { |
802 | switch (iminor(ino)) { | 817 | switch (iminor(ino)) { |
803 | case WATCHDOG_MINOR: | 818 | case WATCHDOG_MINOR: |
804 | if (test_and_set_bit(0, &ipmi_wdog_open)) | 819 | if (test_and_set_bit(0, &ipmi_wdog_open)) |
805 | return -EBUSY; | 820 | return -EBUSY; |
806 | 821 | ||
807 | /* Don't start the timer now, let it start on the | 822 | /* |
808 | first heartbeat. */ | 823 | * Don't start the timer now, let it start on the |
824 | * first heartbeat. | ||
825 | */ | ||
809 | ipmi_start_timer_on_heartbeat = 1; | 826 | ipmi_start_timer_on_heartbeat = 1; |
810 | return nonseekable_open(ino, filep); | 827 | return nonseekable_open(ino, filep); |
811 | 828 | ||
812 | default: | 829 | default: |
813 | return (-ENODEV); | 830 | return (-ENODEV); |
814 | } | 831 | } |
815 | } | 832 | } |
816 | 833 | ||
817 | static unsigned int ipmi_poll(struct file *file, poll_table *wait) | 834 | static unsigned int ipmi_poll(struct file *file, poll_table *wait) |
818 | { | 835 | { |
819 | unsigned int mask = 0; | 836 | unsigned int mask = 0; |
820 | 837 | ||
821 | poll_wait(file, &read_q, wait); | 838 | poll_wait(file, &read_q, wait); |
822 | 839 | ||
823 | spin_lock(&ipmi_read_lock); | 840 | spin_lock(&ipmi_read_lock); |
@@ -851,7 +868,7 @@ static int ipmi_close(struct inode *ino, struct file *filep) | |||
851 | clear_bit(0, &ipmi_wdog_open); | 868 | clear_bit(0, &ipmi_wdog_open); |
852 | } | 869 | } |
853 | 870 | ||
854 | ipmi_fasync (-1, filep, 0); | 871 | ipmi_fasync(-1, filep, 0); |
855 | expect_close = 0; | 872 | expect_close = 0; |
856 | 873 | ||
857 | return 0; | 874 | return 0; |
@@ -882,7 +899,7 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, | |||
882 | msg->msg.data[0], | 899 | msg->msg.data[0], |
883 | msg->msg.cmd); | 900 | msg->msg.cmd); |
884 | } | 901 | } |
885 | 902 | ||
886 | ipmi_free_recv_msg(msg); | 903 | ipmi_free_recv_msg(msg); |
887 | } | 904 | } |
888 | 905 | ||
@@ -902,14 +919,14 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data) | |||
902 | } | 919 | } |
903 | } | 920 | } |
904 | 921 | ||
905 | /* On some machines, the heartbeat will give | 922 | /* |
906 | an error and not work unless we re-enable | 923 | * On some machines, the heartbeat will give an error and not |
907 | the timer. So do so. */ | 924 | * work unless we re-enable the timer. So do so. |
925 | */ | ||
908 | pretimeout_since_last_heartbeat = 1; | 926 | pretimeout_since_last_heartbeat = 1; |
909 | } | 927 | } |
910 | 928 | ||
911 | static struct ipmi_user_hndl ipmi_hndlrs = | 929 | static struct ipmi_user_hndl ipmi_hndlrs = { |
912 | { | ||
913 | .ipmi_recv_hndl = ipmi_wdog_msg_handler, | 930 | .ipmi_recv_hndl = ipmi_wdog_msg_handler, |
914 | .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler | 931 | .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler |
915 | }; | 932 | }; |
@@ -949,8 +966,10 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
949 | int old_timeout = timeout; | 966 | int old_timeout = timeout; |
950 | int old_preop_val = preop_val; | 967 | int old_preop_val = preop_val; |
951 | 968 | ||
952 | /* Set the pretimeout to go off in a second and give | 969 | /* |
953 | ourselves plenty of time to stop the timer. */ | 970 | * Set the pretimeout to go off in a second and give |
971 | * ourselves plenty of time to stop the timer. | ||
972 | */ | ||
954 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | 973 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; |
955 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ | 974 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ |
956 | pretimeout = 99; | 975 | pretimeout = 99; |
@@ -974,7 +993,7 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
974 | " occur. The NMI pretimeout will" | 993 | " occur. The NMI pretimeout will" |
975 | " likely not work\n"); | 994 | " likely not work\n"); |
976 | } | 995 | } |
977 | out_restore: | 996 | out_restore: |
978 | testing_nmi = 0; | 997 | testing_nmi = 0; |
979 | preop_val = old_preop_val; | 998 | preop_val = old_preop_val; |
980 | pretimeout = old_pretimeout; | 999 | pretimeout = old_pretimeout; |
@@ -1009,9 +1028,11 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
1009 | /* Make sure no one can call us any more. */ | 1028 | /* Make sure no one can call us any more. */ |
1010 | misc_deregister(&ipmi_wdog_miscdev); | 1029 | misc_deregister(&ipmi_wdog_miscdev); |
1011 | 1030 | ||
1012 | /* Wait to make sure the message makes it out. The lower layer has | 1031 | /* |
1013 | pointers to our buffers, we want to make sure they are done before | 1032 | * Wait to make sure the message makes it out. The lower layer has |
1014 | we release our memory. */ | 1033 | * pointers to our buffers, we want to make sure they are done before |
1034 | * we release our memory. | ||
1035 | */ | ||
1015 | while (atomic_read(&set_timeout_tofree)) | 1036 | while (atomic_read(&set_timeout_tofree)) |
1016 | schedule_timeout_uninterruptible(1); | 1037 | schedule_timeout_uninterruptible(1); |
1017 | 1038 | ||
@@ -1052,15 +1073,17 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) | |||
1052 | return NOTIFY_STOP; | 1073 | return NOTIFY_STOP; |
1053 | } | 1074 | } |
1054 | 1075 | ||
1055 | /* If we are not expecting a timeout, ignore it. */ | 1076 | /* If we are not expecting a timeout, ignore it. */ |
1056 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1077 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
1057 | return NOTIFY_OK; | 1078 | return NOTIFY_OK; |
1058 | 1079 | ||
1059 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | 1080 | if (preaction_val != WDOG_PRETIMEOUT_NMI) |
1060 | return NOTIFY_OK; | 1081 | return NOTIFY_OK; |
1061 | 1082 | ||
1062 | /* If no one else handled the NMI, we assume it was the IPMI | 1083 | /* |
1063 | watchdog. */ | 1084 | * If no one else handled the NMI, we assume it was the IPMI |
1085 | * watchdog. | ||
1086 | */ | ||
1064 | if (preop_val == WDOG_PREOP_PANIC) { | 1087 | if (preop_val == WDOG_PREOP_PANIC) { |
1065 | /* On some machines, the heartbeat will give | 1088 | /* On some machines, the heartbeat will give |
1066 | an error and not work unless we re-enable | 1089 | an error and not work unless we re-enable |
@@ -1082,7 +1105,7 @@ static int wdog_reboot_handler(struct notifier_block *this, | |||
1082 | unsigned long code, | 1105 | unsigned long code, |
1083 | void *unused) | 1106 | void *unused) |
1084 | { | 1107 | { |
1085 | static int reboot_event_handled = 0; | 1108 | static int reboot_event_handled; |
1086 | 1109 | ||
1087 | if ((watchdog_user) && (!reboot_event_handled)) { | 1110 | if ((watchdog_user) && (!reboot_event_handled)) { |
1088 | /* Make sure we only do this once. */ | 1111 | /* Make sure we only do this once. */ |
@@ -1115,7 +1138,7 @@ static int wdog_panic_handler(struct notifier_block *this, | |||
1115 | unsigned long event, | 1138 | unsigned long event, |
1116 | void *unused) | 1139 | void *unused) |
1117 | { | 1140 | { |
1118 | static int panic_event_handled = 0; | 1141 | static int panic_event_handled; |
1119 | 1142 | ||
1120 | /* On a panic, if we have a panic timeout, make sure to extend | 1143 | /* On a panic, if we have a panic timeout, make sure to extend |
1121 | the watchdog timer to a reasonable value to complete the | 1144 | the watchdog timer to a reasonable value to complete the |
@@ -1125,7 +1148,7 @@ static int wdog_panic_handler(struct notifier_block *this, | |||
1125 | ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { | 1148 | ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { |
1126 | /* Make sure we do this only once. */ | 1149 | /* Make sure we do this only once. */ |
1127 | panic_event_handled = 1; | 1150 | panic_event_handled = 1; |
1128 | 1151 | ||
1129 | timeout = 255; | 1152 | timeout = 255; |
1130 | pretimeout = 0; | 1153 | pretimeout = 0; |
1131 | panic_halt_ipmi_set_timeout(); | 1154 | panic_halt_ipmi_set_timeout(); |
@@ -1151,8 +1174,7 @@ static void ipmi_smi_gone(int if_num) | |||
1151 | ipmi_unregister_watchdog(if_num); | 1174 | ipmi_unregister_watchdog(if_num); |
1152 | } | 1175 | } |
1153 | 1176 | ||
1154 | static struct ipmi_smi_watcher smi_watcher = | 1177 | static struct ipmi_smi_watcher smi_watcher = { |
1155 | { | ||
1156 | .owner = THIS_MODULE, | 1178 | .owner = THIS_MODULE, |
1157 | .new_smi = ipmi_new_smi, | 1179 | .new_smi = ipmi_new_smi, |
1158 | .smi_gone = ipmi_smi_gone | 1180 | .smi_gone = ipmi_smi_gone |