Subversion Repositories Kolibri OS

Rev

Rev 5096 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5096 serge 1
 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
9
 
10
{
11
    return __builtin_malloc(len);
5270 serge 12
};
5096 serge 13
14
 
15
 * DMI stands for "Desktop Management Interface".  It is part
16
 * of and an antecedent to, SMBIOS, which stands for System
17
 * Management BIOS.  See further: http://www.dmtf.org/standards
18
 */
19
static const char dmi_empty_string[] = "        ";
20
21
 
22
/*
23
 * Catch too early calls to dmi_check_system():
24
 */
25
static int dmi_initialized;
26
27
 
28
static char dmi_ids_string[128];
29
30
 
31
	const char *device;
32
	const char *bank;
33
	u16 handle;
34
} *dmi_memdev;
35
static int dmi_memdev_nr;
36
37
 
38
{
39
    const u8 *bp = ((u8 *) dm) + dm->length;
40
41
 
42
        s--;
43
        while (s > 0 && *bp) {
44
            bp += strlen(bp) + 1;
45
            s--;
46
        }
47
48
 
49
            size_t len = strlen(bp)+1;
50
            size_t cmp_len = len > 8 ? 8 : len;
51
52
 
53
                return dmi_empty_string;
54
            return bp;
55
        }
56
    }
57
58
 
59
}
60
61
 
62
{
63
    const char *bp = dmi_string_nosave(dm, s);
64
    char *str;
65
    size_t len;
66
67
 
68
        return dmi_empty_string;
69
70
 
71
    str = dmi_alloc(len);
72
    if (str != NULL)
73
        strcpy(str, bp);
74
75
 
76
}
77
78
 
79
 *	We have to be cautious here. We have seen BIOSes with DMI pointers
80
 *	pointing to completely the wrong place for example
81
 */
82
static void dmi_table(u8 *buf, int len, int num,
83
		      void (*decode)(const struct dmi_header *, void *),
84
		      void *private_data)
85
{
86
	u8 *data = buf;
87
	int i = 0;
88
89
 
90
	 *	Stop when we see all the items the table claimed to have
91
	 *	OR we run off the end of the table (also happens)
92
	 */
93
	while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
94
		const struct dmi_header *dm = (const struct dmi_header *)data;
95
96
 
97
		 *  We want to know the total length (formatted area and
98
		 *  strings) before decoding to make sure we won't run off the
99
		 *  table in dmi_decode or dmi_string
100
		 */
101
		data += dm->length;
102
		while ((data - buf < len - 1) && (data[0] || data[1]))
103
			data++;
104
		if (data - buf < len - 1)
105
			decode(dm, private_data);
106
		data += 2;
107
		i++;
108
	}
109
}
110
111
 
112
static u16 dmi_len;
113
static u16 dmi_num;
114
115
 
116
        void *))
117
{
118
	u8 *buf;
119
120
 
121
	if (buf == NULL)
122
		return -1;
123
124
 
125
126
 
127
128
 
129
}
130
131
 
132
{
133
    u8 sum = 0;
134
    int a;
135
136
 
137
        sum += buf[a];
138
139
 
140
}
141
142
 
143
static LIST_HEAD(dmi_devices);
144
int dmi_available;
145
146
 
147
 *  Save a DMI string
148
 */
149
static void __init dmi_save_ident(const struct dmi_header *dm, int slot,
150
        int string)
151
{
152
    const char *d = (const char *) dm;
153
    const char *p;
154
155
 
156
        return;
157
158
 
159
    if (p == NULL)
160
        return;
161
162
 
163
}
164
165
 
166
        int index)
167
{
168
    const u8 *d = (u8 *) dm + index;
169
    char *s;
170
    int is_ff = 1, is_00 = 1, i;
171
172
 
173
        return;
174
175
 
176
        if (d[i] != 0x00)
177
            is_00 = 0;
178
        if (d[i] != 0xFF)
179
            is_ff = 0;
180
    }
181
182
 
183
        return;
184
185
 
186
    if (!s)
187
        return;
188
189
 
190
     * As of version 2.6 of the SMBIOS specification, the first 3 fields of
