summaryrefslogtreecommitdiff
path: root/drivers/char/ipmi/ipmi_msghandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_msghandler.c')
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c144
1 files changed, 110 insertions, 34 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 2455e8d478ac..c47add8e47df 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -376,13 +376,23 @@ static void free_recv_msg_list(struct list_head *q)
}
}
+static void free_smi_msg_list(struct list_head *q)
+{
+ struct ipmi_smi_msg *msg, *msg2;
+
+ list_for_each_entry_safe(msg, msg2, q, link) {
+ list_del(&msg->link);
+ ipmi_free_smi_msg(msg);
+ }
+}
+
static void clean_up_interface_data(ipmi_smi_t intf)
{
int i;
struct cmd_rcvr *rcvr, *rcvr2;
struct list_head list;
- free_recv_msg_list(&intf->waiting_msgs);
+ free_smi_msg_list(&intf->waiting_msgs);
free_recv_msg_list(&intf->waiting_events);
/* Wholesale remove all the entries from the list in the
@@ -1844,7 +1854,7 @@ static ssize_t provides_dev_sdrs_show(struct device *dev,
struct bmc_device *bmc = dev_get_drvdata(dev);
return snprintf(buf, 10, "%u\n",
- bmc->id.device_revision && 0x80 >> 7);
+ (bmc->id.device_revision & 0x80) >> 7);
}
static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
@@ -1853,7 +1863,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
struct bmc_device *bmc = dev_get_drvdata(dev);
return snprintf(buf, 20, "%u\n",
- bmc->id.device_revision && 0x0F);
+ bmc->id.device_revision & 0x0F);
}
static ssize_t firmware_rev_show(struct device *dev,
@@ -1928,13 +1938,8 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
(long long) bmc->guid[8]);
}
-static void
-cleanup_bmc_device(struct kref *ref)
+static void remove_files(struct bmc_device *bmc)
{
- struct bmc_device *bmc;
-
- bmc = container_of(ref, struct bmc_device, refcount);
-
device_remove_file(&bmc->dev->dev,
&bmc->device_id_attr);
device_remove_file(&bmc->dev->dev,
@@ -1951,12 +1956,23 @@ cleanup_bmc_device(struct kref *ref)
&bmc->manufacturer_id_attr);
device_remove_file(&bmc->dev->dev,
&bmc->product_id_attr);
+
if (bmc->id.aux_firmware_revision_set)
device_remove_file(&bmc->dev->dev,
&bmc->aux_firmware_rev_attr);
if (bmc->guid_set)
device_remove_file(&bmc->dev->dev,
&bmc->guid_attr);
+}
+
+static void
+cleanup_bmc_device(struct kref *ref)
+{
+ struct bmc_device *bmc;
+
+ bmc = container_of(ref, struct bmc_device, refcount);
+
+ remove_files(bmc);
platform_device_unregister(bmc->dev);
kfree(bmc);
}
@@ -1977,6 +1993,79 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
mutex_unlock(&ipmidriver_mutex);
}
+static int create_files(struct bmc_device *bmc)
+{
+ int err;
+
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->device_id_attr);
+ if (err) goto out;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->provides_dev_sdrs_attr);
+ if (err) goto out_devid;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->revision_attr);
+ if (err) goto out_sdrs;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->firmware_rev_attr);
+ if (err) goto out_rev;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->version_attr);
+ if (err) goto out_firm;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->add_dev_support_attr);
+ if (err) goto out_version;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->manufacturer_id_attr);
+ if (err) goto out_add_dev;
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->product_id_attr);
+ if (err) goto out_manu;
+ if (bmc->id.aux_firmware_revision_set) {
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->aux_firmware_rev_attr);
+ if (err) goto out_prod_id;
+ }
+ if (bmc->guid_set) {
+ err = device_create_file(&bmc->dev->dev,
+ &bmc->guid_attr);
+ if (err) goto out_aux_firm;
+ }
+
+ return 0;
+
+out_aux_firm:
+ if (bmc->id.aux_firmware_revision_set)
+ device_remove_file(&bmc->dev->dev,
+ &bmc->aux_firmware_rev_attr);
+out_prod_id:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->product_id_attr);
+out_manu:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->manufacturer_id_attr);
+out_add_dev:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->add_dev_support_attr);
+out_version:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->version_attr);
+out_firm:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->firmware_rev_attr);
+out_rev:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->revision_attr);
+out_sdrs:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->provides_dev_sdrs_attr);
+out_devid:
+ device_remove_file(&bmc->dev->dev,
+ &bmc->device_id_attr);
+out:
+ return err;
+}
+
static int ipmi_bmc_register(ipmi_smi_t intf)
{
int rv;
@@ -2029,7 +2118,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
dev_set_drvdata(&bmc->dev->dev, bmc);
kref_init(&bmc->refcount);
- rv = platform_device_register(bmc->dev);
+ rv = platform_device_add(bmc->dev);
mutex_unlock(&ipmidriver_mutex);
if (rv) {
printk(KERN_ERR
@@ -2051,7 +2140,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
-
bmc->revision_attr.attr.name = "revision";
bmc->revision_attr.attr.owner = THIS_MODULE;
bmc->revision_attr.attr.mode = S_IRUGO;
@@ -2093,28 +2181,14 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
- device_create_file(&bmc->dev->dev,
- &bmc->device_id_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->provides_dev_sdrs_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->revision_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->firmware_rev_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->version_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->add_dev_support_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->manufacturer_id_attr);
- device_create_file(&bmc->dev->dev,
- &bmc->product_id_attr);
- if (bmc->id.aux_firmware_revision_set)
- device_create_file(&bmc->dev->dev,
- &bmc->aux_firmware_rev_attr);
- if (bmc->guid_set)
- device_create_file(&bmc->dev->dev,
- &bmc->guid_attr);
+ rv = create_files(bmc);
+ if (rv) {
+ mutex_lock(&ipmidriver_mutex);
+ platform_device_unregister(bmc->dev);
+ mutex_unlock(&ipmidriver_mutex);
+
+ return rv;
+ }
printk(KERN_INFO
"ipmi: Found new BMC (man_id: 0x%6.6x, "
@@ -3168,7 +3242,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
report the error immediately. */
if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0)
&& (msg->rsp[2] != IPMI_NODE_BUSY_ERR)
- && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR))
+ && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)
+ && (msg->rsp[2] != IPMI_BUS_ERR)
+ && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR))
{
int chan = msg->rsp[3] & 0xf;