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 | |
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>
-rw-r--r-- | drivers/firmware/dmi_scan.c | 62 | ||||
-rw-r--r-- | include/linux/dmi.h | 3 |
2 files changed, 51 insertions, 14 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e0bade73237..1412d7bcdbd 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); | ||
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index b1251b2af56..bbc9992ec37 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
@@ -79,6 +79,7 @@ extern void dmi_scan_machine(void); | |||
79 | extern int dmi_get_year(int field); | 79 | extern int dmi_get_year(int field); |
80 | extern int dmi_name_in_vendors(const char *str); | 80 | extern int dmi_name_in_vendors(const char *str); |
81 | extern int dmi_available; | 81 | extern int dmi_available; |
82 | extern int dmi_walk(void (*decode)(const struct dmi_header *)); | ||
82 | 83 | ||
83 | #else | 84 | #else |
84 | 85 | ||
@@ -89,6 +90,8 @@ static inline const struct dmi_device * dmi_find_device(int type, const char *na | |||
89 | static inline int dmi_get_year(int year) { return 0; } | 90 | static inline int dmi_get_year(int year) { return 0; } |
90 | static inline int dmi_name_in_vendors(const char *s) { return 0; } | 91 | static inline int dmi_name_in_vendors(const char *s) { return 0; } |
91 | #define dmi_available 0 | 92 | #define dmi_available 0 |
93 | static inline int dmi_walk(void (*decode)(const struct dmi_header *)) | ||
94 | { return -1; } | ||
92 | 95 | ||
93 | #endif | 96 | #endif |
94 | 97 | ||