191
     * the UUID are supposed to be little-endian encoded.  The specification
192
     * says that this is the defacto standard.
193
     */
194
    if (dmi_ver >= 0x0206)
195
        sprintf(s, "%pUL", d);
196
    else
197
        sprintf(s, "%pUB", d);
198
199
 
200
}
201
202
 
203
        int index)
204
{
205
    const u8 *d = (u8 *) dm + index;
206
    char *s;
207
208
 
209
        return;
210
211
 
212
    if (!s)
213
        return;
214
215
 
216
    dmi_ident[slot] = s;
217
}
218
219
 
220
{
221
    struct dmi_device *dev;
222
223
 
224
    if (dmi_find_device(type, name, NULL))
225
        return;
226
227
 
228
    if (!dev)
229
        return;
230
231
 
232
    strcpy((char *)(dev + 1), name);
233
    dev->name = (char *)(dev + 1);
234
    dev->device_data = NULL;
235
    list_add(&dev->list, &dmi_devices);
236
}
237
238
 
239
{
240
    int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
241
242
 
243
        const char *d = (char *)(dm + 1) + (i * 2);
244
245
 
246
        if ((*d & 0x80) == 0)
247
            continue;
248
249
 
250
    }
251
}
252
253
 
254
{
255
    int i, count = *(u8 *)(dm + 1);
256
    struct dmi_device *dev;
257
258
 
259
        const char *devname = dmi_string(dm, i);
260
261
 
262
            continue;
263
264
 
265
        if (!dev)
266
            break;
267
268
 
269
        dev->name = devname;
270
        dev->device_data = NULL;
271
272
 
273
    }
274
}
275
276
 
277
{
278
	struct dmi_device *dev;
279
	void *data;
280
281
 
282
	if (data == NULL)
283
		return;
284
285
 
286
287
 
288
	if (!dev)
289
		return;
290
291
 
292
	dev->name = "IPMI controller";
293
	dev->device_data = data;
294
295
 
296
}
297
298
 
299
					int devfn, const char *name)
300
{
301
	struct dmi_dev_onboard *onboard_dev;
302
303
 
304
	if (!onboard_dev)
305
		return;
306
307
 
308
	onboard_dev->segment = segment;
309
	onboard_dev->bus = bus;
310
	onboard_dev->devfn = devfn;
311
312
 
313
	onboard_dev->dev.type = DMI_DEV_TYPE_DEV_ONBOARD;
314
	onboard_dev->dev.name = (char *)&onboard_dev[1];
315
	onboard_dev->dev.device_data = onboard_dev;
316
317
 
318
}
319
320
 
321
{
322
	const u8 *d = (u8 *) dm + 5;
323
324
 
325
	if ((*d & 0x80) == 0)
326
		return;
327
328
 
329
			     dmi_string_nosave(dm, *(d-1)));
330
	dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
331
332
 
333
334
 
335
 *  Process a DMI table entry. Right now all we care about are the BIOS
336
 *  and machine entries. For 2.5 we should pull the smbus controller info
337
 *  out of here.
338
 */
339
static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
340
{
341
    switch (dm->type) {
342
    case 0:     /* BIOS Information */
343
        dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
344
        dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
345
        dmi_save_ident(dm, DMI_BIOS_DATE, 8);
346
        break;
347
    case 1:     /* System Information */
348
        dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
349
        dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
350
        dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
351
        dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
352
        dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8);
353
        break;
354
    case 2:     /* Base Board Information */
355
        dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
356
        dmi_save_ident(dm, DMI_BOARD_NAME, 5);
357
        dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
358
        dmi_save_ident(dm, DMI_BOARD_SERIAL, 7);
359
        dmi_save_ident(dm, DMI_BOARD_ASSET_TAG, 8);
360
        break;
361
    case 3:     /* Chassis Information */
362
        dmi_save_ident(dm, DMI_CHASSIS_VENDOR, 4);
363
        dmi_save_type(dm, DMI_CHASSIS_TYPE, 5);
364
        dmi_save_ident(dm, DMI_CHASSIS_VERSION, 6);
365
        dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7);
366
        dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8);
367
        break;
368
    case 10:    /* Onboard Devices Information */
