]> err.no Git - linux-2.6/blob - arch/i386/kernel/dmi_scan.c
[PATCH] dmi: make dmi_string() behave like strdup()
[linux-2.6] / arch / i386 / kernel / dmi_scan.c
1 #include <linux/types.h>
2 #include <linux/string.h>
3 #include <linux/init.h>
4 #include <linux/module.h>
5 #include <linux/dmi.h>
6 #include <linux/bootmem.h>
7
8
9 struct dmi_header {
10         u8 type;
11         u8 length;
12         u16 handle;
13 };
14
15
16 static char * __init dmi_string(struct dmi_header *dm, u8 s)
17 {
18         u8 *bp = ((u8 *) dm) + dm->length;
19         char *str = "";
20
21         if (s) {
22                 s--;
23                 while (s > 0 && *bp) {
24                         bp += strlen(bp) + 1;
25                         s--;
26                 }
27
28                 if (*bp != 0) {
29                         str = alloc_bootmem(strlen(bp) + 1);
30                         if (str != NULL)
31                                 strcpy(str, bp);
32                         else
33                                 printk(KERN_ERR "dmi_string: out of memory.\n");
34                 }
35         }
36
37         return str;
38 }
39
40 /*
41  *      We have to be cautious here. We have seen BIOSes with DMI pointers
42  *      pointing to completely the wrong place for example
43  */
44 static int __init dmi_table(u32 base, int len, int num,
45                             void (*decode)(struct dmi_header *))
46 {
47         u8 *buf, *data;
48         int i = 0;
49                 
50         buf = bt_ioremap(base, len);
51         if (buf == NULL)
52                 return -1;
53
54         data = buf;
55
56         /*
57          *      Stop when we see all the items the table claimed to have
58          *      OR we run off the end of the table (also happens)
59          */
60         while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
61                 struct dmi_header *dm = (struct dmi_header *)data;
62                 /*
63                  *  We want to know the total length (formated area and strings)
64                  *  before decoding to make sure we won't run off the table in
65                  *  dmi_decode or dmi_string
66                  */
67                 data += dm->length;
68                 while ((data - buf < len - 1) && (data[0] || data[1]))
69                         data++;
70                 if (data - buf < len - 1)
71                         decode(dm);
72                 data += 2;
73                 i++;
74         }
75         bt_iounmap(buf, len);
76         return 0;
77 }
78
79 static int __init dmi_checksum(u8 *buf)
80 {
81         u8 sum = 0;
82         int a;
83         
84         for (a = 0; a < 15; a++)
85                 sum += buf[a];
86
87         return sum == 0;
88 }
89
90 static char *dmi_ident[DMI_STRING_MAX];
91
92 /*
93  *      Save a DMI string
94  */
95 static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
96 {
97         char *p, *d = (char*) dm;
98
99         if (dmi_ident[slot])
100                 return;
101
102         p = dmi_string(dm, d[string]);
103         if (p == NULL)
104                 return;
105
106         dmi_ident[slot] = p;
107 }
108
109 /*
110  *      Process a DMI table entry. Right now all we care about are the BIOS
111  *      and machine entries. For 2.5 we should pull the smbus controller info
112  *      out of here.
113  */
114 static void __init dmi_decode(struct dmi_header *dm)
115 {
116         u8 *data __attribute__((__unused__)) = (u8 *)dm;
117         
118         switch(dm->type) {
119         case  0:
120                 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
121                 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
122                 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
123                 break;
124         case 1:
125                 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
126                 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
127                 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
128                 dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
129                 break;
130         case 2:
131                 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
132                 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
133                 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
134                 break;
135         }
136 }
137
138 void __init dmi_scan_machine(void)
139 {
140         u8 buf[15];
141         char __iomem *p, *q;
142
143         /*
144          * no iounmap() for that ioremap(); it would be a no-op, but it's
145          * so early in setup that sucker gets confused into doing what
146          * it shouldn't if we actually call it.
147          */
148         p = ioremap(0xF0000, 0x10000);
149         if (p == NULL)
150                 goto out;
151
152         for (q = p; q < p + 0x10000; q += 16) {
153                 memcpy_fromio(buf, q, 15);
154                 if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
155                         u16 num = (buf[13] << 8) | buf[12];
156                         u16 len = (buf[7] << 8) | buf[6];
157                         u32 base = (buf[11] << 24) | (buf[10] << 16) |
158                                    (buf[9] << 8) | buf[8];
159
160                         /*
161                          * DMI version 0.0 means that the real version is taken from
162                          * the SMBIOS version, which we don't know at this point.
163                          */
164                         if (buf[14] != 0)
165                                 printk(KERN_INFO "DMI %d.%d present.\n",
166                                         buf[14] >> 4, buf[14] & 0xF);
167                         else
168                                 printk(KERN_INFO "DMI present.\n");
169
170                         if (dmi_table(base,len, num, dmi_decode) == 0)
171                                 return;
172                 }
173         }
174
175 out:    printk(KERN_INFO "DMI not present.\n");
176 }
177
178
179 /**
180  *      dmi_check_system - check system DMI data
181  *      @list: array of dmi_system_id structures to match against
182  *
183  *      Walk the blacklist table running matching functions until someone
184  *      returns non zero or we hit the end. Callback function is called for
185  *      each successfull match. Returns the number of matches.
186  */
187 int dmi_check_system(struct dmi_system_id *list)
188 {
189         int i, count = 0;
190         struct dmi_system_id *d = list;
191
192         while (d->ident) {
193                 for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
194                         int s = d->matches[i].slot;
195                         if (s == DMI_NONE)
196                                 continue;
197                         if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
198                                 continue;
199                         /* No match */
200                         goto fail;
201                 }
202                 if (d->callback && d->callback(d))
203                         break;
204                 count++;
205 fail:           d++;
206         }
207
208         return count;
209 }
210 EXPORT_SYMBOL(dmi_check_system);
211
212 /**
213  *      dmi_get_system_info - return DMI data value
214  *      @field: data index (see enum dmi_filed)
215  *
216  *      Returns one DMI data value, can be used to perform
217  *      complex DMI data checks.
218  */
219 char *dmi_get_system_info(int field)
220 {
221         return dmi_ident[field];
222 }
223 EXPORT_SYMBOL(dmi_get_system_info);