Commit 91e2dd0a authored by Corey Minyard's avatar Corey Minyard

ipmi: Add a panic handler for IPMI users

Users of the IPMI code had their own panic handlers, but the
order was not necessarily right, the base IPMI code would
need to handle the panic first, and the user had no way to
know if the IPMI interface could run at panic time.

Add a panic handler to the user interface, it is called if
non-NULL and the interface the user is on is capable of panic
handling.  It also cleans up the panic log handling a bit to
reuse the existing interface loop in the main panic handler.
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent e2384917
......@@ -4956,13 +4956,15 @@ static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
}
}
static void send_panic_events(char *str)
static void send_panic_events(ipmi_smi_t intf, char *str)
{
struct kernel_ipmi_msg msg;
ipmi_smi_t intf;
unsigned char data[16];
struct ipmi_system_interface_addr *si;
struct ipmi_addr addr;
char *p = str;
struct ipmi_ipmb_addr *ipmb;
int j;
if (ipmi_send_panic_event == IPMI_SEND_PANIC_EVENT_NONE)
return;
......@@ -4993,15 +4995,8 @@ static void send_panic_events(char *str)
data[7] = str[2];
}
/* For every registered interface, send the event. */
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
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);
}
/*
* On every interface, dump a bunch of OEM event holding the
......@@ -5010,16 +5005,6 @@ static void send_panic_events(char *str)
if (ipmi_send_panic_event != IPMI_SEND_PANIC_EVENT_STRING || !str)
return;
/* For every registered interface, send the event. */
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
char *p = str;
struct ipmi_ipmb_addr *ipmb;
int j;
if (intf->intf_num == -1)
/* Interface was not ready yet. */
continue;
/*
* intf_num is used as an marker to tell if the
* interface is valid. Thus we need a read barrier to
......@@ -5088,7 +5073,7 @@ static void send_panic_events(char *str)
si->channel = IPMI_BMC_CHANNEL;
si->lun = 0;
} else
continue; /* No where to send the event. */
return; /* No where to send the event. */
msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */
msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
......@@ -5115,7 +5100,6 @@ static void send_panic_events(char *str)
ipmi_panic_request_and_wait(intf, &addr, &msg);
}
}
}
static int has_panicked;
......@@ -5125,6 +5109,7 @@ static int panic_event(struct notifier_block *this,
void *ptr)
{
ipmi_smi_t intf;
ipmi_user_t user;
if (has_panicked)
return NOTIFY_DONE;
......@@ -5132,10 +5117,13 @@ static int panic_event(struct notifier_block *this,
/* For every registered interface, set it to run to completion. */
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
if (!intf->handlers)
if (!intf->handlers || intf->intf_num == -1)
/* Interface is not ready. */
continue;
if (!intf->handlers->poll)
continue;
/*
* If we were interrupted while locking xmit_msgs_lock or
* waiting_rcv_msgs_lock, the corresponding list may be
......@@ -5157,9 +5145,15 @@ static int panic_event(struct notifier_block *this,
if (intf->handlers->set_run_to_completion)
intf->handlers->set_run_to_completion(intf->send_info,
1);
list_for_each_entry_rcu(user, &intf->users, link) {
if (user->handler->ipmi_panic_handler)
user->handler->ipmi_panic_handler(
user->handler_data);
}
send_panic_events(ptr);
send_panic_events(intf, ptr);
}
return NOTIFY_DONE;
}
......
......@@ -77,6 +77,12 @@ struct ipmi_user_hndl {
/* Called when the interface detects a watchdog pre-timeout. If
this is NULL, it will be ignored for the user. */
void (*ipmi_watchdog_pretimeout)(void *handler_data);
/*
* If not NULL, called at panic time after the interface has
* been set up to handle run to completion.
*/
void (*ipmi_panic_handler)(void *handler_data);
};
/* Create a new user of the IPMI layer on the given interface number. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment