diff options
author | Jean Delvare <khali@linux-fr.org> | 2007-11-03 12:29:20 -0400 |
---|---|---|
committer | Mark M. Hoffman <mhoffman@lightlink.com> | 2008-02-07 20:39:40 -0500 |
commit | 7fce084a0b3e2bb8caef919f8f36065953655bb5 (patch) | |
tree | a5bf95b6321ec488dc8a0667b652bb50479a32da /drivers/firmware | |
parent | df922075f2a55b1ae71a6fe589c1cc1b91381f4f (diff) |
dmi: Let drivers walk the DMI table
Let drivers walk the DMI table for their own needs. Some drivers need
data stored in OEM-specific DMI records for proper operation.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/dmi_scan.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e0bade732376..1412d7bcdbd1 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -43,18 +43,12 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s) | |||
43 | * We have to be cautious here. We have seen BIOSes with DMI pointers | 43 | * We have to be cautious here. We have seen BIOSes with DMI pointers |
44 | * pointing to completely the wrong place for example | 44 | * pointing to completely the wrong place for example |
45 | */ | 45 | */ |
46 | static int __init dmi_table(u32 base, int len, int num, | 46 | static void dmi_table(u8 *buf, int len, int num, |
47 | void (*decode)(const struct dmi_header *)) | 47 | void (*decode)(const struct dmi_header *)) |
48 | { | 48 | { |
49 | u8 *buf, *data; | 49 | u8 *data = buf; |
50 | int i = 0; | 50 | int i = 0; |
51 | 51 | ||
52 | buf = dmi_ioremap(base, len); | ||
53 | if (buf == NULL) | ||
54 | return -1; | ||
55 | |||
56 | data = buf; | ||
57 | |||
58 | /* | 52 | /* |
59 | * Stop when we see all the items the table claimed to have | 53 | * Stop when we see all the items the table claimed to have |
60 | * OR we run off the end of the table (also happens) | 54 | * OR we run off the end of the table (also happens) |
@@ -75,7 +69,23 @@ static int __init dmi_table(u32 base, int len, int num, | |||
75 | data += 2; | 69 | data += 2; |
76 | i++; | 70 | i++; |
77 | } | 71 | } |
78 | dmi_iounmap(buf, len); | 72 | } |
73 | |||
74 | static u32 dmi_base; | ||
75 | static u16 dmi_len; | ||
76 | static u16 dmi_num; | ||
77 | |||
78 | static int __init dmi_walk_early(void (*decode)(const struct dmi_header *)) | ||
79 | { | ||
80 | u8 *buf; | ||
81 | |||
82 | buf = dmi_ioremap(dmi_base, dmi_len); | ||
83 | if (buf == NULL) | ||
84 | return -1; | ||
85 | |||
86 | dmi_table(buf, dmi_len, dmi_num, decode); | ||
87 | |||
88 | dmi_iounmap(buf, dmi_len); | ||
79 | return 0; | 89 | return 0; |
80 | } | 90 | } |
81 | 91 | ||
@@ -291,9 +301,9 @@ static int __init dmi_present(const char __iomem *p) | |||
291 | 301 | ||
292 | memcpy_fromio(buf, p, 15); | 302 | memcpy_fromio(buf, p, 15); |
293 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | 303 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { |
294 | u16 num = (buf[13] << 8) | buf[12]; | 304 | dmi_num = (buf[13] << 8) | buf[12]; |
295 | u16 len = (buf[7] << 8) | buf[6]; | 305 | dmi_len = (buf[7] << 8) | buf[6]; |
296 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | 306 | dmi_base = (buf[11] << 24) | (buf[10] << 16) | |
297 | (buf[9] << 8) | buf[8]; | 307 | (buf[9] << 8) | buf[8]; |
298 | 308 | ||
299 | /* | 309 | /* |
@@ -305,7 +315,7 @@ static int __init dmi_present(const char __iomem *p) | |||
305 | buf[14] >> 4, buf[14] & 0xF); | 315 | buf[14] >> 4, buf[14] & 0xF); |
306 | else | 316 | else |
307 | printk(KERN_INFO "DMI present.\n"); | 317 | printk(KERN_INFO "DMI present.\n"); |
308 | if (dmi_table(base,len, num, dmi_decode) == 0) | 318 | if (dmi_walk_early(dmi_decode) == 0) |
309 | return 0; | 319 | return 0; |
310 | } | 320 | } |
311 | return 1; | 321 | return 1; |
@@ -489,3 +499,27 @@ int dmi_get_year(int field) | |||
489 | 499 | ||
490 | return year; | 500 | return year; |
491 | } | 501 | } |
502 | |||
503 | /** | ||
504 | * dmi_walk - Walk the DMI table and get called back for every record | ||
505 | * @decode: Callback function | ||
506 | * | ||
507 | * Returns -1 when the DMI table can't be reached, 0 on success. | ||
508 | */ | ||
509 | int dmi_walk(void (*decode)(const struct dmi_header *)) | ||
510 | { | ||
511 | u8 *buf; | ||
512 | |||
513 | if (!dmi_available) | ||
514 | return -1; | ||
515 | |||
516 | buf = ioremap(dmi_base, dmi_len); | ||
517 | if (buf == NULL) | ||
518 | return -1; | ||
519 | |||
520 | dmi_table(buf, dmi_len, dmi_num, decode); | ||
521 | |||
522 | iounmap(buf); | ||
523 | return 0; | ||
524 | } | ||
525 | EXPORT_SYMBOL_GPL(dmi_walk); | ||