diff options
author | Corey Minyard <cminyard@mvista.com> | 2017-08-19 01:32:03 +0300 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2017-09-28 00:03:45 +0300 |
commit | 1c9f98d1bfbd0696442f97fa7d43a727e1e16568 (patch) | |
tree | d8ec85252acaa934729502d072b832fc6906c815 /drivers/char | |
parent | b72fce52a14bbe0a94259a95032cf9dd1b3dd143 (diff) | |
download | linux-1c9f98d1bfbd0696442f97fa7d43a727e1e16568.tar.xz |
ipmi: Make IPMI panic strings always available
They were set by config items, but people complained that they were
never turned on. So have them always available and enabled by a
module parameter.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/Kconfig | 27 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 91 |
2 files changed, 95 insertions, 23 deletions
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index f6fa056a52fc..152ccefdaecb 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -25,21 +25,28 @@ if IPMI_HANDLER config IPMI_PANIC_EVENT bool 'Generate a panic event to all BMCs on a panic' help - When a panic occurs, this will cause the IPMI message handler to - generate an IPMI event describing the panic to each interface - registered with the message handler. + When a panic occurs, this will cause the IPMI message handler to, + by default, generate an IPMI event describing the panic to each + interface registered with the message handler. This is always + available, the module parameter for ipmi_msghandler named + panic_op can be set to "event" to chose this value, this config + simply causes the default value to be set to "event". config IPMI_PANIC_STRING bool 'Generate OEM events containing the panic string' depends on IPMI_PANIC_EVENT help - When a panic occurs, this will cause the IPMI message handler to - generate IPMI OEM type f0 events holding the IPMB address of the - panic generator (byte 4 of the event), a sequence number for the - string (byte 5 of the event) and part of the string (the rest of the - event). Bytes 1, 2, and 3 are the normal usage for an OEM event. - You can fetch these events and use the sequence numbers to piece the - string together. + When a panic occurs, this will cause the IPMI message handler to, + by default, generate IPMI OEM type f0 events holding the IPMB + address of the panic generator (byte 4 of the event), a sequence + number for the string (byte 5 of the event) and part of the + string (the rest of the event). Bytes 1, 2, and 3 are the normal + usage for an OEM event. You can fetch these events and use the + sequence numbers to piece the string together. This config + parameter sets the default value to generate these events, + the module parameter for ipmi_msghandler named panic_op can + be set to "string" to chose this value, this config simply + causes the default value to be set to "string". config IPMI_DEVICE_INTERFACE tristate 'Device interface for IPMI' diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index c82d9fd2f05a..047ca9fcb29b 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -46,6 +46,7 @@ #include <linux/proc_fs.h> #include <linux/rcupdate.h> #include <linux/interrupt.h> +#include <linux/moduleparam.h> #define PFX "IPMI message handler: " @@ -61,6 +62,74 @@ static int handle_one_recv_msg(ipmi_smi_t intf, static int initialized; +enum ipmi_panic_event_op { + IPMI_SEND_PANIC_EVENT_NONE, + IPMI_SEND_PANIC_EVENT, + IPMI_SEND_PANIC_EVENT_STRING +}; +#ifdef CONFIG_IPMI_PANIC_STRING +#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_STRING +#elif defined(CONFIG_IPMI_PANIC_EVENT) +#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT +#else +#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_NONE +#endif +static enum ipmi_panic_event_op ipmi_send_panic_event = IPMI_PANIC_DEFAULT; + +static int panic_op_write_handler(const char *val, + const struct kernel_param *kp) +{ + char valcp[16]; + char *s; + + strncpy(valcp, val, 16); + valcp[15] = '\0'; + + s = strstrip(valcp); + + if (strcmp(s, "none") == 0) + ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT_NONE; + else if (strcmp(s, "event") == 0) + ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT; + else if (strcmp(s, "string") == 0) + ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT_STRING; + else + return -EINVAL; + + return 0; +} + +static int panic_op_read_handler(char *buffer, const struct kernel_param *kp) +{ + switch (ipmi_send_panic_event) { + case IPMI_SEND_PANIC_EVENT_NONE: + strcpy(buffer, "none"); + break; + + case IPMI_SEND_PANIC_EVENT: + strcpy(buffer, "event"); + break; + + case IPMI_SEND_PANIC_EVENT_STRING: + strcpy(buffer, "string"); + break; + + default: + strcpy(buffer, "???"); + break; + } + + return strlen(buffer); +} + +static const struct kernel_param_ops panic_op_ops = { + .set = panic_op_write_handler, + .get = panic_op_read_handler +}; +module_param_cb(panic_op, &panic_op_ops, NULL, 0600); +MODULE_PARM_DESC(panic_op, "Sets if the IPMI driver will attempt to store panic information in the event log in the event of a panic. Set to 'none' for no, 'event' for a single event, or 'string' for a generic event and the panic string in IPMI OEM events."); + + #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_ipmi_root; #endif /* CONFIG_PROC_FS */ @@ -4271,8 +4340,6 @@ void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) } EXPORT_SYMBOL(ipmi_free_recv_msg); -#ifdef CONFIG_IPMI_PANIC_EVENT - static atomic_t panic_done_count = ATOMIC_INIT(0); static void dummy_smi_done_handler(struct ipmi_smi_msg *msg) @@ -4320,7 +4387,6 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf, ipmi_poll(intf); } -#ifdef CONFIG_IPMI_PANIC_STRING static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg) { if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) @@ -4347,7 +4413,6 @@ static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg) intf->local_event_generator = (msg->msg.data[6] >> 5) & 1; } } -#endif static void send_panic_events(char *str) { @@ -4357,6 +4422,9 @@ static void send_panic_events(char *str) struct ipmi_system_interface_addr *si; struct ipmi_addr addr; + if (ipmi_send_panic_event == IPMI_SEND_PANIC_EVENT_NONE) + return; + si = (struct ipmi_system_interface_addr *) &addr; si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; si->channel = IPMI_BMC_CHANNEL; @@ -4385,20 +4453,19 @@ static void send_panic_events(char *str) /* For every registered interface, send the event. */ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - if (!intf->handlers) - /* Interface is not ready. */ + if (!intf->handlers || !intf->handlers->poll) + /* Interface is not ready or can't run at panic time. */ continue; /* Send the event announcing the panic. */ ipmi_panic_request_and_wait(intf, &addr, &msg); } -#ifdef CONFIG_IPMI_PANIC_STRING /* * On every interface, dump a bunch of OEM event holding the * string. */ - if (!str) + if (ipmi_send_panic_event != IPMI_SEND_PANIC_EVENT_STRING || !str) return; /* For every registered interface, send the event. */ @@ -4507,9 +4574,7 @@ static void send_panic_events(char *str) ipmi_panic_request_and_wait(intf, &addr, &msg); } } -#endif /* CONFIG_IPMI_PANIC_STRING */ } -#endif /* CONFIG_IPMI_PANIC_EVENT */ static int has_panicked; @@ -4547,12 +4612,12 @@ static int panic_event(struct notifier_block *this, spin_unlock(&intf->waiting_rcv_msgs_lock); intf->run_to_completion = 1; - intf->handlers->set_run_to_completion(intf->send_info, 1); + if (intf->handlers->set_run_to_completion) + intf->handlers->set_run_to_completion(intf->send_info, + 1); } -#ifdef CONFIG_IPMI_PANIC_EVENT send_panic_events(ptr); -#endif return NOTIFY_DONE; } |