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 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); | ||
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index b1251b2af568..bbc9992ec374 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 | ||
