aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorMatt Domsch <Matt_Domsch@dell.com>2006-03-26 04:37:03 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:56:54 -0500
commit3ed3bce846abc7ef460104b461cac793e41afe5e (patch)
tree6db86a6cdfd3600db4e24cd91f53ba6f4f661280 /arch/i386
parent10dbe196a8da6b3196881269c6639c0ec11c36cb (diff)
[PATCH] ia64: use i386 dmi_scan.c
Enable DMI table parsing on ia64. Andi Kleen has a patch in his x86_64 tree which enables the use of i386 dmi_scan.c on x86_64. dmi_scan.c functions are being used by the drivers/char/ipmi/ipmi_si_intf.c driver for autodetecting the ports or memory spaces where the IPMI controllers may be found. This patch adds equivalent changes for ia64 as to what is in the x86_64 tree. In addition, I reworked the DMI detection, such that on EFI-capable systems, it uses the efi.smbios pointer to find the table, rather than brute-force searching from 0xF0000. On non-EFI systems, it continues the brute-force search. My test system, an Intel S870BN4 'Tiger4', aka Dell PowerEdge 7250, with latest BIOS, does not list the IPMI controller in the ACPI namespace, nor does it have an ACPI SPMI table. Also note, currently shipping Dell x8xx EM64T servers don't have these either, so DMI is the only method for obtaining the address of the IPMI controller. Signed-off-by: Matt Domsch <Matt_Domsch@dell.com> Acked-by: "Luck, Tony" <tony.luck@intel.com> Cc: Andi Kleen <ak@muc.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/dmi_scan.c90
1 files changed, 58 insertions, 32 deletions
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
index ebc8dc116c43..bfecbd46f22a 100644
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -3,6 +3,7 @@
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/dmi.h> 5#include <linux/dmi.h>
6#include <linux/efi.h>
6#include <linux/bootmem.h> 7#include <linux/bootmem.h>
7#include <linux/slab.h> 8#include <linux/slab.h>
8#include <asm/dmi.h> 9#include <asm/dmi.h>
@@ -185,47 +186,72 @@ static void __init dmi_decode(struct dmi_header *dm)
185 } 186 }
186} 187}
187 188
188void __init dmi_scan_machine(void) 189static int __init dmi_present(char __iomem *p)
189{ 190{
190 u8 buf[15]; 191 u8 buf[15];
191 char __iomem *p, *q; 192 memcpy_fromio(buf, p, 15);
193 if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
194 u16 num = (buf[13] << 8) | buf[12];
195 u16 len = (buf[7] << 8) | buf[6];
196 u32 base = (buf[11] << 24) | (buf[10] << 16) |
197 (buf[9] << 8) | buf[8];
192 198
193 /* 199 /*
194 * no iounmap() for that ioremap(); it would be a no-op, but it's 200 * DMI version 0.0 means that the real version is taken from
195 * so early in setup that sucker gets confused into doing what 201 * the SMBIOS version, which we don't know at this point.
196 * it shouldn't if we actually call it. 202 */
197 */ 203 if (buf[14] != 0)
198 p = ioremap(0xF0000, 0x10000); 204 printk(KERN_INFO "DMI %d.%d present.\n",
199 if (p == NULL) 205 buf[14] >> 4, buf[14] & 0xF);
200 goto out; 206 else
201 207 printk(KERN_INFO "DMI present.\n");
202 for (q = p; q < p + 0x10000; q += 16) { 208 if (dmi_table(base,len, num, dmi_decode) == 0)
203 memcpy_fromio(buf, q, 15); 209 return 0;
204 if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { 210 }
205 u16 num = (buf[13] << 8) | buf[12]; 211 return 1;
206 u16 len = (buf[7] << 8) | buf[6]; 212}
207 u32 base = (buf[11] << 24) | (buf[10] << 16) |
208 (buf[9] << 8) | buf[8];
209
210 /*
211 * DMI version 0.0 means that the real version is taken from
212 * the SMBIOS version, which we don't know at this point.
213 */
214 if (buf[14] != 0)
215 printk(KERN_INFO "DMI %d.%d present.\n",
216 buf[14] >> 4, buf[14] & 0xF);
217 else
218 printk(KERN_INFO "DMI present.\n");
219 213
220 if (dmi_table(base,len, num, dmi_decode) == 0) 214void __init dmi_scan_machine(void)
215{
216 char __iomem *p, *q;
217 int rc;
218
219 if (efi_enabled) {
220 if (!efi.smbios)
221 goto out;
222
223 /* This is called as a core_initcall() because it isn't
224 * needed during early boot. This also means we can
225 * iounmap the space when we're done with it.
226 */
227 p = dmi_ioremap((unsigned long)efi.smbios, 0x10000);
228 if (p == NULL)
229 goto out;
230
231 rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
232 iounmap(p);
233 if (!rc)
234 return;
235 }
236 else {
237 /*
238 * no iounmap() for that ioremap(); it would be a no-op, but
239 * it's so early in setup that sucker gets confused into doing
240 * what it shouldn't if we actually call it.
241 */
242 p = dmi_ioremap(0xF0000, 0x10000);
243 if (p == NULL)
244 goto out;
245
246 for (q = p; q < p + 0x10000; q += 16) {
247 rc = dmi_present(q);
248 if (!rc)
221 return; 249 return;
222 } 250 }
223 } 251 }
224 252 out: printk(KERN_INFO "DMI not present or invalid.\n");
225out: printk(KERN_INFO "DMI not present or invalid.\n");
226} 253}
227 254
228
229/** 255/**
230 * dmi_check_system - check system DMI data 256 * dmi_check_system - check system DMI data
231 * @list: array of dmi_system_id structures to match against 257 * @list: array of dmi_system_id structures to match against