1 #include <xen/types.h>
2 #include <xen/lib.h>
3 #include <xen/kernel.h>
4 #include <xen/string.h>
5 #include <xen/init.h>
6 #include <xen/cache.h>
7 #include <xen/acpi.h>
8 #include <asm/io.h>
9 #include <asm/system.h>
10 #include <xen/dmi.h>
11 #include <xen/efi.h>
12 #include <xen/pci.h>
13 #include <xen/pci_regs.h>
14
15 #define bt_ioremap(b,l) ((void *)__acpi_map_table(b,l))
16 #define bt_iounmap(b,l) ((void)0)
17 #define memcpy_fromio memcpy
18 #define alloc_bootmem(l) xmalloc_bytes(l)
19
20 struct __packed dmi_eps {
21 char anchor[5]; /* "_DMI_" */
22 u8 checksum;
23 u16 size;
24 u32 address;
25 u16 num_structures;
26 u8 revision;
27 };
28
29 struct __packed smbios_eps {
30 char anchor[4]; /* "_SM_" */
31 u8 checksum;
32 u8 length;
33 u8 major, minor;
34 u16 max_size;
35 u8 revision;
36 u8 _rsrvd_[5];
37 struct dmi_eps dmi;
38 };
39
40 struct __packed smbios3_eps {
41 char anchor[5]; /* "_SM3_" */
42 u8 checksum;
43 u8 length;
44 u8 major, minor;
45 u8 docrev;
46 u8 revision;
47 u8 _rsrvd_;
48 u32 max_size;
49 u64 address;
50 };
51
52 struct dmi_header
53 {
54 u8 type;
55 u8 length;
56 u16 handle;
57 };
58
59 enum dmi_entry_type {
60 DMI_ENTRY_BIOS = 0,
61 DMI_ENTRY_SYSTEM,
62 DMI_ENTRY_BASEBOARD,
63 DMI_ENTRY_CHASSIS,
64 DMI_ENTRY_PROCESSOR,
65 DMI_ENTRY_MEM_CONTROLLER,
66 DMI_ENTRY_MEM_MODULE,
67 DMI_ENTRY_CACHE,
68 DMI_ENTRY_PORT_CONNECTOR,
69 DMI_ENTRY_SYSTEM_SLOT,
70 DMI_ENTRY_ONBOARD_DEVICE,
71 DMI_ENTRY_OEMSTRINGS,
72 DMI_ENTRY_SYSCONF,
73 DMI_ENTRY_BIOS_LANG,
74 DMI_ENTRY_GROUP_ASSOC,
75 DMI_ENTRY_SYSTEM_EVENT_LOG,
76 DMI_ENTRY_PHYS_MEM_ARRAY,
77 DMI_ENTRY_MEM_DEVICE,
78 DMI_ENTRY_32_MEM_ERROR,
79 DMI_ENTRY_MEM_ARRAY_MAPPED_ADDR,
80 DMI_ENTRY_MEM_DEV_MAPPED_ADDR,
81 DMI_ENTRY_BUILTIN_POINTING_DEV,
82 DMI_ENTRY_PORTABLE_BATTERY,
83 DMI_ENTRY_SYSTEM_RESET,
84 DMI_ENTRY_HW_SECURITY,
85 DMI_ENTRY_SYSTEM_POWER_CONTROLS,
86 DMI_ENTRY_VOLTAGE_PROBE,
87 DMI_ENTRY_COOLING_DEV,
88 DMI_ENTRY_TEMP_PROBE,
89 DMI_ENTRY_ELECTRICAL_CURRENT_PROBE,
90 DMI_ENTRY_OOB_REMOTE_ACCESS,
91 DMI_ENTRY_BIS_ENTRY,
92 DMI_ENTRY_SYSTEM_BOOT,
93 DMI_ENTRY_MGMT_DEV,
94 DMI_ENTRY_MGMT_DEV_COMPONENT,
95 DMI_ENTRY_MGMT_DEV_THRES,
96 DMI_ENTRY_MEM_CHANNEL,
97 DMI_ENTRY_IPMI_DEV,
98 DMI_ENTRY_SYS_POWER_SUPPLY,
99 DMI_ENTRY_ADDITIONAL,
100 DMI_ENTRY_ONBOARD_DEV_EXT,
101 DMI_ENTRY_MGMT_CONTROLLER_HOST,
102 DMI_ENTRY_INACTIVE = 126,
103 DMI_ENTRY_END_OF_TABLE = 127,
104 };
105
106 #undef DMI_DEBUG
107
108 #ifdef DMI_DEBUG
109 #define dmi_printk(x) printk x
110 #else
111 #define dmi_printk(x)
112 #endif
113
dmi_string(struct dmi_header * dm,u8 s)114 static char * __init dmi_string(struct dmi_header *dm, u8 s)
115 {
116 char *bp=(char *)dm;
117 bp+=dm->length;
118 if(!s)
119 return "";
120 s--;
121 while(s>0 && *bp)
122 {
123 bp+=strlen(bp);
124 bp++;
125 s--;
126 }
127 return bp;
128 }
129
130 /*
131 * We have to be cautious here. We have seen BIOSes with DMI pointers
132 * pointing to completely the wrong place for example
133 */
134
dmi_table(paddr_t base,u32 len,int num,void (* decode)(struct dmi_header *))135 static int __init dmi_table(paddr_t base, u32 len, int num,
136 void (*decode)(struct dmi_header *))
137 {
138 u8 *buf;
139 struct dmi_header *dm;
140 u8 *data;
141 int i=0;
142
143 buf = bt_ioremap(base, len);
144 if(buf==NULL)
145 return -1;
146
147 data = buf;
148
149 /*
150 * Stop when we have seen all the items the table claimed to have
151 * (SMBIOS < 3.0 only) OR we reach an end-of-table marker (SMBIOS
152 * >= 3.0 only) OR we run off the end of the table (should never
153 * happen but sometimes does on bogus implementations.)
154 */
155 while((num < 0 || i < num) && data-buf+sizeof(struct dmi_header)<=len)
156 {
157 dm=(struct dmi_header *)data;
158 /*
159 * We want to know the total length (formated area and strings)
160 * before decoding to make sure we won't run off the table in
161 * dmi_decode or dmi_string
162 */
163 data+=dm->length;
164 while(data-buf<len-1 && (data[0] || data[1]))
165 data++;
166 if(data-buf<len-1)
167 decode(dm);
168 /*
169 * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0]
170 * For tables behind a 64-bit entry point, we have no item
171 * count and no exact table length, so stop on end-of-table
172 * marker. For tables behind a 32-bit entry point, we have
173 * seen OEM structures behind the end-of-table marker on
174 * some systems, so don't trust it.
175 */
176 if (num < 0 && dm->type == DMI_ENTRY_END_OF_TABLE)
177 break;
178 data+=2;
179 i++;
180 }
181 bt_iounmap(buf, len);
182 return 0;
183 }
184
185
dmi_checksum(const void __iomem * buf,unsigned int len)186 static inline bool __init dmi_checksum(const void __iomem *buf,
187 unsigned int len)
188 {
189 u8 sum = 0;
190 const u8 *p = buf;
191 unsigned int a;
192
193 for (a = 0; a < len; a++)
194 sum += p[a];
195 return sum == 0;
196 }
197
198 static u32 __initdata efi_dmi_address;
199 static u32 __initdata efi_dmi_size;
200 static u32 __initdata efi_smbios_address;
201 static u32 __initdata efi_smbios_size;
202 static u64 __initdata efi_smbios3_address;
203 static u32 __initdata efi_smbios3_size;
204
205 /*
206 * Important: This function gets called while still in EFI
207 * (pseudo-)physical mode.
208 */
dmi_efi_get_table(const void * smbios,const void * smbios3)209 void __init dmi_efi_get_table(const void *smbios, const void *smbios3)
210 {
211 const struct smbios_eps *eps = smbios;
212 const struct smbios3_eps *eps3 = smbios3;
213
214 if (eps3 && memcmp(eps3->anchor, "_SM3_", 5) == 0 &&
215 eps3->length >= sizeof(*eps3) &&
216 dmi_checksum(eps3, eps3->length)) {
217 efi_smbios3_address = eps3->address;
218 efi_smbios3_size = eps3->max_size;
219 return;
220 }
221
222 if (eps && memcmp(eps->anchor, "_SM_", 4) == 0 &&
223 eps->length >= sizeof(*eps) &&
224 dmi_checksum(eps, eps->length)) {
225 efi_smbios_address = (u32)(long)eps;
226 efi_smbios_size = eps->length;
227
228 if (memcmp(eps->dmi.anchor, "_DMI_", 5) == 0 &&
229 dmi_checksum(&eps->dmi, sizeof(eps->dmi))) {
230 efi_dmi_address = eps->dmi.address;
231 efi_dmi_size = eps->dmi.size;
232 }
233 }
234 }
235
dmi_get_table(paddr_t * base,u32 * len)236 const char *__init dmi_get_table(paddr_t *base, u32 *len)
237 {
238 static unsigned int __initdata instance;
239
240 if (efi_enabled(EFI_BOOT)) {
241 if (efi_smbios3_size && !(instance & 1)) {
242 *base = efi_smbios3_address;
243 *len = efi_smbios3_size;
244 instance |= 1;
245 return "SMBIOSv3";
246 }
247 if (efi_dmi_size && !(instance & 2)) {
248 *base = efi_dmi_address;
249 *len = efi_dmi_size;
250 instance |= 2;
251 return "DMI";
252 }
253 if (efi_smbios_size && !(instance & 4)) {
254 *base = efi_smbios_address;
255 *len = efi_smbios_size;
256 instance |= 4;
257 return "SMBIOS";
258 }
259 } else {
260 char __iomem *p = maddr_to_virt(0xF0000), *q;
261 union {
262 struct dmi_eps dmi;
263 struct smbios3_eps smbios3;
264 } eps;
265
266 for (q = p; q <= p + 0x10000 - sizeof(eps.dmi); q += 16) {
267 memcpy_fromio(&eps, q, sizeof(eps.dmi));
268 if (!(instance & 1) &&
269 memcmp(eps.dmi.anchor, "_DMI_", 5) == 0 &&
270 dmi_checksum(&eps.dmi, sizeof(eps.dmi))) {
271 *base = eps.dmi.address;
272 *len = eps.dmi.size;
273 instance |= 1;
274 return "DMI";
275 }
276
277 BUILD_BUG_ON(sizeof(eps.smbios3) <= sizeof(eps.dmi));
278 if ((instance & 2) ||
279 q > p + 0x10000 - sizeof(eps.smbios3))
280 continue;
281 memcpy_fromio(&eps.dmi + 1, q + sizeof(eps.dmi),
282 sizeof(eps.smbios3) - sizeof(eps.dmi));
283 if (!memcmp(eps.smbios3.anchor, "_SM3_", 5) &&
284 eps.smbios3.length >= sizeof(eps.smbios3) &&
285 q <= p + 0x10000 - eps.smbios3.length &&
286 dmi_checksum(q, eps.smbios3.length)) {
287 *base = eps.smbios3.address;
288 *len = eps.smbios3.max_size;
289 instance |= 2;
290 return "SMBIOSv3";
291 }
292 }
293 }
294 return NULL;
295 }
296
297 typedef union {
298 const struct smbios_eps __iomem *legacy;
299 const struct smbios3_eps __iomem *v3;
300 } smbios_eps_u __attribute__((transparent_union));
301
_dmi_iterate(const struct dmi_eps * dmi,const smbios_eps_u smbios,void (* decode)(struct dmi_header *))302 static int __init _dmi_iterate(const struct dmi_eps *dmi,
303 const smbios_eps_u smbios,
304 void (*decode)(struct dmi_header *))
305 {
306 int num;
307 u32 len;
308 paddr_t base;
309
310 if (!dmi) {
311 num = -1;
312 len = smbios.v3->max_size;
313 base = smbios.v3->address;
314 printk(KERN_INFO "SMBIOS %d.%d present.\n",
315 smbios.v3->major, smbios.v3->minor);
316 dmi_printk((KERN_INFO "SMBIOS v3 table at 0x%"PRIpaddr".\n", base));
317 } else {
318 num = dmi->num_structures;
319 len = dmi->size;
320 base = dmi->address;
321
322 /*
323 * DMI version 0.0 means that the real version is taken from
324 * the SMBIOS version, which we may not know at this point.
325 */
326 if (dmi->revision)
327 printk(KERN_INFO "DMI %d.%d present.\n",
328 dmi->revision >> 4, dmi->revision & 0x0f);
329 else if (!smbios.legacy)
330 printk(KERN_INFO "DMI present.\n");
331 dmi_printk((KERN_INFO "%d structures occupying %u bytes.\n",
332 num, len));
333 dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", (u32)base));
334 }
335 return dmi_table(base, len, num, decode);
336 }
337
dmi_iterate(void (* decode)(struct dmi_header *))338 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
339 {
340 struct dmi_eps dmi;
341 struct smbios3_eps smbios3;
342 char __iomem *p, *q;
343
344 dmi.size = 0;
345 smbios3.length = 0;
346
347 p = maddr_to_virt(0xF0000);
348 for (q = p; q < p + 0x10000; q += 16) {
349 if (!dmi.size) {
350 memcpy_fromio(&dmi, q, sizeof(dmi));
351 if (memcmp(dmi.anchor, "_DMI_", 5) ||
352 !dmi_checksum(&dmi, sizeof(dmi)))
353 dmi.size = 0;
354 }
355 if (!smbios3.length &&
356 q <= p + 0x10000 - sizeof(smbios3)) {
357 memcpy_fromio(&smbios3, q, sizeof(smbios3));
358 if (memcmp(smbios3.anchor, "_SM3_", 5) ||
359 smbios3.length < sizeof(smbios3) ||
360 q > p + 0x10000 - smbios3.length ||
361 !dmi_checksum(q, smbios3.length))
362 smbios3.length = 0;
363 }
364 }
365
366 if (smbios3.length)
367 return _dmi_iterate(NULL, &smbios3, decode);
368 if (dmi.size)
369 return _dmi_iterate(&dmi, NULL, decode);
370 return -1;
371 }
372
dmi_efi_iterate(void (* decode)(struct dmi_header *))373 static int __init dmi_efi_iterate(void (*decode)(struct dmi_header *))
374 {
375 int ret = -1;
376
377 while (efi.smbios3 != EFI_INVALID_TABLE_ADDR) {
378 struct smbios3_eps eps;
379 const struct smbios3_eps __iomem *p;
380
381 p = bt_ioremap(efi.smbios3, sizeof(eps));
382 if (!p)
383 break;
384 memcpy_fromio(&eps, p, sizeof(eps));
385 bt_iounmap(p, sizeof(eps));
386
387 if (memcmp(eps.anchor, "_SM3_", 5) ||
388 eps.length < sizeof(eps))
389 break;
390
391 p = bt_ioremap(efi.smbios3, eps.length);
392 if (!p)
393 break;
394 if (dmi_checksum(p, eps.length))
395 ret = _dmi_iterate(NULL, p, decode);
396 bt_iounmap(p, eps.length);
397 break;
398 }
399
400 if (ret != 0 && efi.smbios != EFI_INVALID_TABLE_ADDR) {
401 struct smbios_eps eps;
402 const struct smbios_eps __iomem *p;
403
404 p = bt_ioremap(efi.smbios, sizeof(eps));
405 if (!p)
406 return -1;
407 memcpy_fromio(&eps, p, sizeof(eps));
408 bt_iounmap(p, sizeof(eps));
409
410 if (memcmp(eps.anchor, "_SM_", 4) ||
411 eps.length < sizeof(eps))
412 return -1;
413
414 p = bt_ioremap(efi.smbios, eps.length);
415 if (!p)
416 return -1;
417 if (dmi_checksum(p, eps.length) &&
418 memcmp(eps.dmi.anchor, "_DMI_", 5) == 0 &&
419 dmi_checksum(&eps.dmi, sizeof(eps.dmi))) {
420 printk(KERN_INFO "SMBIOS %d.%d present.\n",
421 eps.major, eps.minor);
422 ret = _dmi_iterate(&eps.dmi, p, decode);
423 }
424 bt_iounmap(p, eps.length);
425 }
426
427 return ret;
428 }
429
430 static char *__initdata dmi_ident[DMI_STRING_MAX];
431
432 /*
433 * Save a DMI string
434 */
435
dmi_save_ident(struct dmi_header * dm,int slot,int string)436 static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
437 {
438 char *d = (char*)dm;
439 char *p = dmi_string(dm, d[string]);
440 if(p==NULL || *p == 0)
441 return;
442 if (dmi_ident[slot])
443 return;
444 dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
445 if(dmi_ident[slot])
446 strlcpy(dmi_ident[slot], p, strlen(p)+1);
447 else
448 printk(KERN_ERR "dmi_save_ident: out of memory.\n");
449 }
450
451 /*
452 * Ugly compatibility crap.
453 */
454 #define dmi_blacklist dmi_system_id
455 #define NO_MATCH { DMI_NONE, NULL}
456 #define MATCH DMI_MATCH
457
ich10_bios_quirk(const struct dmi_system_id * d)458 static int __init ich10_bios_quirk(const struct dmi_system_id *d)
459 {
460 u32 port, smictl;
461
462 if ( pci_conf_read16(PCI_SBDF(0, 0, 0x1f, 0), PCI_VENDOR_ID) != 0x8086 )
463 return 0;
464
465 switch ( pci_conf_read16(PCI_SBDF(0, 0, 0x1f, 0), PCI_DEVICE_ID) ) {
466 case 0x3a14:
467 case 0x3a16:
468 case 0x3a18:
469 case 0x3a1a:
470 port = (pci_conf_read16(PCI_SBDF(0, 0, 0x1f, 0), 0x40) & 0xff80) + 0x30;
471 smictl = inl(port);
472 /* turn off LEGACY_USB{,2}_EN if enabled */
473 if ( smictl & 0x20008 )
474 outl(smictl & ~0x20008, port);
475 break;
476 }
477
478 return 0;
479 }
480
reset_videomode_after_s3(const struct dmi_blacklist * d)481 static __init int reset_videomode_after_s3(const struct dmi_blacklist *d)
482 {
483 /* See wakeup.S */
484 acpi_video_flags |= 2;
485 return 0;
486 }
487
dmi_disable_acpi(const struct dmi_blacklist * d)488 static __init int dmi_disable_acpi(const struct dmi_blacklist *d)
489 {
490 if (!acpi_force) {
491 printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
492 disable_acpi();
493 } else {
494 printk(KERN_NOTICE
495 "Warning: DMI blacklist says broken, but acpi forced\n");
496 }
497 return 0;
498 }
499
500 /*
501 * Limit ACPI to CPU enumeration for HT
502 */
force_acpi_ht(const struct dmi_blacklist * d)503 static __init int force_acpi_ht(const struct dmi_blacklist *d)
504 {
505 if (!acpi_force) {
506 printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
507 disable_acpi();
508 acpi_ht = 1;
509 } else {
510 printk(KERN_NOTICE
511 "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
512 }
513 return 0;
514 }
515
516 /*
517 * Process the DMI blacklists
518 */
519
520
521 /*
522 * This will be expanded over time to force things like the APM
523 * interrupt mask settings according to the laptop
524 */
525
526 static const struct dmi_blacklist __initconstrel dmi_blacklist[] = {
527
528 { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
529 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
530 NO_MATCH, NO_MATCH, NO_MATCH
531 } },
532
533 { ich10_bios_quirk, "Intel board & BIOS",
534 /*
535 * BIOS leaves legacy USB emulation enabled while
536 * SMM can't properly handle it.
537 */
538 {
539 MATCH(DMI_BOARD_VENDOR, "Intel Corp"),
540 MATCH(DMI_BIOS_VENDOR, "Intel Corp"),
541 NO_MATCH, NO_MATCH
542 }
543 },
544
545 /*
546 * If your system is blacklisted here, but you find that acpi=force
547 * works for you, please contact acpi-devel@sourceforge.net
548 */
549
550 /*
551 * Boxes that need ACPI disabled
552 */
553
554 { dmi_disable_acpi, "IBM Thinkpad", {
555 MATCH(DMI_BOARD_VENDOR, "IBM"),
556 MATCH(DMI_BOARD_NAME, "2629H1G"),
557 NO_MATCH, NO_MATCH }},
558
559 /*
560 * Boxes that need acpi=ht
561 */
562
563 { force_acpi_ht, "FSC Primergy T850", {
564 MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
565 MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
566 NO_MATCH, NO_MATCH }},
567
568 { force_acpi_ht, "DELL GX240", {
569 MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
570 MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
571 NO_MATCH, NO_MATCH }},
572
573 { force_acpi_ht, "HP VISUALIZE NT Workstation", {
574 MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
575 MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
576 NO_MATCH, NO_MATCH }},
577
578 { force_acpi_ht, "Compaq Workstation W8000", {
579 MATCH(DMI_SYS_VENDOR, "Compaq"),
580 MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
581 NO_MATCH, NO_MATCH }},
582
583 { force_acpi_ht, "ASUS P4B266", {
584 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
585 MATCH(DMI_BOARD_NAME, "P4B266"),
586 NO_MATCH, NO_MATCH }},
587
588 { force_acpi_ht, "ASUS P2B-DS", {
589 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
590 MATCH(DMI_BOARD_NAME, "P2B-DS"),
591 NO_MATCH, NO_MATCH }},
592
593 { force_acpi_ht, "ASUS CUR-DLS", {
594 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
595 MATCH(DMI_BOARD_NAME, "CUR-DLS"),
596 NO_MATCH, NO_MATCH }},
597
598 { force_acpi_ht, "ABIT i440BX-W83977", {
599 MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
600 MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
601 NO_MATCH, NO_MATCH }},
602
603 { force_acpi_ht, "IBM Bladecenter", {
604 MATCH(DMI_BOARD_VENDOR, "IBM"),
605 MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
606 NO_MATCH, NO_MATCH }},
607
608 { force_acpi_ht, "IBM eServer xSeries 360", {
609 MATCH(DMI_BOARD_VENDOR, "IBM"),
610 MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
611 NO_MATCH, NO_MATCH }},
612
613 { force_acpi_ht, "IBM eserver xSeries 330", {
614 MATCH(DMI_BOARD_VENDOR, "IBM"),
615 MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
616 NO_MATCH, NO_MATCH }},
617
618 { force_acpi_ht, "IBM eserver xSeries 440", {
619 MATCH(DMI_BOARD_VENDOR, "IBM"),
620 MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
621 NO_MATCH, NO_MATCH }},
622
623 { NULL, }
624 };
625
626 /*
627 * Process a DMI table entry. Right now all we care about are the BIOS
628 * and machine entries. For 2.5 we should pull the smbus controller info
629 * out of here.
630 */
631
dmi_decode(struct dmi_header * dm)632 static void __init dmi_decode(struct dmi_header *dm)
633 {
634 #ifdef DMI_DEBUG
635 u8 *data = (u8 *)dm;
636 #endif
637
638 switch(dm->type)
639 {
640 case DMI_ENTRY_BIOS:
641 dmi_printk(("BIOS Vendor: %s\n",
642 dmi_string(dm, data[4])));
643 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
644 dmi_printk(("BIOS Version: %s\n",
645 dmi_string(dm, data[5])));
646 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
647 dmi_printk(("BIOS Release: %s\n",
648 dmi_string(dm, data[8])));
649 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
650 break;
651 case DMI_ENTRY_SYSTEM:
652 dmi_printk(("System Vendor: %s\n",
653 dmi_string(dm, data[4])));
654 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
655 dmi_printk(("Product Name: %s\n",
656 dmi_string(dm, data[5])));
657 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
658 dmi_printk(("Version: %s\n",
659 dmi_string(dm, data[6])));
660 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
661 dmi_printk(("Serial Number: %s\n",
662 dmi_string(dm, data[7])));
663 break;
664 case DMI_ENTRY_BASEBOARD:
665 dmi_printk(("Board Vendor: %s\n",
666 dmi_string(dm, data[4])));
667 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
668 dmi_printk(("Board Name: %s\n",
669 dmi_string(dm, data[5])));
670 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
671 dmi_printk(("Board Version: %s\n",
672 dmi_string(dm, data[6])));
673 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
674 break;
675 }
676 }
677
dmi_scan_machine(void)678 void __init dmi_scan_machine(void)
679 {
680 if ((!efi_enabled(EFI_BOOT) ? dmi_iterate(dmi_decode) :
681 dmi_efi_iterate(dmi_decode)) == 0)
682 dmi_check_system(dmi_blacklist);
683 else
684 printk(KERN_INFO "DMI not present.\n");
685 }
686
687
688 /**
689 * dmi_check_system - check system DMI data
690 * @list: array of dmi_system_id structures to match against
691 *
692 * Walk the blacklist table running matching functions until someone
693 * returns non zero or we hit the end. Callback function is called for
694 * each successfull match. Returns the number of matches.
695 */
dmi_check_system(const struct dmi_system_id * list)696 int __init dmi_check_system(const struct dmi_system_id *list)
697 {
698 int i, count = 0;
699 const struct dmi_system_id *d = list;
700
701 while (d->ident) {
702 for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
703 int s = d->matches[i].slot;
704 if (s == DMI_NONE)
705 continue;
706 if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
707 continue;
708 /* No match */
709 goto fail;
710 }
711 if (d->callback && d->callback(d))
712 break;
713 count++;
714 fail: d++;
715 }
716
717 return count;
718 }
719
720 /**
721 * dmi_get_date - parse a DMI date
722 * @field: data index (see enum dmi_field)
723 * @yearp: optional out parameter for the year
724 * @monthp: optional out parameter for the month
725 * @dayp: optional out parameter for the day
726 *
727 * The date field is assumed to be in the form resembling
728 * [mm[/dd]]/yy[yy] and the result is stored in the out
729 * parameters any or all of which can be omitted.
730 *
731 * If the field doesn't exist, all out parameters are set to zero
732 * and false is returned. Otherwise, true is returned with any
733 * invalid part of date set to zero.
734 *
735 * On return, year, month and day are guaranteed to be in the
736 * range of [0,9999], [0,12] and [0,31] respectively.
737 */
dmi_get_date(int field,int * yearp,int * monthp,int * dayp)738 bool __init dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
739 {
740 int year = 0, month = 0, day = 0;
741 bool exists;
742 const char *s, *e, *y;
743
744 s = field < DMI_STRING_MAX ? dmi_ident[field] : NULL;
745 exists = !!s;
746 if (!exists)
747 goto out;
748
749 /*
750 * Determine year first. We assume the date string resembles
751 * mm/dd/yy[yy] but the original code extracted only the year
752 * from the end. Keep the behavior in the spirit of no
753 * surprises.
754 */
755 y = strrchr(s, '/');
756 if (!y)
757 goto out;
758
759 y++;
760 year = simple_strtoul(y, &e, 10);
761 if (y != e && year < 100) { /* 2-digit year */
762 year += 1900;
763 if (year < 1996) /* no dates < spec 1.0 */
764 year += 100;
765 }
766 if (year > 9999) /* year should fit in %04d */
767 year = 0;
768
769 /* parse the mm and dd */
770 month = simple_strtoul(s, &e, 10);
771 if (s == e || *e != '/' || !month || month > 12) {
772 month = 0;
773 goto out;
774 }
775
776 s = e + 1;
777 day = simple_strtoul(s, &e, 10);
778 if (s == y || s == e || *e != '/' || day > 31)
779 day = 0;
780 out:
781 if (yearp)
782 *yearp = year;
783 if (monthp)
784 *monthp = month;
785 if (dayp)
786 *dayp = day;
787 return exists;
788 }
789
dmi_end_boot(void)790 void __init dmi_end_boot(void)
791 {
792 unsigned int i;
793
794 for ( i = 0; i < DMI_STRING_MAX; ++i )
795 xfree(dmi_ident[i]);
796 }
797