369
        dmi_save_devices(dm);
370
        break;
371
    case 11:    /* OEM Strings */
372
        dmi_save_oem_strings_devices(dm);
373
        break;
374
    case 38:    /* IPMI Device Information */
375
        dmi_save_ipmi_device(dm);
376
        break;
377
    case 41:    /* Onboard Devices Extended Information */
378
        dmi_save_extended_devices(dm);
379
    }
380
}
381
382
 
383
{
384
	int c = 0;
385
	const char *p;
386
387
 
388
		return c;
389
390
 
391
		if (isprint(*p))
392
			c += scnprintf(buf + c, len - c, "%c", *p);
393
		else
394
			c += scnprintf(buf + c, len - c, "\\x%02x", *p & 0xff);
395
	return c;
396
}
397
398
 
399
{
400
    int c = 0;
401
    const char *board;  /* Board Name is optional */
402
403
 
404
                dmi_get_system_info(DMI_SYS_VENDOR));
405
    c += scnprintf(buf + c, len - c, " ");
406
    c += print_filtered(buf + c, len - c,
407
                dmi_get_system_info(DMI_PRODUCT_NAME));
408
409
 
410
    if (board) {
411
        c += scnprintf(buf + c, len - c, "/");
412
        c += print_filtered(buf + c, len - c, board);
413
    }
414
    c += scnprintf(buf + c, len - c, ", BIOS ");
415
    c += print_filtered(buf + c, len - c,
416
                dmi_get_system_info(DMI_BIOS_VERSION));
417
    c += scnprintf(buf + c, len - c, " ");
418
    c += print_filtered(buf + c, len - c,
419
                dmi_get_system_info(DMI_BIOS_DATE));
420
}
421
422
 
423
 * Check for DMI/SMBIOS headers in the system firmware image.  Any
424
 * SMBIOS header must start 16 bytes before the DMI header, so take a
425
 * 32 byte buffer and check for DMI at offset 16 and SMBIOS at offset
426
 * 0.  If the DMI header is present, set dmi_ver accordingly (SMBIOS
427
 * takes precedence) and return 0.  Otherwise return 1.
428
 */
429
static int __init dmi_present(const u8 *buf)
430
{
431
    int smbios_ver;
432
433
 
434
        buf[5] < 32 && dmi_checksum(buf, buf[5])) {
435
        smbios_ver = (buf[6] << 8) + buf[7];
436
437
 
438
        switch (smbios_ver) {
439
        case 0x021F:
440
        case 0x0221:
441
            pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
442
                 smbios_ver & 0xFF, 3);
443
            smbios_ver = 0x0203;
444
            break;
445
        case 0x0233:
446
            pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
447
            smbios_ver = 0x0206;
448
            break;
449
        }
450
    } else {
451
        smbios_ver = 0;
452
    }
453
454
 
455
456
 
457
        dmi_num = (buf[13] << 8) | buf[12];
458
        dmi_len = (buf[7] << 8) | buf[6];
459
        dmi_base = (buf[11] << 24) | (buf[10] << 16) |
460
            (buf[9] << 8) | buf[8];
461
462
 
463
            if (smbios_ver) {
464
                dmi_ver = smbios_ver;
465
                pr_info("SMBIOS %d.%d present.\n",
466
                       dmi_ver >> 8, dmi_ver & 0xFF);
467
            } else {
468
                dmi_ver = (buf[14] & 0xF0) << 4 |
469
                       (buf[14] & 0x0F);
470
                pr_info("Legacy DMI %d.%d present.\n",
471
                       dmi_ver >> 8, dmi_ver & 0xFF);
472
            }
473
			dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
474
			printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
475
            return 0;
476
        }
477
    }
478
479
 
480
}
481
482
 
