提交 68e7e50f 编写于 作者: C Corey Minyard

ipmi: Don't use BMC product/dev ids in the BMC name

There are a lot of bad things that a set of BMCs could do that
would really confuse the IPMI driver; it's possible for BMCs with
different GUIDs to have the same product/devid (though that's
not technically legal), which would result in platform device
namespace collisions.  Fixing it would involve either using
the GUID in the BMC name, which resulted in huge names, or
just using an ida for numbering the BMCs.  The latter approach
was chosen to avoid the huge names.
Signed-off-by: NCorey Minyard <cminyard@mvista.com>
上级 c468f911
...@@ -268,7 +268,6 @@ struct bmc_device { ...@@ -268,7 +268,6 @@ struct bmc_device {
struct list_head intfs; struct list_head intfs;
unsigned char guid[16]; unsigned char guid[16];
int guid_set; int guid_set;
char name[16];
struct kref usecount; struct kref usecount;
}; };
#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev) #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( ...@@ -2591,6 +2590,8 @@ static struct bmc_device *ipmi_find_bmc_prod_dev_id(
return bmc; return bmc;
} }
static DEFINE_IDA(ipmi_bmc_ida);
static void static void
release_bmc_device(struct device *dev) release_bmc_device(struct device *dev)
{ {
...@@ -2601,8 +2602,10 @@ static void ...@@ -2601,8 +2602,10 @@ static void
cleanup_bmc_device(struct kref *ref) cleanup_bmc_device(struct kref *ref)
{ {
struct bmc_device *bmc = container_of(ref, struct bmc_device, usecount); struct bmc_device *bmc = container_of(ref, struct bmc_device, usecount);
int id = bmc->pdev.id; /* Unregister overwrites id */
platform_device_unregister(&bmc->pdev); platform_device_unregister(&bmc->pdev);
ida_simple_remove(&ipmi_bmc_ida, id);
} }
static void ipmi_bmc_unregister(ipmi_smi_t intf) static void ipmi_bmc_unregister(ipmi_smi_t intf)
...@@ -2663,47 +2666,19 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum) ...@@ -2663,47 +2666,19 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum)
bmc->id.product_id, bmc->id.product_id,
bmc->id.device_id); bmc->id.device_id);
} else { } else {
unsigned char orig_dev_id = bmc->id.device_id; bmc->pdev.name = "ipmi_bmc";
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;
}
}
rv = ida_simple_get(&ipmi_bmc_ida, 0, 0, GFP_KERNEL);
if (rv < 0)
goto out;
bmc->pdev.dev.driver = &ipmidriver.driver; 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.release = release_bmc_device;
bmc->pdev.dev.type = &bmc_device_type; bmc->pdev.dev.type = &bmc_device_type;
kref_init(&bmc->usecount); kref_init(&bmc->usecount);
rv = platform_device_register(&bmc->pdev); rv = platform_device_register(&bmc->pdev);
mutex_lock(&ipmidriver_mutex);
list_add_tail(&intf->bmc_link, &bmc->intfs); list_add_tail(&intf->bmc_link, &bmc->intfs);
mutex_unlock(&ipmidriver_mutex); mutex_unlock(&ipmidriver_mutex);
if (rv) { if (rv) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册