|
@@ -3381,39 +3381,45 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
|
|
|
|
|
|
rv = handlers->start_processing(send_info, intf);
|
|
|
if (rv)
|
|
|
- goto out;
|
|
|
+ goto out_err;
|
|
|
|
|
|
rv = __bmc_get_device_id(intf, NULL, &id, NULL, NULL, i);
|
|
|
if (rv) {
|
|
|
dev_err(si_dev, "Unable to get the device id: %d\n", rv);
|
|
|
- goto out;
|
|
|
+ goto out_err_started;
|
|
|
}
|
|
|
|
|
|
mutex_lock(&intf->bmc_reg_mutex);
|
|
|
rv = __scan_channels(intf, &id);
|
|
|
mutex_unlock(&intf->bmc_reg_mutex);
|
|
|
+ if (rv)
|
|
|
+ goto out_err_bmc_reg;
|
|
|
|
|
|
- out:
|
|
|
- if (rv) {
|
|
|
- ipmi_bmc_unregister(intf);
|
|
|
- list_del_rcu(&intf->link);
|
|
|
- mutex_unlock(&ipmi_interfaces_mutex);
|
|
|
- synchronize_srcu(&ipmi_interfaces_srcu);
|
|
|
- cleanup_srcu_struct(&intf->users_srcu);
|
|
|
- kref_put(&intf->refcount, intf_free);
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * Keep memory order straight for RCU readers. Make
|
|
|
- * sure everything else is committed to memory before
|
|
|
- * setting intf_num to mark the interface valid.
|
|
|
- */
|
|
|
- smp_wmb();
|
|
|
- intf->intf_num = i;
|
|
|
- mutex_unlock(&ipmi_interfaces_mutex);
|
|
|
+ /*
|
|
|
+ * Keep memory order straight for RCU readers. Make
|
|
|
+ * sure everything else is committed to memory before
|
|
|
+ * setting intf_num to mark the interface valid.
|
|
|
+ */
|
|
|
+ smp_wmb();
|
|
|
+ intf->intf_num = i;
|
|
|
+ mutex_unlock(&ipmi_interfaces_mutex);
|
|
|
|
|
|
- /* After this point the interface is legal to use. */
|
|
|
- call_smi_watchers(i, intf->si_dev);
|
|
|
- }
|
|
|
+ /* After this point the interface is legal to use. */
|
|
|
+ call_smi_watchers(i, intf->si_dev);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ out_err_bmc_reg:
|
|
|
+ ipmi_bmc_unregister(intf);
|
|
|
+ out_err_started:
|
|
|
+ if (intf->handlers->shutdown)
|
|
|
+ intf->handlers->shutdown(intf->send_info);
|
|
|
+ out_err:
|
|
|
+ list_del_rcu(&intf->link);
|
|
|
+ mutex_unlock(&ipmi_interfaces_mutex);
|
|
|
+ synchronize_srcu(&ipmi_interfaces_srcu);
|
|
|
+ cleanup_srcu_struct(&intf->users_srcu);
|
|
|
+ kref_put(&intf->refcount, intf_free);
|
|
|
|
|
|
return rv;
|
|
|
}
|
|
@@ -3504,7 +3510,8 @@ void ipmi_unregister_smi(struct ipmi_smi *intf)
|
|
|
}
|
|
|
srcu_read_unlock(&intf->users_srcu, index);
|
|
|
|
|
|
- intf->handlers->shutdown(intf->send_info);
|
|
|
+ if (intf->handlers->shutdown)
|
|
|
+ intf->handlers->shutdown(intf->send_info);
|
|
|
|
|
|
cleanup_smi_msgs(intf);
|
|
|
|