summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c285
1 files changed, 92 insertions, 193 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index e5d7c0b6fe3d..4539afa5b7f2 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -191,12 +191,12 @@ struct ipmi_proc_entry {
#endif
struct bmc_device {
- struct platform_device *dev;
+ struct platform_device pdev;
struct ipmi_device_id id;
unsigned char guid[16];
int guid_set;
-
- struct kref refcount;
+ char name[16];
+ struct kref usecount;
/* bmc device attributes */
struct device_attribute device_id_attr;
@@ -210,6 +210,7 @@ struct bmc_device {
struct device_attribute guid_attr;
struct device_attribute aux_firmware_rev_attr;
};
+#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev)
/*
* Various statistics for IPMI, these index stats[] in the ipmi_smi
@@ -2165,7 +2166,7 @@ static void remove_proc_entries(ipmi_smi_t smi)
static int __find_bmc_guid(struct device *dev, void *data)
{
unsigned char *id = data;
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return memcmp(bmc->guid, id, 16) == 0;
}
@@ -2176,7 +2177,7 @@ static struct bmc_device *ipmi_find_bmc_guid(struct device_driver *drv,
dev = driver_find_device(drv, NULL, guid, __find_bmc_guid);
if (dev)
- return dev_get_drvdata(dev);
+ return to_bmc_device(dev);
else
return NULL;
}
@@ -2189,7 +2190,7 @@ struct prod_dev_id {
static int __find_bmc_prod_dev_id(struct device *dev, void *data)
{
struct prod_dev_id *id = data;
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return (bmc->id.product_id == id->product_id
&& bmc->id.device_id == id->device_id);
@@ -2207,7 +2208,7 @@ static struct bmc_device *ipmi_find_bmc_prod_dev_id(
dev = driver_find_device(drv, NULL, &id, __find_bmc_prod_dev_id);
if (dev)
- return dev_get_drvdata(dev);
+ return to_bmc_device(dev);
else
return NULL;
}
@@ -2216,84 +2217,92 @@ static ssize_t device_id_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 10, "%u\n", bmc->id.device_id);
}
+DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL);
-static ssize_t provides_dev_sdrs_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t provides_device_sdrs_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 10, "%u\n",
(bmc->id.device_revision & 0x80) >> 7);
}
+DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, NULL);
static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 20, "%u\n",
bmc->id.device_revision & 0x0F);
}
+DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL);
-static ssize_t firmware_rev_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t firmware_revision_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1,
bmc->id.firmware_revision_2);
}
+DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL);
static ssize_t ipmi_version_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 20, "%u.%u\n",
ipmi_version_major(&bmc->id),
ipmi_version_minor(&bmc->id));
}
+DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL);
static ssize_t add_dev_support_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 10, "0x%02x\n",
bmc->id.additional_device_support);
}
+DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, NULL);
static ssize_t manufacturer_id_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id);
}
+DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL);
static ssize_t product_id_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id);
}
+DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL);
static ssize_t aux_firmware_rev_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 21, "0x%02x 0x%02x 0x%02x 0x%02x\n",
bmc->id.aux_firmware_revision[3],
@@ -2301,57 +2310,63 @@ static ssize_t aux_firmware_rev_show(struct device *dev,
bmc->id.aux_firmware_revision[1],
bmc->id.aux_firmware_revision[0]);
}
+DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL);
static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct bmc_device *bmc = dev_get_drvdata(dev);
+ struct bmc_device *bmc = to_bmc_device(dev);
return snprintf(buf, 100, "%Lx%Lx\n",
(long long) bmc->guid[0],
(long long) bmc->guid[8]);
}
+DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL);
+
+static struct attribute *bmc_dev_attrs[] = {
+ &dev_attr_device_id.attr,
+ &dev_attr_provides_device_sdrs.attr,
+ &dev_attr_revision.attr,
+ &dev_attr_firmware_revision.attr,
+ &dev_attr_ipmi_version.attr,
+ &dev_attr_additional_device_support.attr,
+ &dev_attr_manufacturer_id.attr,
+ &dev_attr_product_id.attr,
+ NULL
+};
-static void remove_files(struct bmc_device *bmc)
-{
- if (!bmc->dev)
- return;
+static struct attribute_group bmc_dev_attr_group = {
+ .attrs = bmc_dev_attrs,
+};
- device_remove_file(&bmc->dev->dev,
- &bmc->device_id_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->provides_dev_sdrs_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->revision_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->firmware_rev_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->version_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->add_dev_support_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->manufacturer_id_attr);
- device_remove_file(&bmc->dev->dev,
- &bmc->product_id_attr);
+static const struct attribute_group *bmc_dev_attr_groups[] = {
+ &bmc_dev_attr_group,
+ NULL
+};
- 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 struct device_type bmc_device_type = {
+ .groups = bmc_dev_attr_groups,
+};
+
+static void
+release_bmc_device(struct device *dev)
+{
+ kfree(to_bmc_device(dev));
}
static void
cleanup_bmc_device(struct kref *ref)
{
- struct bmc_device *bmc;
+ struct bmc_device *bmc = container_of(ref, struct bmc_device, usecount);
- bmc = container_of(ref, struct bmc_device, refcount);
+ if (bmc->id.aux_firmware_revision_set)
+ device_remove_file(&bmc->pdev.dev,
+ &bmc->aux_firmware_rev_attr);
+ if (bmc->guid_set)
+ device_remove_file(&bmc->pdev.dev,
+ &bmc->guid_attr);
- remove_files(bmc);
- platform_device_unregister(bmc->dev);
- kfree(bmc);
+ platform_device_unregister(&bmc->pdev);
}
static void ipmi_bmc_unregister(ipmi_smi_t intf)
@@ -2364,111 +2379,29 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
intf->sysfs_name = NULL;
}
if (intf->my_dev_name) {
- sysfs_remove_link(&bmc->dev->dev.kobj, intf->my_dev_name);
+ sysfs_remove_link(&bmc->pdev.dev.kobj, intf->my_dev_name);
kfree(intf->my_dev_name);
intf->my_dev_name = NULL;
}
mutex_lock(&ipmidriver_mutex);
- kref_put(&bmc->refcount, cleanup_bmc_device);
+ kref_put(&bmc->usecount, cleanup_bmc_device);
intf->bmc = NULL;
mutex_unlock(&ipmidriver_mutex);
}
-static int create_files(struct bmc_device *bmc)
+static int create_bmc_files(struct bmc_device *bmc)
{
int err;
- bmc->device_id_attr.attr.name = "device_id";
- bmc->device_id_attr.attr.mode = S_IRUGO;
- bmc->device_id_attr.show = device_id_show;
- sysfs_attr_init(&bmc->device_id_attr.attr);
-
- bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
- bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
- bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
- sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
-
- bmc->revision_attr.attr.name = "revision";
- bmc->revision_attr.attr.mode = S_IRUGO;
- bmc->revision_attr.show = revision_show;
- sysfs_attr_init(&bmc->revision_attr.attr);
-
- bmc->firmware_rev_attr.attr.name = "firmware_revision";
- bmc->firmware_rev_attr.attr.mode = S_IRUGO;
- bmc->firmware_rev_attr.show = firmware_rev_show;
- sysfs_attr_init(&bmc->firmware_rev_attr.attr);
-
- bmc->version_attr.attr.name = "ipmi_version";
- bmc->version_attr.attr.mode = S_IRUGO;
- bmc->version_attr.show = ipmi_version_show;
- sysfs_attr_init(&bmc->version_attr.attr);
-
- bmc->add_dev_support_attr.attr.name = "additional_device_support";
- bmc->add_dev_support_attr.attr.mode = S_IRUGO;
- bmc->add_dev_support_attr.show = add_dev_support_show;
- sysfs_attr_init(&bmc->add_dev_support_attr.attr);
-
- bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
- bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
- bmc->manufacturer_id_attr.show = manufacturer_id_show;
- sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
-
- bmc->product_id_attr.attr.name = "product_id";
- bmc->product_id_attr.attr.mode = S_IRUGO;
- bmc->product_id_attr.show = product_id_show;
- sysfs_attr_init(&bmc->product_id_attr.attr);
-
- bmc->guid_attr.attr.name = "guid";
- bmc->guid_attr.attr.mode = S_IRUGO;
- bmc->guid_attr.show = guid_show;
- sysfs_attr_init(&bmc->guid_attr.attr);
-
- bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
- bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
- bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
- sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
-
- 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,
+ err = device_create_file(&bmc->pdev.dev,
&bmc->aux_firmware_rev_attr);
if (err)
- goto out_prod_id;
+ goto out;
}
if (bmc->guid_set) {
- err = device_create_file(&bmc->dev->dev,
+ err = device_create_file(&bmc->pdev.dev,
&bmc->guid_attr);
if (err)
goto out_aux_firm;
@@ -2478,32 +2411,8 @@ static int create_files(struct bmc_device *bmc)
out_aux_firm:
if (bmc->id.aux_firmware_revision_set)
- device_remove_file(&bmc->dev->dev,
+ device_remove_file(&bmc->pdev.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;
}
@@ -2514,8 +2423,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
int rv;
struct bmc_device *bmc = intf->bmc;
struct bmc_device *old_bmc;
- int size;
- char dummy[1];
mutex_lock(&ipmidriver_mutex);
@@ -2539,7 +2446,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
intf->bmc = old_bmc;
bmc = old_bmc;
- kref_get(&bmc->refcount);
+ kref_get(&bmc->usecount);
mutex_unlock(&ipmidriver_mutex);
printk(KERN_INFO
@@ -2549,12 +2456,12 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
bmc->id.product_id,
bmc->id.device_id);
} else {
- char name[14];
unsigned char orig_dev_id = bmc->id.device_id;
int warn_printed = 0;
- snprintf(name, sizeof(name),
+ snprintf(bmc->name, sizeof(bmc->name),
"ipmi_bmc.%4.4x", bmc->id.product_id);
+ bmc->pdev.name = bmc->name;
while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
bmc->id.product_id,
@@ -2578,23 +2485,15 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
}
}
- bmc->dev = platform_device_alloc(name, bmc->id.device_id);
- if (!bmc->dev) {
- mutex_unlock(&ipmidriver_mutex);
- printk(KERN_ERR
- "ipmi_msghandler:"
- " Unable to allocate platform device\n");
- return -ENOMEM;
- }
- bmc->dev->dev.driver = &ipmidriver.driver;
- dev_set_drvdata(&bmc->dev->dev, bmc);
- kref_init(&bmc->refcount);
+ bmc->pdev.dev.driver = &ipmidriver.driver;
+ bmc->pdev.id = bmc->id.device_id;
+ bmc->pdev.dev.release = release_bmc_device;
+ bmc->pdev.dev.type = &bmc_device_type;
- rv = platform_device_add(bmc->dev);
+ rv = platform_device_register(&bmc->pdev);
mutex_unlock(&ipmidriver_mutex);
if (rv) {
- platform_device_put(bmc->dev);
- bmc->dev = NULL;
+ put_device(&bmc->pdev.dev);
printk(KERN_ERR
"ipmi_msghandler:"
" Unable to register bmc device: %d\n",
@@ -2606,10 +2505,12 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
return rv;
}
- rv = create_files(bmc);
+ kref_init(&bmc->usecount);
+
+ rv = create_bmc_files(bmc);
if (rv) {
mutex_lock(&ipmidriver_mutex);
- platform_device_unregister(bmc->dev);
+ platform_device_unregister(&bmc->pdev);
mutex_unlock(&ipmidriver_mutex);
return rv;
@@ -2636,7 +2537,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
}
rv = sysfs_create_link(&intf->si_dev->kobj,
- &bmc->dev->dev.kobj, intf->sysfs_name);
+ &bmc->pdev.dev.kobj, intf->sysfs_name);
if (rv) {
kfree(intf->sysfs_name);
intf->sysfs_name = NULL;
@@ -2646,8 +2547,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
goto out_err;
}
- size = snprintf(dummy, 0, "ipmi%d", ifnum);
- intf->my_dev_name = kmalloc(size+1, GFP_KERNEL);
+ intf->my_dev_name = kasprintf(GFP_KERNEL, "ipmi%d", ifnum);
if (!intf->my_dev_name) {
kfree(intf->sysfs_name);
intf->sysfs_name = NULL;
@@ -2657,9 +2557,8 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
rv);
goto out_err;
}
- snprintf(intf->my_dev_name, size+1, "ipmi%d", ifnum);
- rv = sysfs_create_link(&bmc->dev->dev.kobj, &intf->si_dev->kobj,
+ rv = sysfs_create_link(&bmc->pdev.dev.kobj, &intf->si_dev->kobj,
intf->my_dev_name);
if (rv) {
kfree(intf->sysfs_name);