#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>
        }
 }
 
-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
 
 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o      \
         irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o          \
         salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
-        unwind.o mca.o mca_asm.o topology.o
+        unwind.o mca.o mca_asm.o topology.o dmi_scan.o
 
 obj-$(CONFIG_IA64_BRL_EMU)     += brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)     += acpi-ext.o
 obj-$(CONFIG_KPROBES)          += kprobes.o jprobes.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)  += uncached.o
 mca_recovery-y                 += mca_drv.o mca_drv_asm.o
+dmi_scan-y                     += ../../i386/kernel/dmi_scan.o
 
 # The gate DSO image is built using a special linker script.
 targets += gate.so gate-syms.o