Преглед на файлове

[PATCH] x86_64: Generalize DMI and enable for x86-64

Some people need it now on 64bit so reuse the i386 code for
x86-64. This will be also useful for future bug workarounds.

It is a bit simplified there because there is no need
to do it very early on x86-64. This means it doesn't need
early ioremap et.al. We run it as a core initcall right now.

I hope it's not needed for early setup.

I added a general CONFIG_DMI symbol in case IA64 or someone
else wants to reuse the code later too.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Andi Kleen преди 19 години
родител
ревизия
e992867445
променени са 9 файла, в които са добавени 44 реда и са изтрити 11 реда
  1. 4 0
      arch/i386/Kconfig
  2. 8 8
      arch/i386/kernel/dmi_scan.c
  3. 1 1
      arch/i386/kernel/setup.c
  4. 4 0
      arch/x86_64/Kconfig
  5. 4 1
      arch/x86_64/kernel/Makefile
  6. 9 0
      arch/x86_64/kernel/setup.c
  7. 5 0
      include/asm-i386/io.h
  8. 5 0
      include/asm-x86_64/io.h
  9. 4 1
      include/linux/dmi.h

+ 4 - 0
arch/i386/Kconfig

@@ -41,6 +41,10 @@ config ARCH_MAY_HAVE_PC_FDC
 	bool
 	default y
 
+config DMI
+	bool
+	default y
+
 source "init/Kconfig"
 
 menu "Processor type and features"

+ 8 - 8
arch/i386/kernel/dmi_scan.c

@@ -4,7 +4,7 @@
 #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)
 {
@@ -19,7 +19,7 @@ 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
@@ -40,7 +40,7 @@ static int __init dmi_table(u32 base, int len, int num,
 	u8 *buf, *data;
 	int i = 0;
 		
-	buf = bt_ioremap(base, len);
+	buf = dmi_ioremap(base, len);
 	if (buf == NULL)
 		return -1;
 
@@ -65,7 +65,7 @@ static int __init dmi_table(u32 base, int len, int num,
 		data += 2;
 		i++;
 	}
-	bt_iounmap(buf, len);
+	dmi_iounmap(buf, len);
 	return 0;
 }
 
@@ -112,7 +112,7 @@ static void __init dmi_save_devices(struct dmi_header *dm)
 		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;
@@ -131,7 +131,7 @@ static void __init dmi_save_ipmi_device(struct dmi_header *dm)
 	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;
@@ -139,7 +139,7 @@ static void __init dmi_save_ipmi_device(struct dmi_header *dm)
 
 	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;
@@ -221,7 +221,7 @@ void __init dmi_scan_machine(void)
 		}
 	}
 
-out:	printk(KERN_INFO "DMI not present.\n");
+out:	printk(KERN_INFO "DMI not present or invalid.\n");
 }
 
 

+ 1 - 1
arch/i386/kernel/setup.c

@@ -45,6 +45,7 @@
 #include <linux/nodemask.h>
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
+#include <linux/dmi.h>
 
 #include <video/edid.h>
 
@@ -146,7 +147,6 @@ EXPORT_SYMBOL(ist_info);
 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;
 

+ 4 - 0
arch/x86_64/Kconfig

@@ -69,6 +69,10 @@ config ARCH_MAY_HAVE_PC_FDC
 	bool
 	default y
 
+config DMI
+	bool
+	default y
+
 source "init/Kconfig"
 
 

+ 4 - 1
arch/x86_64/kernel/Makefile

@@ -7,7 +7,8 @@ EXTRA_AFLAGS	:= -traditional
 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
@@ -47,3 +48,5 @@ intel_cacheinfo-y		+= ../../i386/kernel/cpu/intel_cacheinfo.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
+

+ 9 - 0
arch/x86_64/kernel/setup.c

@@ -44,6 +44,7 @@
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
 #include <linux/cpufreq.h>
+#include <linux/dmi.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -1392,3 +1393,11 @@ struct seq_operations cpuinfo_op = {
 	.stop =	c_stop,
 	.show =	show_cpuinfo,
 };
+
+static int __init run_dmi_scan(void)
+{
+	dmi_scan_machine();
+	return 0;
+}
+core_initcall(run_dmi_scan);
+

+ 5 - 0
include/asm-i386/io.h

@@ -131,6 +131,11 @@ extern void iounmap(volatile void __iomem *addr);
 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.
  */

+ 5 - 0
include/asm-x86_64/io.h

@@ -143,6 +143,11 @@ static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
 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.
  */

+ 4 - 1
include/linux/dmi.h

@@ -2,6 +2,7 @@
 #define __DMI_H__
 
 #include <linux/list.h>
+#include <linux/config.h>
 
 enum dmi_field {
 	DMI_NONE,
@@ -60,12 +61,14 @@ struct dmi_device {
 	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; }