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
458 /*
459 * Toshiba keyboard likes to repeat keys when they are not repeated.
460 */
461
broken_toshiba_keyboard(struct dmi_blacklist * d)462 static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
463 {
464 printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
465 return 0;
466 }
467
ich10_bios_quirk(struct dmi_system_id * d)468 static int __init ich10_bios_quirk(struct dmi_system_id *d)
469 {
470 u32 port, smictl;
471
472 if ( pci_conf_read16(0, 0, 0x1f, 0, PCI_VENDOR_ID) != 0x8086 )
473 return 0;
474
475 switch ( pci_conf_read16(0, 0, 0x1f, 0, PCI_DEVICE_ID) ) {
476 case 0x3a14:
477 case 0x3a16:
478 case 0x3a18:
479 case 0x3a1a:
480 port = (pci_conf_read16(0, 0, 0x1f, 0, 0x40) & 0xff80) + 0x30;
481 smictl = inl(port);
482 /* turn off LEGACY_USB{,2}_EN if enabled */
483 if ( smictl & 0x20008 )
484 outl(smictl & ~0x20008, port);
485 break;
486 }
487
488 return 0;
489 }
490
491 #ifdef CONFIG_ACPI_SLEEP
reset_videomode_after_s3(struct dmi_blacklist * d)492 static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
493 {
494 /* See acpi_wakeup.S */
495 acpi_video_flags |= 2;
496 return 0;
497 }
498 #endif
499
dmi_disable_acpi(struct dmi_blacklist * d)500 static __init int dmi_disable_acpi(struct dmi_blacklist *d)
501 {
502 if (!acpi_force) {
503 printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
504 disable_acpi();
505 } else {
506 printk(KERN_NOTICE
507 "Warning: DMI blacklist says broken, but acpi forced\n");
508 }
509 return 0;
510 }
511
512 /*
513 * Limit ACPI to CPU enumeration for HT
514 */
force_acpi_ht(struct dmi_blacklist * d)515 static __init int force_acpi_ht(struct dmi_blacklist *d)
516 {
517 if (!acpi_force) {
518 printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
519 disable_acpi();
520 acpi_ht = 1;
521 } else {
522 printk(KERN_NOTICE
523 "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
524 }
525 return 0;
526 }
527
528 /*
529 * Process the DMI blacklists
530 */
531
532
533 /*
534 * This will be expanded over time to force things like the APM
535 * interrupt mask settings according to the laptop
536 */
537
538 static __initdata struct dmi_blacklist dmi_blacklist[]={
539
540 { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
541 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
542 NO_MATCH, NO_MATCH, NO_MATCH
543 } },
544 #ifdef CONFIG_ACPI_SLEEP
545 { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
546 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
547 NO_MATCH, NO_MATCH, NO_MATCH
548 } },
549 #endif
550
551 { ich10_bios_quirk, "Intel board & BIOS",
552 /*
553 * BIOS leaves legacy USB emulation enabled while
554 * SMM can't properly handle it.
555 */
556 {
557 MATCH(DMI_BOARD_VENDOR, "Intel Corp"),
558 MATCH(DMI_BIOS_VENDOR, "Intel Corp"),
559 NO_MATCH, NO_MATCH
560 }
561 },
562
563 /*
564 * If your system is blacklisted here, but you find that acpi=force
565 * works for you, please contact acpi-devel@sourceforge.net
566 */
567
568 /*
569 * Boxes that need ACPI disabled
570 */
571
572 { dmi_disable_acpi, "IBM Thinkpad", {
573 MATCH(DMI_BOARD_VENDOR, "IBM"),
574 MATCH(DMI_BOARD_NAME, "2629H1G"),
575 NO_MATCH, NO_MATCH }},
576
577 /*
578 * Boxes that need acpi=ht
579 */
580
581 { force_acpi_ht, "FSC Primergy T850", {
582 MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
583 MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
584 NO_MATCH, NO_MATCH }},
585
586 { force_acpi_ht, "DELL GX240", {
587 MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
588 MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
589 NO_MATCH, NO_MATCH }},
590
591 { force_acpi_ht, "HP VISUALIZE NT Workstation", {
592 MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
593 MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
594 NO_MATCH, NO_MATCH }},
595
596 { force_acpi_ht, "Compaq Workstation W8000", {
597 MATCH(DMI_SYS_VENDOR, "Compaq"),
598 MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
599 NO_MATCH, NO_MATCH }},
600
601 { force_acpi_ht, "ASUS P4B266", {
602 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
603 MATCH(DMI_BOARD_NAME, "P4B266"),
604 NO_MATCH, NO_MATCH }},
605
606 { force_acpi_ht, "ASUS P2B-DS", {
607 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
608 MATCH(DMI_BOARD_NAME, "P2B-DS"),
609 NO_MATCH, NO_MATCH }},
610
611 { force_acpi_ht, "ASUS CUR-DLS", {
612 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
613 MATCH(DMI_BOARD_NAME, "CUR-DLS"),
614 NO_MATCH, NO_MATCH }},
615
616 { force_acpi_ht, "ABIT i440BX-W83977", {
617 MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
618 MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
619 NO_MATCH, NO_MATCH }},
620
621 { force_acpi_ht, "IBM Bladecenter", {
622 MATCH(DMI_BOARD_VENDOR, "IBM"),
623 MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
624 NO_MATCH, NO_MATCH }},
625
626 { force_acpi_ht, "IBM eServer xSeries 360", {
627 MATCH(DMI_BOARD_VENDOR, "IBM"),
628 MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
629 NO_MATCH, NO_MATCH }},
630
631 { force_acpi_ht, "IBM eserver xSeries 330", {
632 MATCH(DMI_BOARD_VENDOR, "IBM"),
633 MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
634 NO_MATCH, NO_MATCH }},
635
636 { force_acpi_ht, "IBM eserver xSeries 440", {
637 MATCH(DMI_BOARD_VENDOR, "IBM"),
638 MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
639 NO_MATCH, NO_MATCH }},
640
641 { NULL, }
642 };
643
644 /*
645 * Process a DMI table entry. Right now all we care about are the BIOS
646 * and machine entries. For 2.5 we should pull the smbus controller info
647 * out of here.
648 */
649
dmi_decode(struct dmi_header * dm)650 static void __init dmi_decode(struct dmi_header *dm)
651 {
652 #ifdef DMI_DEBUG
653 u8 *data = (u8 *)dm;
654 #endif
655
656 switch(dm->type)
657 {
658 case DMI_ENTRY_BIOS:
659 dmi_printk(("BIOS Vendor: %s\n",
660 dmi_string(dm, data[4])));
661 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
662 dmi_printk(("BIOS Version: %s\n",
663 dmi_string(dm, data[5])));
664 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
665 dmi_printk(("BIOS Release: %s\n",
666 dmi_string(dm, data[8])));
667 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
668 break;
669 case DMI_ENTRY_SYSTEM:
670 dmi_printk(("System Vendor: %s\n",
671 dmi_string(dm, data[4])));
672 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
673 dmi_printk(("Product Name: %s\n",
674 dmi_string(dm, data[5])));
675 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
676 dmi_printk(("Version: %s\n",
677 dmi_string(dm, data[6])));
678 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
679 dmi_printk(("Serial Number: %s\n",
680 dmi_string(dm, data[7])));
681 break;
682 case DMI_ENTRY_BASEBOARD:
683 dmi_printk(("Board Vendor: %s\n",
684 dmi_string(dm, data[4])));
685 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
686 dmi_printk(("Board Name: %s\n",
687 dmi_string(dm, data[5])));
688 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
689 dmi_printk(("Board Version: %s\n",
690 dmi_string(dm, data[6])));
691 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
692 break;
693 }
694 }
695
dmi_scan_machine(void)696 void __init dmi_scan_machine(void)
697 {
698 if ((!efi_enabled(EFI_BOOT) ? dmi_iterate(dmi_decode) :
699 dmi_efi_iterate(dmi_decode)) == 0)
700 dmi_check_system(dmi_blacklist);
701 else
702 printk(KERN_INFO "DMI not present.\n");
703 }
704
705
706 /**
707 * dmi_check_system - check system DMI data
708 * @list: array of dmi_system_id structures to match against
709 *
710 * Walk the blacklist table running matching functions until someone
711 * returns non zero or we hit the end. Callback function is called for
712 * each successfull match. Returns the number of matches.
713 */
dmi_check_system(struct dmi_system_id * list)714 int __init dmi_check_system(struct dmi_system_id *list)
715 {
716 int i, count = 0;
717 struct dmi_system_id *d = list;
718
719 while (d->ident) {
720 for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
721 int s = d->matches[i].slot;
722 if (s == DMI_NONE)
723 continue;
724 if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
725 continue;
726 /* No match */
727 goto fail;
728 }
729 if (d->callback && d->callback(d))
730 break;
731 count++;
732 fail: d++;
733 }
734
735 return count;
736 }
737
738 /**
739 * dmi_get_date - parse a DMI date
740 * @field: data index (see enum dmi_field)
741 * @yearp: optional out parameter for the year
742 * @monthp: optional out parameter for the month
743 * @dayp: optional out parameter for the day
744 *
745 * The date field is assumed to be in the form resembling
746 * [mm[/dd]]/yy[yy] and the result is stored in the out
747 * parameters any or all of which can be omitted.
748 *
749 * If the field doesn't exist, all out parameters are set to zero
750 * and false is returned. Otherwise, true is returned with any
751 * invalid part of date set to zero.
752 *
753 * On return, year, month and day are guaranteed to be in the
754 * range of [0,9999], [0,12] and [0,31] respectively.
755 */
dmi_get_date(int field,int * yearp,int * monthp,int * dayp)756 bool __init dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
757 {
758 int year = 0, month = 0, day = 0;
759 bool exists;
760 const char *s, *e, *y;
761
762 s = field < DMI_STRING_MAX ? dmi_ident[field] : NULL;
763 exists = !!s;
764 if (!exists)
765 goto out;
766
767 /*
768 * Determine year first. We assume the date string resembles
769 * mm/dd/yy[yy] but the original code extracted only the year
770 * from the end. Keep the behavior in the spirit of no
771 * surprises.
772 */
773 y = strrchr(s, '/');
774 if (!y)
775 goto out;
776
777 y++;
778 year = simple_strtoul(y, &e, 10);
779 if (y != e && year < 100) { /* 2-digit year */
780 year += 1900;
781 if (year < 1996) /* no dates < spec 1.0 */
782 year += 100;
783 }
784 if (year > 9999) /* year should fit in %04d */
785 year = 0;
786
787 /* parse the mm and dd */
788 month = simple_strtoul(s, &e, 10);
789 if (s == e || *e != '/' || !month || month > 12) {
790 month = 0;
791 goto out;
792 }
793
794 s = e + 1;
795 day = simple_strtoul(s, &e, 10);
796 if (s == y || s == e || *e != '/' || day > 31)
797 day = 0;
798 out:
799 if (yearp)
800 *yearp = year;
801 if (monthp)
802 *monthp = month;
803 if (dayp)
804 *dayp = day;
805 return exists;
806 }
807
dmi_end_boot(void)808 void __init dmi_end_boot(void)
809 {
810 unsigned int i;
811
812 for ( i = 0; i < DMI_STRING_MAX; ++i )
813 xfree(dmi_ident[i]);
814 }
815