bool
        default y
 
+config DMI
+       bool
+       default y
+
 source "init/Kconfig"
 
 menu "Processor type and features"
 
 #include <linux/module.h>
 #include <linux/dmi.h>
 #include <linux/bootmem.h>
-
+#include <linux/slab.h>
 
 static char * __init dmi_string(struct dmi_header *dm, u8 s)
 {
                }
 
                if (*bp != 0) {
-                       str = alloc_bootmem(strlen(bp) + 1);
+                       str = dmi_alloc(strlen(bp) + 1);
                        if (str != NULL)
                                strcpy(str, bp);
                        else
        u8 *buf, *data;
        int i = 0;
                
-       buf = bt_ioremap(base, len);
+       buf = dmi_ioremap(base, len);
        if (buf == NULL)
                return -1;
 
                data += 2;
                i++;
        }
-       bt_iounmap(buf, len);
+       dmi_iounmap(buf, len);
        return 0;
 }
 
                if ((*d & 0x80) == 0)
                        continue;
 
-               dev = alloc_bootmem(sizeof(*dev));
+               dev = dmi_alloc(sizeof(*dev));
                if (!dev) {
                        printk(KERN_ERR "dmi_save_devices: out of memory.\n");
                        break;
        struct dmi_device *dev;
        void * data;
 
-       data = alloc_bootmem(dm->length);
+       data = dmi_alloc(dm->length);
        if (data == NULL) {
                printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
                return;
 
        memcpy(data, dm, dm->length);
 
-       dev = alloc_bootmem(sizeof(*dev));
+       dev = dmi_alloc(sizeof(*dev));
        if (!dev) {
                printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
                return;
                }
        }
 
-out:   printk(KERN_INFO "DMI not present.\n");
+out:   printk(KERN_INFO "DMI not present or invalid.\n");
 }
 
 
 
 #include <linux/nodemask.h>
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
+#include <linux/dmi.h>
 
 #include <video/edid.h>
 
 struct e820map e820;
 
 extern void early_cpu_init(void);
-extern void dmi_scan_machine(void);
 extern void generic_apic_probe(char *);
 extern int root_mountflags;
 
 
        bool
        default y
 
+config DMI
+       bool
+       default y
+
 source "init/Kconfig"
 
 
 
 obj-y  := process.o signal.o entry.o traps.o irq.o \
                ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
                x8664_ksyms.o i387.o syscall.o vsyscall.o \
-               setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o
+               setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
+               dmi_scan.o
 
 obj-$(CONFIG_X86_MCE)         += mce.o
 obj-$(CONFIG_X86_MCE_INTEL)    += mce_intel.o
 quirks-y                       += ../../i386/kernel/quirks.o
 i8237-y                                += ../../i386/kernel/i8237.o
 msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
+dmi_scan-y                     += ../../i386/kernel/dmi_scan.o
+
 
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
 #include <linux/cpufreq.h>
+#include <linux/dmi.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
        .stop = c_stop,
        .show = show_cpuinfo,
 };
+
+static int __init run_dmi_scan(void)
+{
+       dmi_scan_machine();
+       return 0;
+}
+core_initcall(run_dmi_scan);
+
 
 extern void *bt_ioremap(unsigned long offset, unsigned long size);
 extern void bt_iounmap(void *addr, unsigned long size);
 
+/* Use early IO mappings for DMI because it's initialized early */
+#define dmi_ioremap bt_ioremap
+#define dmi_iounmap bt_iounmap
+#define dmi_alloc alloc_bootmem
+
 /*
  * ISA I/O bus memory addresses are 1:1 with the physical address.
  */
 
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
 extern void iounmap(volatile void __iomem *addr);
 
+/* Use normal IO mappings for DMI */
+#define dmi_ioremap ioremap
+#define dmi_iounmap(x,l) iounmap(x)
+#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
+
 /*
  * ISA I/O bus memory addresses are 1:1 with the physical address.
  */
 
 #define __DMI_H__
 
 #include <linux/list.h>
+#include <linux/config.h>
 
 enum dmi_field {
        DMI_NONE,
        void *device_data;      /* Type specific data */
 };
 
-#if defined(CONFIG_X86_32)
+#ifdef CONFIG_DMI
 
 extern int dmi_check_system(struct dmi_system_id *list);
 extern char * dmi_get_system_info(int field);
 extern struct dmi_device * dmi_find_device(int type, const char *name,
        struct dmi_device *from);
+extern void dmi_scan_machine(void);
+
 #else
 
 static inline int dmi_check_system(struct dmi_system_id *list) { return 0; }