diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 8814f4bed862..f42459a27b19 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -268,7 +268,6 @@ struct bmc_device { struct list_head intfs; unsigned char guid[16]; int guid_set; - char name[16]; struct kref usecount; }; #define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev) @@ -2591,6 +2590,8 @@ static struct bmc_device *ipmi_find_bmc_prod_dev_id( return bmc; } +static DEFINE_IDA(ipmi_bmc_ida); + static void release_bmc_device(struct device *dev) { @@ -2601,8 +2602,10 @@ static void cleanup_bmc_device(struct kref *ref) { struct bmc_device *bmc = container_of(ref, struct bmc_device, usecount); + int id = bmc->pdev.id; /* Unregister overwrites id */ platform_device_unregister(&bmc->pdev); + ida_simple_remove(&ipmi_bmc_ida, id); } static void ipmi_bmc_unregister(ipmi_smi_t intf) @@ -2663,47 +2666,19 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) bmc->id.product_id, bmc->id.device_id); } else { - unsigned char orig_dev_id = bmc->id.device_id; - int warn_printed = 0; - struct bmc_device *tmp_bmc; - - snprintf(bmc->name, sizeof(bmc->name), - "ipmi_bmc.%4.4x", bmc->id.product_id); - bmc->pdev.name = bmc->name; - - mutex_lock(&ipmidriver_mutex); - while ((tmp_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, - bmc->id.product_id, - bmc->id.device_id))) { - kref_put(&tmp_bmc->usecount, cleanup_bmc_device); - if (!warn_printed) { - printk(KERN_WARNING PFX - "This machine has two different BMCs" - " with the same product id and device" - " id. This is an error in the" - " firmware, but incrementing the" - " device id to work around the problem." - " Prod ID = 0x%x, Dev ID = 0x%x\n", - bmc->id.product_id, bmc->id.device_id); - warn_printed = 1; - } - bmc->id.device_id++; /* Wraps at 255 */ - if (bmc->id.device_id == orig_dev_id) { - printk(KERN_ERR PFX - "Out of device ids!\n"); - mutex_unlock(&ipmidriver_mutex); - rv = -EAGAIN; - goto out; - } - } + bmc->pdev.name = "ipmi_bmc"; + rv = ida_simple_get(&ipmi_bmc_ida, 0, 0, GFP_KERNEL); + if (rv < 0) + goto out; bmc->pdev.dev.driver = &ipmidriver.driver; - bmc->pdev.id = bmc->id.device_id; + bmc->pdev.id = rv; bmc->pdev.dev.release = release_bmc_device; bmc->pdev.dev.type = &bmc_device_type; kref_init(&bmc->usecount); rv = platform_device_register(&bmc->pdev); + mutex_lock(&ipmidriver_mutex); list_add_tail(&intf->bmc_link, &bmc->intfs); mutex_unlock(&ipmidriver_mutex); if (rv) {