|
@@ -3,6 +3,7 @@
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/dmi.h>
|
|
|
+#include <linux/efi.h>
|
|
|
#include <linux/bootmem.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <asm/dmi.h>
|
|
@@ -185,47 +186,72 @@ static void __init dmi_decode(struct dmi_header *dm)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void __init dmi_scan_machine(void)
|
|
|
+static int __init dmi_present(char __iomem *p)
|
|
|
{
|
|
|
u8 buf[15];
|
|
|
- char __iomem *p, *q;
|
|
|
+ memcpy_fromio(buf, p, 15);
|
|
|
+ if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
|
|
|
+ u16 num = (buf[13] << 8) | buf[12];
|
|
|
+ u16 len = (buf[7] << 8) | buf[6];
|
|
|
+ u32 base = (buf[11] << 24) | (buf[10] << 16) |
|
|
|
+ (buf[9] << 8) | buf[8];
|
|
|
|
|
|
- /*
|
|
|
- * no iounmap() for that ioremap(); it would be a no-op, but it's
|
|
|
- * so early in setup that sucker gets confused into doing what
|
|
|
- * it shouldn't if we actually call it.
|
|
|
- */
|
|
|
- p = ioremap(0xF0000, 0x10000);
|
|
|
- if (p == NULL)
|
|
|
- goto out;
|
|
|
-
|
|
|
- for (q = p; q < p + 0x10000; q += 16) {
|
|
|
- memcpy_fromio(buf, q, 15);
|
|
|
- if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
|
|
|
- u16 num = (buf[13] << 8) | buf[12];
|
|
|
- u16 len = (buf[7] << 8) | buf[6];
|
|
|
- u32 base = (buf[11] << 24) | (buf[10] << 16) |
|
|
|
- (buf[9] << 8) | buf[8];
|
|
|
-
|
|
|
- /*
|
|
|
- * DMI version 0.0 means that the real version is taken from
|
|
|
- * the SMBIOS version, which we don't know at this point.
|
|
|
- */
|
|
|
- if (buf[14] != 0)
|
|
|
- printk(KERN_INFO "DMI %d.%d present.\n",
|
|
|
- buf[14] >> 4, buf[14] & 0xF);
|
|
|
- else
|
|
|
- printk(KERN_INFO "DMI present.\n");
|
|
|
+ /*
|
|
|
+ * DMI version 0.0 means that the real version is taken from
|
|
|
+ * the SMBIOS version, which we don't know at this point.
|
|
|
+ */
|
|
|
+ if (buf[14] != 0)
|
|
|
+ printk(KERN_INFO "DMI %d.%d present.\n",
|
|
|
+ buf[14] >> 4, buf[14] & 0xF);
|
|
|
+ else
|
|
|
+ printk(KERN_INFO "DMI present.\n");
|
|
|
+ if (dmi_table(base,len, num, dmi_decode) == 0)
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
|
|
|
- if (dmi_table(base,len, num, dmi_decode) == 0)
|
|
|
+void __init dmi_scan_machine(void)
|
|
|
+{
|
|
|
+ char __iomem *p, *q;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ if (efi_enabled) {
|
|
|
+ if (!efi.smbios)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /* This is called as a core_initcall() because it isn't
|
|
|
+ * needed during early boot. This also means we can
|
|
|
+ * iounmap the space when we're done with it.
|
|
|
+ */
|
|
|
+ p = dmi_ioremap((unsigned long)efi.smbios, 0x10000);
|
|
|
+ if (p == NULL)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
|
|
|
+ iounmap(p);
|
|
|
+ if (!rc)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /*
|
|
|
+ * no iounmap() for that ioremap(); it would be a no-op, but
|
|
|
+ * it's so early in setup that sucker gets confused into doing
|
|
|
+ * what it shouldn't if we actually call it.
|
|
|
+ */
|
|
|
+ p = dmi_ioremap(0xF0000, 0x10000);
|
|
|
+ if (p == NULL)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ for (q = p; q < p + 0x10000; q += 16) {
|
|
|
+ rc = dmi_present(q);
|
|
|
+ if (!rc)
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-out: printk(KERN_INFO "DMI not present or invalid.\n");
|
|
|
+ out: printk(KERN_INFO "DMI not present or invalid.\n");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* dmi_check_system - check system DMI data
|
|
|
* @list: array of dmi_system_id structures to match against
|