aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-11-03 12:29:20 -0400
committerMark M. Hoffman <mhoffman@lightlink.com>2008-02-07 20:39:40 -0500
commit7fce084a0b3e2bb8caef919f8f36065953655bb5 (patch)
treea5bf95b6321ec488dc8a0667b652bb50479a32da /drivers/firmware
parentdf922075f2a55b1ae71a6fe589c1cc1b91381f4f (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.c62
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 */
46static int __init dmi_table(u32 base, int len, int num, 46static 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
74static u32 dmi_base;
75static u16 dmi_len;
76static u16 dmi_num;
77
78static 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 */
509int 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}
525EXPORT_SYMBOL_GPL(dmi_walk);