dmi_scan: refactor dmi_scan_machine(), {smbios,dmi}_present()
[pandora-kernel.git] / drivers / firmware / dmi_scan.c
index 982f1f5..232bb65 100644 (file)
@@ -410,22 +410,45 @@ static void __init dmi_dump_ids(void)
        printk(KERN_CONT "\n");
 }
 
-static int __init dmi_present(const char __iomem *p)
+static int __init dmi_present(const u8 *buf)
 {
-       u8 buf[15];
+       int smbios_ver;
 
-       memcpy_fromio(buf, p, 15);
-       if (dmi_checksum(buf, 15)) {
+       if (memcmp(buf, "_SM_", 4) == 0 &&
+           buf[5] < 32 && dmi_checksum(buf, buf[5])) {
+               smbios_ver = (buf[6] << 8) + buf[7];
+
+               /* Some BIOS report weird SMBIOS version, fix that up */
+               switch (smbios_ver) {
+               case 0x021F:
+               case 0x0221:
+                       pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
+                                smbios_ver & 0xFF, 3);
+                       smbios_ver = 0x0203;
+                       break;
+               case 0x0233:
+                       pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
+                       smbios_ver = 0x0206;
+                       break;
+               }
+       } else {
+               smbios_ver = 0;
+       }
+
+       buf += 16;
+
+       if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
                dmi_num = (buf[13] << 8) | buf[12];
                dmi_len = (buf[7] << 8) | buf[6];
                dmi_base = (buf[11] << 24) | (buf[10] << 16) |
                        (buf[9] << 8) | buf[8];
 
                if (dmi_walk_early(dmi_decode) == 0) {
-                       if (dmi_ver)
+                       if (smbios_ver) {
+                               dmi_ver = smbios_ver;
                                pr_info("SMBIOS %d.%d present.\n",
                                       dmi_ver >> 8, dmi_ver & 0xFF);
-                       else {
+                       else {
                                dmi_ver = (buf[14] & 0xF0) << 4 |
                                           (buf[14] & 0x0F);
                                pr_info("Legacy DMI %d.%d present.\n",
@@ -435,41 +458,14 @@ static int __init dmi_present(const char __iomem *p)
                        return 0;
                }
        }
-       dmi_ver = 0;
-       return 1;
-}
 
-static int __init smbios_present(const char __iomem *p)
-{
-       u8 buf[32];
-       int offset = 0;
-
-       memcpy_fromio(buf, p, 32);
-       if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
-               dmi_ver = (buf[6] << 8) + buf[7];
-
-               /* Some BIOS report weird SMBIOS version, fix that up */
-               switch (dmi_ver) {
-               case 0x021F:
-               case 0x0221:
-                       pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
-                              dmi_ver & 0xFF, 3);
-                       dmi_ver = 0x0203;
-                       break;
-               case 0x0233:
-                       pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
-                       dmi_ver = 0x0206;
-                       break;
-               }
-               offset = 16;
-       }
-       return dmi_present(buf + offset);
+       return 1;
 }
 
 void __init dmi_scan_machine(void)
 {
        char __iomem *p, *q;
-       int rc;
+       char buf[32];
 
        if (efi_enabled(EFI_CONFIG_TABLES)) {
                if (efi.smbios == EFI_INVALID_TABLE_ADDR)
@@ -482,10 +478,10 @@ void __init dmi_scan_machine(void)
                p = dmi_ioremap(efi.smbios, 32);
                if (p == NULL)
                        goto error;
-
-               rc = smbios_present(p);
+               memcpy_fromio(buf, p, 32);
                dmi_iounmap(p, 32);
-               if (!rc) {
+
+               if (!dmi_present(buf)) {
                        dmi_available = 1;
                        goto out;
                }
@@ -500,18 +496,15 @@ void __init dmi_scan_machine(void)
                if (p == NULL)
                        goto error;
 
+               memset(buf, 0, 16);
                for (q = p; q < p + 0x10000; q += 16) {
-                       if (memcmp(q, "_SM_", 4) == 0 && q - p <= 0xFFE0)
-                               rc = smbios_present(q);
-                       else if (memcmp(q, "_DMI_", 5) == 0)
-                               rc = dmi_present(q);
-                       else
-                               continue;
-                       if (!rc) {
+                       memcpy_fromio(buf + 16, q, 16);
+                       if (!dmi_present(buf)) {
                                dmi_available = 1;
                                dmi_iounmap(p, 0x10000);
                                goto out;
                        }
+                       memcpy(buf, buf + 16, 16);
                }
                dmi_iounmap(p, 0x10000);
        }
@@ -535,9 +528,15 @@ static bool dmi_matches(const struct dmi_system_id *dmi)
                int s = dmi->matches[i].slot;
                if (s == DMI_NONE)
                        break;
-               if (dmi_ident[s]
-                   && strstr(dmi_ident[s], dmi->matches[i].substr))
-                       continue;
+               if (dmi_ident[s]) {
+                       if (!dmi->matches[i].exact_match &&
+                           strstr(dmi_ident[s], dmi->matches[i].substr))
+                               continue;
+                       else if (dmi->matches[i].exact_match &&
+                                !strcmp(dmi_ident[s], dmi->matches[i].substr))
+                               continue;
+               }
+
                /* No match */
                return false;
        }