Commit a2cb600f authored by Corey Minyard's avatar Corey Minyard

ipmi: Rework BMC registration

There was a certain error case where the BMC wouldn't be deregistered
like it should be.  Rework the BMC registration to make calling
ipmi_bmc_unregister() ok even if it's not registered and to clean up
the error handling for ipmi_bmc_register().
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent 7e030d6d
...@@ -404,6 +404,7 @@ struct ipmi_smi { ...@@ -404,6 +404,7 @@ struct ipmi_smi {
wait_queue_head_t waitq; wait_queue_head_t waitq;
struct bmc_device *bmc; struct bmc_device *bmc;
bool bmc_registered;
char *my_dev_name; char *my_dev_name;
/* /*
...@@ -2524,17 +2525,18 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) ...@@ -2524,17 +2525,18 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
{ {
struct bmc_device *bmc = intf->bmc; struct bmc_device *bmc = intf->bmc;
if (!intf->bmc_registered)
return;
sysfs_remove_link(&intf->si_dev->kobj, "bmc"); sysfs_remove_link(&intf->si_dev->kobj, "bmc");
if (intf->my_dev_name) { sysfs_remove_link(&bmc->pdev.dev.kobj, intf->my_dev_name);
sysfs_remove_link(&bmc->pdev.dev.kobj, intf->my_dev_name); kfree(intf->my_dev_name);
kfree(intf->my_dev_name); intf->my_dev_name = NULL;
intf->my_dev_name = NULL;
}
mutex_lock(&ipmidriver_mutex); mutex_lock(&ipmidriver_mutex);
kref_put(&bmc->usecount, cleanup_bmc_device); kref_put(&bmc->usecount, cleanup_bmc_device);
mutex_unlock(&ipmidriver_mutex); mutex_unlock(&ipmidriver_mutex);
intf->bmc = NULL; intf->bmc_registered = false;
} }
static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
...@@ -2600,7 +2602,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) ...@@ -2600,7 +2602,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
if (bmc->id.device_id == orig_dev_id) { if (bmc->id.device_id == orig_dev_id) {
printk(KERN_ERR PFX printk(KERN_ERR PFX
"Out of device ids!\n"); "Out of device ids!\n");
break; mutex_unlock(&ipmidriver_mutex);
rv = -EAGAIN;
goto out;
} }
} }
...@@ -2613,16 +2617,11 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) ...@@ -2613,16 +2617,11 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
rv = platform_device_register(&bmc->pdev); rv = platform_device_register(&bmc->pdev);
mutex_unlock(&ipmidriver_mutex); mutex_unlock(&ipmidriver_mutex);
if (rv) { if (rv) {
put_device(&bmc->pdev.dev);
printk(KERN_ERR printk(KERN_ERR
"ipmi_msghandler:" "ipmi_msghandler:"
" Unable to register bmc device: %d\n", " Unable to register bmc device: %d\n",
rv); rv);
/* goto out_list_del;
* Don't go to out_err, you can only do that if
* the device is registered already.
*/
return rv;
} }
dev_info(intf->si_dev, "Found new BMC (man_id: 0x%6.6x, " dev_info(intf->si_dev, "Found new BMC (man_id: 0x%6.6x, "
...@@ -2641,7 +2640,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) ...@@ -2641,7 +2640,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
printk(KERN_ERR printk(KERN_ERR
"ipmi_msghandler: Unable to create bmc symlink: %d\n", "ipmi_msghandler: Unable to create bmc symlink: %d\n",
rv); rv);
goto out_err; goto out_put_bmc;
} }
intf->my_dev_name = kasprintf(GFP_KERNEL, "ipmi%d", ifnum); intf->my_dev_name = kasprintf(GFP_KERNEL, "ipmi%d", ifnum);
...@@ -2650,7 +2649,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) ...@@ -2650,7 +2649,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
printk(KERN_ERR printk(KERN_ERR
"ipmi_msghandler: allocate link from BMC: %d\n", "ipmi_msghandler: allocate link from BMC: %d\n",
rv); rv);
goto out_err; goto out_unlink1;
} }
rv = sysfs_create_link(&bmc->pdev.dev.kobj, &intf->si_dev->kobj, rv = sysfs_create_link(&bmc->pdev.dev.kobj, &intf->si_dev->kobj,
...@@ -2662,14 +2661,35 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) ...@@ -2662,14 +2661,35 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
"ipmi_msghandler:" "ipmi_msghandler:"
" Unable to create symlink to bmc: %d\n", " Unable to create symlink to bmc: %d\n",
rv); rv);
goto out_err; goto out_free_my_dev_name;
} }
return 0; intf->bmc_registered = true;
out_err: out:
ipmi_bmc_unregister(intf);
return rv; return rv;
out_free_my_dev_name:
kfree(intf->my_dev_name);
intf->my_dev_name = NULL;
out_unlink1:
sysfs_remove_link(&intf->si_dev->kobj, "bmc");
out_put_bmc:
mutex_lock(&ipmidriver_mutex);
intf->bmc = NULL;
kref_put(&bmc->usecount, cleanup_bmc_device);
mutex_unlock(&ipmidriver_mutex);
goto out;
out_list_del:
mutex_lock(&ipmidriver_mutex);
intf->bmc = NULL;
mutex_unlock(&ipmidriver_mutex);
put_device(&bmc->pdev.dev);
goto out;
} }
static int static int
...@@ -2959,6 +2979,10 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, ...@@ -2959,6 +2979,10 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
get_guid(intf); get_guid(intf);
rv = ipmi_bmc_register(intf, i);
if (rv)
goto out;
if ((intf->ipmi_version_major > 1) if ((intf->ipmi_version_major > 1)
|| ((intf->ipmi_version_major == 1) || ((intf->ipmi_version_major == 1)
&& (intf->ipmi_version_minor >= 5))) { && (intf->ipmi_version_minor >= 5))) {
...@@ -2987,13 +3011,11 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, ...@@ -2987,13 +3011,11 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
intf->curr_channel = IPMI_MAX_CHANNELS; intf->curr_channel = IPMI_MAX_CHANNELS;
} }
rv = ipmi_bmc_register(intf, i); rv = add_proc_entries(intf, i);
if (rv == 0)
rv = add_proc_entries(intf, i);
out: out:
if (rv) { if (rv) {
ipmi_bmc_unregister(intf);
if (intf->proc_dir) if (intf->proc_dir)
remove_proc_entries(intf); remove_proc_entries(intf);
intf->handlers = NULL; intf->handlers = NULL;
......
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