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>
This commit is contained in:
parent
df922075f2
commit
7fce084a0b
|
@ -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);
|
||||
|
|
|
@ -79,6 +79,7 @@ extern void dmi_scan_machine(void);
|
|||
extern int dmi_get_year(int field);
|
||||
extern int dmi_name_in_vendors(const char *str);
|
||||
extern int dmi_available;
|
||||
extern int dmi_walk(void (*decode)(const struct dmi_header *));
|
||||
|
||||
#else
|
||||
|
||||
|
@ -89,6 +90,8 @@ static inline const struct dmi_device * dmi_find_device(int type, const char *na
|
|||
static inline int dmi_get_year(int year) { return 0; }
|
||||
static inline int dmi_name_in_vendors(const char *s) { return 0; }
|
||||
#define dmi_available 0
|
||||
static inline int dmi_walk(void (*decode)(const struct dmi_header *))
|
||||
{ return -1; }
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue