|
@@ -43,18 +43,12 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s)
|
|
|
* We have to be cautious here. We have seen BIOSes with DMI pointers
|
|
|
* pointing to completely the wrong place for example
|
|
|
*/
|
|
|
-static int __init dmi_table(u32 base, int len, int num,
|
|
|
- void (*decode)(const struct dmi_header *))
|
|
|
+static void dmi_table(u8 *buf, int len, int num,
|
|
|
+ void (*decode)(const struct dmi_header *))
|
|
|
{
|
|
|
- u8 *buf, *data;
|
|
|
+ u8 *data = buf;
|
|
|
int i = 0;
|
|
|
|
|
|
- buf = dmi_ioremap(base, len);
|
|
|
- if (buf == NULL)
|
|
|
- return -1;
|
|
|
-
|
|
|
- data = buf;
|
|
|
-
|
|
|
/*
|
|
|
* Stop when we see all the items the table claimed to have
|
|
|
* 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,
|
|
|
data += 2;
|
|
|
i++;
|
|
|
}
|
|
|
- dmi_iounmap(buf, len);
|
|
|
+}
|
|
|
+
|
|
|
+static u32 dmi_base;
|
|
|
+static u16 dmi_len;
|
|
|
+static u16 dmi_num;
|
|
|
+
|
|
|
+static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
|
|
|
+{
|
|
|
+ u8 *buf;
|
|
|
+
|
|
|
+ buf = dmi_ioremap(dmi_base, dmi_len);
|
|
|
+ if (buf == NULL)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ dmi_table(buf, dmi_len, dmi_num, decode);
|
|
|
+
|
|
|
+ dmi_iounmap(buf, dmi_len);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -291,9 +301,9 @@ static int __init dmi_present(const char __iomem *p)
|
|
|
|
|
|
memcpy_fromio(buf, p, 15);
|
|
|
if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
|
|
|
- u16 num = (buf[13] << 8) | buf[12];
|
|
|
- u16 len = (buf[7] << 8) | buf[6];
|
|
|
- u32 base = (buf[11] << 24) | (buf[10] << 16) |
|
|
|
+ dmi_num = (buf[13] << 8) | buf[12];
|
|
|
+ dmi_len = (buf[7] << 8) | buf[6];
|
|
|
+ dmi_base = (buf[11] << 24) | (buf[10] << 16) |
|
|
|
(buf[9] << 8) | buf[8];
|
|
|
|
|
|
/*
|
|
@@ -305,7 +315,7 @@ static int __init dmi_present(const char __iomem *p)
|
|
|
buf[14] >> 4, buf[14] & 0xF);
|
|
|
else
|
|
|
printk(KERN_INFO "DMI present.\n");
|
|
|
- if (dmi_table(base,len, num, dmi_decode) == 0)
|
|
|
+ if (dmi_walk_early(dmi_decode) == 0)
|
|
|
return 0;
|
|
|
}
|
|
|
return 1;
|
|
@@ -489,3 +499,27 @@ int dmi_get_year(int field)
|
|
|
|
|
|
return year;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * dmi_walk - Walk the DMI table and get called back for every record
|
|
|
+ * @decode: Callback function
|
|
|
+ *
|
|
|
+ * Returns -1 when the DMI table can't be reached, 0 on success.
|
|
|
+ */
|
|
|
+int dmi_walk(void (*decode)(const struct dmi_header *))
|
|
|
+{
|
|
|
+ u8 *buf;
|
|
|
+
|
|
|
+ if (!dmi_available)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ buf = ioremap(dmi_base, dmi_len);
|
|
|
+ if (buf == NULL)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ dmi_table(buf, dmi_len, dmi_num, decode);
|
|
|
+
|
|
|
+ iounmap(buf);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(dmi_walk);
|