483
{
484
    char __iomem *p, *q;
485
	char buf[32];
486
487
 
488
 
489
 
490
491
 
492
     * Iterate over all possible DMI header addresses q.
493
     * Maintain the 32 bytes around q in buf.  On the
494
     * first iteration, substitute zero for the
495
     * out-of-range bytes so there is no chance of falsely
496
     * detecting an SMBIOS header.
497
     */
498
    memset(buf, 0, 16);
499
    for (q = p; q < p + 0x10000; q += 16) {
500
        memcpy(buf + 16, q, 16);
501
        if (!dmi_present(buf)) {
502
            dmi_available = 1;
503
            goto out;
504
        }
505
        memcpy(buf, buf + 16, 16);
506
    }
507
 error:
508
    pr_info("DMI not present or invalid.\n");
509
 out:
510
    dmi_initialized = 1;
511
}
512
513
 
514
/**
515
 *	dmi_matches - check if dmi_system_id structure matches system DMI data
516
 *	@dmi: pointer to the dmi_system_id structure to check
517
 */
518
static bool dmi_matches(const struct dmi_system_id *dmi)
519
{
520
	int i;
521
522
 
523
524
 
525
		int s = dmi->matches[i].slot;
526
		if (s == DMI_NONE)
527
			break;
528
		if (dmi_ident[s]) {
529
			if (!dmi->matches[i].exact_match &&
530
			    strstr(dmi_ident[s], dmi->matches[i].substr))
531
				continue;
532
			else if (dmi->matches[i].exact_match &&
533
				 !strcmp(dmi_ident[s], dmi->matches[i].substr))
534
				continue;
535
		}
536
537
 
538
		return false;
539
	}
540
	return true;
541
}
542
543
 
544
 *	dmi_is_end_of_table - check for end-of-table marker
545
 *	@dmi: pointer to the dmi_system_id structure to check
546
 */
547
static bool dmi_is_end_of_table(const struct dmi_system_id *dmi)
548
{
549
	return dmi->matches[0].slot == DMI_NONE;
550
}
551
552
 
553
 *	dmi_check_system - check system DMI data
554
 *	@list: array of dmi_system_id structures to match against
555
 *		All non-null elements of the list must match
556
 *		their slot's (field index's) data (i.e., each
557
 *		list string must be a substring of the specified
558
 *		DMI slot's string data) to be considered a
559
 *		successful match.
560
 *
561
 *	Walk the blacklist table running matching functions until someone
562
 *	returns non zero or we hit the end. Callback function is called for
563
 *	each successful match. Returns the number of matches.
564
 */
565
int dmi_check_system(const struct dmi_system_id *list)
566
{
567
	int count = 0;
568
	const struct dmi_system_id *d;
569
570
 
571
		if (dmi_matches(d)) {
572
			count++;
573
			if (d->callback && d->callback(d))
574
				break;
575
		}
576
577
 
578
}
579
EXPORT_SYMBOL(dmi_check_system);
580
581
 
582
 *  dmi_get_system_info - return DMI data value
583
 *  @field: data index (see enum dmi_field)
584
 *
585
 *  Returns one DMI data value, can be used to perform
586
 *  complex DMI data checks.
587
 */
588
const char *dmi_get_system_info(int field)
589
{
590
    return dmi_ident[field];
591
}
592
EXPORT_SYMBOL(dmi_get_system_info);
593
/**
594
 *	dmi_find_device - find onboard device by type/name
595
 *	@type: device type or %DMI_DEV_TYPE_ANY to match all device types
596
 *	@name: device name string or %NULL to match all
597
 *	@from: previous device found in search, or %NULL for new search.
598
 *
599
 *	Iterates through the list of known onboard devices. If a device is
600
 *	found with a matching @vendor and @device, a pointer to its device
601
 *	structure is returned.  Otherwise, %NULL is returned.
602
 *	A new search is initiated by passing %NULL as the @from argument.
603
 *	If @from is not %NULL, searches continue from next device.
604
 */
605
const struct dmi_device *dmi_find_device(int type, const char *name,
606
				    const struct dmi_device *from)
607
{
608
	const struct list_head *head = from ? &from->list : &dmi_devices;
609
	struct list_head *d;
610
611
 
612
		const struct dmi_device *dev =
613
			list_entry(d, struct dmi_device, list);
614
615
 
616
		    ((name == NULL) || (strcmp(dev->name, name) == 0)))
617
			return dev;
618
	}
619
620
 
621
}
622
EXPORT_SYMBOL(dmi_find_device);
623