Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f3069ae9d76901d021362bb63d9ad6c5900dfc76
Commit:     f3069ae9d76901d021362bb63d9ad6c5900dfc76
Parent:     c8626a1d7250c593f148530b559c20f6f6af18e8
Author:     Jean Delvare <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 23 15:23:46 2008 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sat Feb 23 17:12:14 2008 -0800

    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: Jean Delvare <[EMAIL PROTECTED]>
    Cc: Wim Van Sebroeck <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/firmware/dmi_scan.c |   74 +++++++++++++++++++++++++-----------------
 1 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 653265a..de30275 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -10,10 +10,9 @@
 
 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;
-       char *str = "";
 
        if (s) {
                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))
                                return dmi_empty_string;
-                       str = dmi_alloc(len);
-                       if (str != NULL)
-                               strcpy(str, bp);
-                       else
-                               printk(KERN_ERR "dmi_string: cannot allocate 
%Zu bytes.\n", len);
+                       return bp;
                }
        }
 
+       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;
 }
 
@@ -167,10 +181,30 @@ static void __init dmi_save_type(const struct dmi_header 
*dm, int slot, int inde
        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)
 {
        int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
-       struct dmi_device *dev;
 
        for (i = 0; i < count; i++) {
                const char *d = (char *)(dm + 1) + (i * 2);
@@ -179,16 +213,7 @@ static void __init dmi_save_devices(const struct 
dmi_header *dm)
                if ((*d & 0x80) == 0)
                        continue;
 
-               dev = dmi_alloc(sizeof(*dev));
-               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);
+               dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d + 1)));
        }
 }
 
@@ -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)
 {
        const u8 *d = (u8*) dm + 5;
-       struct dmi_device *dev;
 
        /* Skip disabled device */
        if ((*d & 0x80) == 0)
                return;
 
-       dev = dmi_alloc(sizeof(*dev));
-       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);
+       dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
 }
 
 /*
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to