Subversion Repositories Kolibri OS

Rev

Rev 5270 | Details | Compare with Previous | Last modification | View Log | RSS feed

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