diff options
author | Corey Minyard <cminyard@mvista.com> | 2017-09-01 00:09:03 +0200 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2017-09-27 23:03:45 +0200 |
commit | c0734bd594d43a28afcbe476bbf0d35a5bbffa4c (patch) | |
tree | fabccdfb7dc1f5416a041b2cf66b8c98a38ad3f5 /drivers/char | |
parent | ipmi: Rework device id and guid handling to catch changing BMCs (diff) | |
download | linux-c0734bd594d43a28afcbe476bbf0d35a5bbffa4c.tar.xz linux-c0734bd594d43a28afcbe476bbf0d35a5bbffa4c.zip |
ipmi: Retry BMC registration on a failure
If the BMC fails to register, just set up to retry periodically.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 1da0b3cca6aa..c6ee1de8d76b 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -47,6 +47,7 @@ #include <linux/rcupdate.h> #include <linux/interrupt.h> #include <linux/moduleparam.h> +#include <linux/workqueue.h> #define PFX "IPMI message handler: " @@ -430,6 +431,7 @@ struct ipmi_smi { struct list_head bmc_link; char *my_dev_name; bool in_bmc_register; /* Handle recursive situations. Yuck. */ + struct work_struct bmc_reg_work; /* * This is the lower-layer's sender routine. Note that you @@ -2275,7 +2277,8 @@ retry_bmc_lock: intf->bmc->id = id; intf->bmc->dyn_guid_set = guid_set; memcpy(intf->bmc->guid, guid, 16); - rv = __ipmi_bmc_register(intf, &id, guid_set, guid, intf_num); + if (__ipmi_bmc_register(intf, &id, guid_set, guid, intf_num)) + need_waiter(intf); /* Retry later on an error. */ if (!intf_set) { /* @@ -3276,6 +3279,16 @@ void ipmi_poll_interface(ipmi_user_t user) } EXPORT_SYMBOL(ipmi_poll_interface); +static void redo_bmc_reg(struct work_struct *work) +{ + ipmi_smi_t intf = container_of(work, struct ipmi_smi, bmc_reg_work); + + if (!intf->in_shutdown) + bmc_get_device_id(intf, NULL, NULL, NULL, NULL); + + kref_put(&intf->refcount, intf_free); +} + int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, void *send_info, struct device *si_dev, @@ -3315,6 +3328,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, mutex_init(&intf->bmc_reg_mutex); intf->intf_num = -1; /* Mark it invalid for now. */ kref_init(&intf->refcount); + INIT_WORK(&intf->bmc_reg_work, redo_bmc_reg); intf->si_dev = si_dev; for (j = 0; j < IPMI_MAX_CHANNELS; j++) { intf->channels[j].address = IPMI_BMC_SLAVE_ADDR; @@ -4641,6 +4655,14 @@ static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, int i; unsigned int waiting_msgs = 0; + if (!intf->bmc_registered) { + kref_get(&intf->refcount); + if (!schedule_work(&intf->bmc_reg_work)) { + kref_put(&intf->refcount, intf_free); + waiting_msgs++; + } + } + /* * Go through the seq table and find any messages that * have timed out, putting them in the timeouts |