提交 f3069ae9 编写于 作者: J Jean Delvare 提交者: Linus Torvalds

dmi: don't save the same device twice

Now that we gather on-board devices from both DMI types 10 and 41, there is
a possibility that we list the same device twice.  In order to not confuse
drivers, and also to save memory, make sure that we do not add duplicate
devices to the dmi_devices list.
Signed-off-by: NJean Delvare <khali@linux-fr.org>
Cc: Wim Van Sebroeck <wim@iguana.be>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 c8626a1d
...@@ -10,10 +10,9 @@ ...@@ -10,10 +10,9 @@
static char dmi_empty_string[] = " "; static char dmi_empty_string[] = " ";
static char * __init dmi_string(const struct dmi_header *dm, u8 s) static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
{ {
const u8 *bp = ((u8 *) dm) + dm->length; const u8 *bp = ((u8 *) dm) + dm->length;
char *str = "";
if (s) { if (s) {
s--; s--;
...@@ -28,14 +27,29 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s) ...@@ -28,14 +27,29 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s)
if (!memcmp(bp, dmi_empty_string, cmp_len)) if (!memcmp(bp, dmi_empty_string, cmp_len))
return dmi_empty_string; return dmi_empty_string;
str = dmi_alloc(len); return bp;
if (str != NULL)
strcpy(str, bp);
else
printk(KERN_ERR "dmi_string: cannot allocate %Zu bytes.\n", len);
} }
} }
return "";
}
static char * __init dmi_string(const struct dmi_header *dm, u8 s)
{
const char *bp = dmi_string_nosave(dm, s);
char *str;
size_t len;
if (bp == dmi_empty_string)
return dmi_empty_string;
len = strlen(bp) + 1;
str = dmi_alloc(len);
if (str != NULL)
strcpy(str, bp);
else
printk(KERN_ERR "dmi_string: cannot allocate %Zu bytes.\n", len);
return str; return str;
} }
...@@ -167,10 +181,30 @@ static void __init dmi_save_type(const struct dmi_header *dm, int slot, int inde ...@@ -167,10 +181,30 @@ static void __init dmi_save_type(const struct dmi_header *dm, int slot, int inde
dmi_ident[slot] = s; dmi_ident[slot] = s;
} }
static void __init dmi_save_one_device(int type, const char *name)
{
struct dmi_device *dev;
/* No duplicate device */
if (dmi_find_device(type, name, NULL))
return;
dev = dmi_alloc(sizeof(*dev) + strlen(name) + 1);
if (!dev) {
printk(KERN_ERR "dmi_save_one_device: out of memory.\n");
return;
}
dev->type = type;
strcpy((char *)(dev + 1), name);
dev->name = (char *)(dev + 1);
dev->device_data = NULL;
list_add(&dev->list, &dmi_devices);
}
static void __init dmi_save_devices(const struct dmi_header *dm) static void __init dmi_save_devices(const struct dmi_header *dm)
{ {
int i, count = (dm->length - sizeof(struct dmi_header)) / 2; int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
struct dmi_device *dev;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
const char *d = (char *)(dm + 1) + (i * 2); const char *d = (char *)(dm + 1) + (i * 2);
...@@ -179,16 +213,7 @@ static void __init dmi_save_devices(const struct dmi_header *dm) ...@@ -179,16 +213,7 @@ static void __init dmi_save_devices(const struct dmi_header *dm)
if ((*d & 0x80) == 0) if ((*d & 0x80) == 0)
continue; continue;
dev = dmi_alloc(sizeof(*dev)); dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d + 1)));
if (!dev) {
printk(KERN_ERR "dmi_save_devices: out of memory.\n");
break;
}
dev->type = *d++ & 0x7f;
dev->name = dmi_string(dm, *d);
dev->device_data = NULL;
list_add(&dev->list, &dmi_devices);
} }
} }
...@@ -253,23 +278,12 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm) ...@@ -253,23 +278,12 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm)
static void __init dmi_save_extended_devices(const struct dmi_header *dm) static void __init dmi_save_extended_devices(const struct dmi_header *dm)
{ {
const u8 *d = (u8*) dm + 5; const u8 *d = (u8*) dm + 5;
struct dmi_device *dev;
/* Skip disabled device */ /* Skip disabled device */
if ((*d & 0x80) == 0) if ((*d & 0x80) == 0)
return; return;
dev = dmi_alloc(sizeof(*dev)); dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
if (!dev) {
printk(KERN_ERR "dmi_save_extended_devices: out of memory.\n");
return;
}
dev->type = *d-- & 0x7f;
dev->name = dmi_string(dm, *d);
dev->device_data = NULL;
list_add(&dev->list, &dmi_devices);
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册