Commit efd3d374 authored by Andrey Panin's avatar Andrey Panin Committed by Linus Torvalds

[PATCH] export DMI check functions

This patch creates and exports 2 functions which can be used by the rest of
kernel code to perform DMI data checks:

- dmi_check_system() function checks system DMI data against given blacklist
  table and on each match runs corresponding callback function;

- dmi_get_system_info() function returns DMI data value.  Useful for people
  wanting more complex DMI data check than simple string match.

Also filling unused match entries with NO_MATCH made optional, but existing
NO_MATCH occurences are left intact, so people are free to continue dmi_scan.c
patching without massive reject problems.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c397fc82
......@@ -10,6 +10,7 @@
#include <asm/io.h>
#include <linux/pm.h>
#include <asm/system.h>
#include <linux/dmi.h>
#include <linux/bootmem.h>
unsigned long dmi_broken;
......@@ -139,21 +140,6 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
return -1;
}
enum
{
DMI_BIOS_VENDOR,
DMI_BIOS_VERSION,
DMI_BIOS_DATE,
DMI_SYS_VENDOR,
DMI_PRODUCT_NAME,
DMI_PRODUCT_VERSION,
DMI_BOARD_VENDOR,
DMI_BOARD_NAME,
DMI_BOARD_VERSION,
DMI_STRING_MAX
};
static char *dmi_ident[DMI_STRING_MAX];
/*
......@@ -176,26 +162,11 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
}
/*
* DMI callbacks for problem boards
* Ugly compatibility crap.
*/
struct dmi_strmatch
{
u8 slot;
char *substr;
};
#define NONE 255
struct dmi_blacklist
{
int (*callback)(struct dmi_blacklist *);
char *ident;
struct dmi_strmatch matches[4];
};
#define NO_MATCH { NONE, NULL}
#define MATCH(a,b) { a, b }
#define dmi_blacklist dmi_system_id
#define NO_MATCH { DMI_NONE, NULL}
#define MATCH DMI_MATCH
/*
* Reboot options and system auto-detection code provided by
......@@ -1054,9 +1025,6 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
static __init void dmi_check_blacklist(void)
{
struct dmi_blacklist *d;
int i;
#ifdef CONFIG_ACPI_BOOT
#define ACPI_BLACKLIST_CUTOFF_YEAR 2001
......@@ -1078,25 +1046,7 @@ static __init void dmi_check_blacklist(void)
}
}
#endif
d=&dmi_blacklist[0];
while(d->callback)
{
for(i=0;i<4;i++)
{
int s = d->matches[i].slot;
if(s==NONE)
continue;
if(dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
continue;
/* No match */
goto fail;
}
if(d->callback(d))
return;
fail:
d++;
}
dmi_check_system(dmi_blacklist);
}
......@@ -1163,3 +1113,52 @@ void __init dmi_scan_machine(void)
}
EXPORT_SYMBOL(is_unsafe_smbus);
/**
* dmi_check_system - check system DMI data
* @list: array of dmi_system_id structures to match against
*
* Walk the blacklist table running matching functions until someone
* returns non zero or we hit the end. Callback function is called for
* each successfull match. Returns the number of matches.
*/
int dmi_check_system(struct dmi_system_id *list)
{
int i, count = 0;
struct dmi_system_id *d = list;
while (d->ident) {
for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
int s = d->matches[i].slot;
if (s == DMI_NONE)
continue;
if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
continue;
/* No match */
goto fail;
}
if (d->callback && d->callback(d))
break;
count++;
fail: d++;
}
return count;
}
EXPORT_SYMBOL(dmi_check_system);
/**
* dmi_get_system_info - return DMI data value
* @field: data index (see enum dmi_filed)
*
* Returns one DMI data value, can be used to perform
* complex DMI data checks.
*/
char * dmi_get_system_info(int field)
{
return dmi_ident[field];
}
EXPORT_SYMBOL(dmi_get_system_info);
#ifndef __DMI_H__
#define __DMI_H__
enum dmi_field {
DMI_NONE,
DMI_BIOS_VENDOR,
DMI_BIOS_VERSION,
DMI_BIOS_DATE,
DMI_SYS_VENDOR,
DMI_PRODUCT_NAME,
DMI_PRODUCT_VERSION,
DMI_BOARD_VENDOR,
DMI_BOARD_NAME,
DMI_BOARD_VERSION,
DMI_STRING_MAX,
};
/*
* DMI callbacks for problem boards
*/
struct dmi_strmatch {
u8 slot;
char *substr;
};
struct dmi_system_id {
int (*callback)(struct dmi_system_id *);
char *ident;
struct dmi_strmatch matches[4];
void *driver_data;
};
#define DMI_MATCH(a,b) { a, b }
#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)
extern int dmi_check_system(struct dmi_system_id *list);
extern char * dmi_get_system_info(int field);
#else
static inline int dmi_check_system(struct dmi_system_id *list) { return 0; }
static inline char * dmi_get_system_info(int field) { return NULL; }
#endif
#endif /* __DMI_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment