aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/dmi.h41
-rw-r--r--include/linux/mod_devicetable.h47
-rw-r--r--scripts/mod/file2alias.c57
3 files changed, 106 insertions, 39 deletions
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 2a063b64133f..e5084eb5943a 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -2,29 +2,9 @@
2#define __DMI_H__ 2#define __DMI_H__
3 3
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/mod_devicetable.h>
5 6
6enum dmi_field { 7/* enum dmi_field is in mod_devicetable.h */
7 DMI_NONE,
8 DMI_BIOS_VENDOR,
9 DMI_BIOS_VERSION,
10 DMI_BIOS_DATE,
11 DMI_SYS_VENDOR,
12 DMI_PRODUCT_NAME,
13 DMI_PRODUCT_VERSION,
14 DMI_PRODUCT_SERIAL,
15 DMI_PRODUCT_UUID,
16 DMI_BOARD_VENDOR,
17 DMI_BOARD_NAME,
18 DMI_BOARD_VERSION,
19 DMI_BOARD_SERIAL,
20 DMI_BOARD_ASSET_TAG,
21 DMI_CHASSIS_VENDOR,
22 DMI_CHASSIS_TYPE,
23 DMI_CHASSIS_VERSION,
24 DMI_CHASSIS_SERIAL,
25 DMI_CHASSIS_ASSET_TAG,
26 DMI_STRING_MAX,
27};
28 8
29enum dmi_device_type { 9enum dmi_device_type {
30 DMI_DEV_TYPE_ANY = 0, 10 DMI_DEV_TYPE_ANY = 0,
@@ -48,23 +28,6 @@ struct dmi_header {
48 u16 handle; 28 u16 handle;
49}; 29};
50 30
51/*
52 * DMI callbacks for problem boards
53 */
54struct dmi_strmatch {
55 u8 slot;
56 char *substr;
57};
58
59struct dmi_system_id {
60 int (*callback)(const struct dmi_system_id *);
61 const char *ident;
62 struct dmi_strmatch matches[4];
63 void *driver_data;
64};
65
66#define DMI_MATCH(a, b) { a, b }
67
68struct dmi_device { 31struct dmi_device {
69 struct list_head list; 32 struct list_head list;
70 int type; 33 int type;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index c4db5827963d..3481a7d5bc0a 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -388,5 +388,52 @@ struct i2c_device_id {
388 __attribute__((aligned(sizeof(kernel_ulong_t)))); 388 __attribute__((aligned(sizeof(kernel_ulong_t))));
389}; 389};
390 390
391/* dmi */
392enum dmi_field {
393 DMI_NONE,
394 DMI_BIOS_VENDOR,
395 DMI_BIOS_VERSION,
396 DMI_BIOS_DATE,
397 DMI_SYS_VENDOR,
398 DMI_PRODUCT_NAME,
399 DMI_PRODUCT_VERSION,
400 DMI_PRODUCT_SERIAL,
401 DMI_PRODUCT_UUID,
402 DMI_BOARD_VENDOR,
403 DMI_BOARD_NAME,
404 DMI_BOARD_VERSION,
405 DMI_BOARD_SERIAL,
406 DMI_BOARD_ASSET_TAG,
407 DMI_CHASSIS_VENDOR,
408 DMI_CHASSIS_TYPE,
409 DMI_CHASSIS_VERSION,
410 DMI_CHASSIS_SERIAL,
411 DMI_CHASSIS_ASSET_TAG,
412 DMI_STRING_MAX,
413};
414
415struct dmi_strmatch {
416 unsigned char slot;
417 char substr[79];
418};
419
420#ifndef __KERNEL__
421struct dmi_system_id {
422 kernel_ulong_t callback;
423 kernel_ulong_t ident;
424 struct dmi_strmatch matches[4];
425 kernel_ulong_t driver_data
426 __attribute__((aligned(sizeof(kernel_ulong_t))));
427};
428#else
429struct dmi_system_id {
430 int (*callback)(const struct dmi_system_id *);
431 const char *ident;
432 struct dmi_strmatch matches[4];
433 void *driver_data;
434};
435#endif
436
437#define DMI_MATCH(a, b) { a, b }
391 438
392#endif /* LINUX_MOD_DEVICETABLE_H */ 439#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 4c9890ec2528..473f94e56ead 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -629,6 +629,59 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
629 return 1; 629 return 1;
630} 630}
631 631
632static const struct dmifield {
633 const char *prefix;
634 int field;
635} dmi_fields[] = {
636 { "bvn", DMI_BIOS_VENDOR },
637 { "bvr", DMI_BIOS_VERSION },
638 { "bd", DMI_BIOS_DATE },
639 { "svn", DMI_SYS_VENDOR },
640 { "pn", DMI_PRODUCT_NAME },
641 { "pvr", DMI_PRODUCT_VERSION },
642 { "rvn", DMI_BOARD_VENDOR },
643 { "rn", DMI_BOARD_NAME },
644 { "rvr", DMI_BOARD_VERSION },
645 { "cvn", DMI_CHASSIS_VENDOR },
646 { "ct", DMI_CHASSIS_TYPE },
647 { "cvr", DMI_CHASSIS_VERSION },
648 { NULL, DMI_NONE }
649};
650
651static void dmi_ascii_filter(char *d, const char *s)
652{
653 /* Filter out characters we don't want to see in the modalias string */
654 for (; *s; s++)
655 if (*s > ' ' && *s < 127 && *s != ':')
656 *(d++) = *s;
657
658 *d = 0;
659}
660
661
662static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
663 char *alias)
664{
665 int i, j;
666
667 sprintf(alias, "dmi*");
668
669 for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) {
670 for (j = 0; j < 4; j++) {
671 if (id->matches[j].slot &&
672 id->matches[j].slot == dmi_fields[i].field) {
673 sprintf(alias + strlen(alias), ":%s*",
674 dmi_fields[i].prefix);
675 dmi_ascii_filter(alias + strlen(alias),
676 id->matches[j].substr);
677 strcat(alias, "*");
678 }
679 }
680 }
681
682 strcat(alias, ":");
683 return 1;
684}
632/* Ignore any prefix, eg. some architectures prepend _ */ 685/* Ignore any prefix, eg. some architectures prepend _ */
633static inline int sym_is(const char *symbol, const char *name) 686static inline int sym_is(const char *symbol, const char *name)
634{ 687{
@@ -760,6 +813,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
760 do_table(symval, sym->st_size, 813 do_table(symval, sym->st_size,
761 sizeof(struct i2c_device_id), "i2c", 814 sizeof(struct i2c_device_id), "i2c",
762 do_i2c_entry, mod); 815 do_i2c_entry, mod);
816 else if (sym_is(symname, "__mod_dmi_device_table"))
817 do_table(symval, sym->st_size,
818 sizeof(struct dmi_system_id), "dmi",
819 do_dmi_entry, mod);
763 free(zeros); 820 free(zeros);
764} 821}
765 822