OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [firmware/] [dmi_scan.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
#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/efi.h>
7
#include <linux/bootmem.h>
8
#include <linux/slab.h>
9
#include <asm/dmi.h>
10
 
11
static char * __init dmi_string(const struct dmi_header *dm, u8 s)
12
{
13
        const u8 *bp = ((u8 *) dm) + dm->length;
14
        char *str = "";
15
 
16
        if (s) {
17
                s--;
18
                while (s > 0 && *bp) {
19
                        bp += strlen(bp) + 1;
20
                        s--;
21
                }
22
 
23
                if (*bp != 0) {
24
                        str = dmi_alloc(strlen(bp) + 1);
25
                        if (str != NULL)
26
                                strcpy(str, bp);
27
                        else
28
                                printk(KERN_ERR "dmi_string: out of memory.\n");
29
                }
30
        }
31
 
32
        return str;
33
}
34
 
35
/*
36
 *      We have to be cautious here. We have seen BIOSes with DMI pointers
37
 *      pointing to completely the wrong place for example
38
 */
39
static int __init dmi_table(u32 base, int len, int num,
40
                            void (*decode)(const struct dmi_header *))
41
{
42
        u8 *buf, *data;
43
        int i = 0;
44
 
45
        buf = dmi_ioremap(base, len);
46
        if (buf == NULL)
47
                return -1;
48
 
49
        data = buf;
50
 
51
        /*
52
         *      Stop when we see all the items the table claimed to have
53
         *      OR we run off the end of the table (also happens)
54
         */
55
        while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
56
                const struct dmi_header *dm = (const struct dmi_header *)data;
57
 
58
                /*
59
                 *  We want to know the total length (formated area and strings)
60
                 *  before decoding to make sure we won't run off the table in
61
                 *  dmi_decode or dmi_string
62
                 */
63
                data += dm->length;
64
                while ((data - buf < len - 1) && (data[0] || data[1]))
65
                        data++;
66
                if (data - buf < len - 1)
67
                        decode(dm);
68
                data += 2;
69
                i++;
70
        }
71
        dmi_iounmap(buf, len);
72
        return 0;
73
}
74
 
75
static int __init dmi_checksum(const u8 *buf)
76
{
77
        u8 sum = 0;
78
        int a;
79
 
80
        for (a = 0; a < 15; a++)
81
                sum += buf[a];
82
 
83
        return sum == 0;
84
}
85
 
86
static char *dmi_ident[DMI_STRING_MAX];
87
static LIST_HEAD(dmi_devices);
88
int dmi_available;
89
 
90
/*
91
 *      Save a DMI string
92
 */
93
static void __init dmi_save_ident(const struct dmi_header *dm, int slot, int string)
94
{
95
        const char *d = (const char*) dm;
96
        char *p;
97
 
98
        if (dmi_ident[slot])
99
                return;
100
 
101
        p = dmi_string(dm, d[string]);
102
        if (p == NULL)
103
                return;
104
 
105
        dmi_ident[slot] = p;
106
}
107
 
108
static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int index)
109
{
110
        const u8 *d = (u8*) dm + index;
111
        char *s;
112
        int is_ff = 1, is_00 = 1, i;
113
 
114
        if (dmi_ident[slot])
115
                return;
116
 
117
        for (i = 0; i < 16 && (is_ff || is_00); i++) {
118
                if(d[i] != 0x00) is_ff = 0;
119
                if(d[i] != 0xFF) is_00 = 0;
120
        }
121
 
122
        if (is_ff || is_00)
123
                return;
124
 
125
        s = dmi_alloc(16*2+4+1);
126
        if (!s)
127
                return;
128
 
129
        sprintf(s,
130
                "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
131
                d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
132
                d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
133
 
134
        dmi_ident[slot] = s;
135
}
136
 
137
static void __init dmi_save_type(const struct dmi_header *dm, int slot, int index)
138
{
139
        const u8 *d = (u8*) dm + index;
140
        char *s;
141
 
142
        if (dmi_ident[slot])
143
                return;
144
 
145
        s = dmi_alloc(4);
146
        if (!s)
147
                return;
148
 
149
        sprintf(s, "%u", *d & 0x7F);
150
        dmi_ident[slot] = s;
151
}
152
 
153
static void __init dmi_save_devices(const struct dmi_header *dm)
154
{
155
        int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
156
        struct dmi_device *dev;
157
 
158
        for (i = 0; i < count; i++) {
159
                const char *d = (char *)(dm + 1) + (i * 2);
160
 
161
                /* Skip disabled device */
162
                if ((*d & 0x80) == 0)
163
                        continue;
164
 
165
                dev = dmi_alloc(sizeof(*dev));
166
                if (!dev) {
167
                        printk(KERN_ERR "dmi_save_devices: out of memory.\n");
168
                        break;
169
                }
170
 
171
                dev->type = *d++ & 0x7f;
172
                dev->name = dmi_string(dm, *d);
173
                dev->device_data = NULL;
174
                list_add(&dev->list, &dmi_devices);
175
        }
176
}
177
 
178
static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm)
179
{
180
        int i, count = *(u8 *)(dm + 1);
181
        struct dmi_device *dev;
182
 
183
        for (i = 1; i <= count; i++) {
184
                dev = dmi_alloc(sizeof(*dev));
185
                if (!dev) {
186
                        printk(KERN_ERR
187
                           "dmi_save_oem_strings_devices: out of memory.\n");
188
                        break;
189
                }
190
 
191
                dev->type = DMI_DEV_TYPE_OEM_STRING;
192
                dev->name = dmi_string(dm, i);
193
                dev->device_data = NULL;
194
 
195
                list_add(&dev->list, &dmi_devices);
196
        }
197
}
198
 
199
static void __init dmi_save_ipmi_device(const struct dmi_header *dm)
200
{
201
        struct dmi_device *dev;
202
        void * data;
203
 
204
        data = dmi_alloc(dm->length);
205
        if (data == NULL) {
206
                printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
207
                return;
208
        }
209
 
210
        memcpy(data, dm, dm->length);
211
 
212
        dev = dmi_alloc(sizeof(*dev));
213
        if (!dev) {
214
                printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
215
                return;
216
        }
217
 
218
        dev->type = DMI_DEV_TYPE_IPMI;
219
        dev->name = "IPMI controller";
220
        dev->device_data = data;
221
 
222
        list_add(&dev->list, &dmi_devices);
223
}
224
 
225
/*
226
 *      Process a DMI table entry. Right now all we care about are the BIOS
227
 *      and machine entries. For 2.5 we should pull the smbus controller info
228
 *      out of here.
229
 */
230
static void __init dmi_decode(const struct dmi_header *dm)
231
{
232
        switch(dm->type) {
233
        case 0:          /* BIOS Information */
234
                dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
235
                dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
236
                dmi_save_ident(dm, DMI_BIOS_DATE, 8);
237
                break;
238
        case 1:         /* System Information */
239
                dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
240
                dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
241
                dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
242
                dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
243
                dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8);
244
                break;
245
        case 2:         /* Base Board Information */
246
                dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
247
                dmi_save_ident(dm, DMI_BOARD_NAME, 5);
248
                dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
249
                dmi_save_ident(dm, DMI_BOARD_SERIAL, 7);
250
                dmi_save_ident(dm, DMI_BOARD_ASSET_TAG, 8);
251
                break;
252
        case 3:         /* Chassis Information */
253
                dmi_save_ident(dm, DMI_CHASSIS_VENDOR, 4);
254
                dmi_save_type(dm, DMI_CHASSIS_TYPE, 5);
255
                dmi_save_ident(dm, DMI_CHASSIS_VERSION, 6);
256
                dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7);
257
                dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8);
258
                break;
259
        case 10:        /* Onboard Devices Information */
260
                dmi_save_devices(dm);
261
                break;
262
        case 11:        /* OEM Strings */
263
                dmi_save_oem_strings_devices(dm);
264
                break;
265
        case 38:        /* IPMI Device Information */
266
                dmi_save_ipmi_device(dm);
267
        }
268
}
269
 
270
static int __init dmi_present(const char __iomem *p)
271
{
272
        u8 buf[15];
273
 
274
        memcpy_fromio(buf, p, 15);
275
        if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
276
                u16 num = (buf[13] << 8) | buf[12];
277
                u16 len = (buf[7] << 8) | buf[6];
278
                u32 base = (buf[11] << 24) | (buf[10] << 16) |
279
                        (buf[9] << 8) | buf[8];
280
 
281
                /*
282
                 * DMI version 0.0 means that the real version is taken from
283
                 * the SMBIOS version, which we don't know at this point.
284
                 */
285
                if (buf[14] != 0)
286
                        printk(KERN_INFO "DMI %d.%d present.\n",
287
                               buf[14] >> 4, buf[14] & 0xF);
288
                else
289
                        printk(KERN_INFO "DMI present.\n");
290
                if (dmi_table(base,len, num, dmi_decode) == 0)
291
                        return 0;
292
        }
293
        return 1;
294
}
295
 
296
void __init dmi_scan_machine(void)
297
{
298
        char __iomem *p, *q;
299
        int rc;
300
 
301
        if (efi_enabled) {
302
                if (efi.smbios == EFI_INVALID_TABLE_ADDR)
303
                        goto out;
304
 
305
                /* This is called as a core_initcall() because it isn't
306
                 * needed during early boot.  This also means we can
307
                 * iounmap the space when we're done with it.
308
                 */
309
                p = dmi_ioremap(efi.smbios, 32);
310
                if (p == NULL)
311
                        goto out;
312
 
313
                rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
314
                dmi_iounmap(p, 32);
315
                if (!rc) {
316
                        dmi_available = 1;
317
                        return;
318
                }
319
        }
320
        else {
321
                /*
322
                 * no iounmap() for that ioremap(); it would be a no-op, but
323
                 * it's so early in setup that sucker gets confused into doing
324
                 * what it shouldn't if we actually call it.
325
                 */
326
                p = dmi_ioremap(0xF0000, 0x10000);
327
                if (p == NULL)
328
                        goto out;
329
 
330
                for (q = p; q < p + 0x10000; q += 16) {
331
                        rc = dmi_present(q);
332
                        if (!rc) {
333
                                dmi_available = 1;
334
                                return;
335
                        }
336
                }
337
        }
338
 out:   printk(KERN_INFO "DMI not present or invalid.\n");
339
}
340
 
341
/**
342
 *      dmi_check_system - check system DMI data
343
 *      @list: array of dmi_system_id structures to match against
344
 *              All non-null elements of the list must match
345
 *              their slot's (field index's) data (i.e., each
346
 *              list string must be a substring of the specified
347
 *              DMI slot's string data) to be considered a
348
 *              successful match.
349
 *
350
 *      Walk the blacklist table running matching functions until someone
351
 *      returns non zero or we hit the end. Callback function is called for
352
 *      each successful match. Returns the number of matches.
353
 */
354
int dmi_check_system(const struct dmi_system_id *list)
355
{
356
        int i, count = 0;
357
        const struct dmi_system_id *d = list;
358
 
359
        while (d->ident) {
360
                for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
361
                        int s = d->matches[i].slot;
362
                        if (s == DMI_NONE)
363
                                continue;
364
                        if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
365
                                continue;
366
                        /* No match */
367
                        goto fail;
368
                }
369
                count++;
370
                if (d->callback && d->callback(d))
371
                        break;
372
fail:           d++;
373
        }
374
 
375
        return count;
376
}
377
EXPORT_SYMBOL(dmi_check_system);
378
 
379
/**
380
 *      dmi_get_system_info - return DMI data value
381
 *      @field: data index (see enum dmi_field)
382
 *
383
 *      Returns one DMI data value, can be used to perform
384
 *      complex DMI data checks.
385
 */
386
const char *dmi_get_system_info(int field)
387
{
388
        return dmi_ident[field];
389
}
390
EXPORT_SYMBOL(dmi_get_system_info);
391
 
392
 
393
/**
394
 *      dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
395
 *      @str:   Case sensitive Name
396
 */
397
int dmi_name_in_vendors(const char *str)
398
{
399
        static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
400
                                DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
401
                                DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
402
        int i;
403
        for (i = 0; fields[i] != DMI_NONE; i++) {
404
                int f = fields[i];
405
                if (dmi_ident[f] && strstr(dmi_ident[f], str))
406
                        return 1;
407
        }
408
        return 0;
409
}
410
EXPORT_SYMBOL(dmi_name_in_vendors);
411
 
412
/**
413
 *      dmi_find_device - find onboard device by type/name
414
 *      @type: device type or %DMI_DEV_TYPE_ANY to match all device types
415
 *      @name: device name string or %NULL to match all
416
 *      @from: previous device found in search, or %NULL for new search.
417
 *
418
 *      Iterates through the list of known onboard devices. If a device is
419
 *      found with a matching @vendor and @device, a pointer to its device
420
 *      structure is returned.  Otherwise, %NULL is returned.
421
 *      A new search is initiated by passing %NULL as the @from argument.
422
 *      If @from is not %NULL, searches continue from next device.
423
 */
424
const struct dmi_device * dmi_find_device(int type, const char *name,
425
                                    const struct dmi_device *from)
426
{
427
        const struct list_head *head = from ? &from->list : &dmi_devices;
428
        struct list_head *d;
429
 
430
        for(d = head->next; d != &dmi_devices; d = d->next) {
431
                const struct dmi_device *dev =
432
                        list_entry(d, struct dmi_device, list);
433
 
434
                if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) &&
435
                    ((name == NULL) || (strcmp(dev->name, name) == 0)))
436
                        return dev;
437
        }
438
 
439
        return NULL;
440
}
441
EXPORT_SYMBOL(dmi_find_device);
442
 
443
/**
444
 *      dmi_get_year - Return year of a DMI date
445
 *      @field: data index (like dmi_get_system_info)
446
 *
447
 *      Returns -1 when the field doesn't exist. 0 when it is broken.
448
 */
449
int dmi_get_year(int field)
450
{
451
        int year;
452
        const char *s = dmi_get_system_info(field);
453
 
454
        if (!s)
455
                return -1;
456
        if (*s == '\0')
457
                return 0;
458
        s = strrchr(s, '/');
459
        if (!s)
460
                return 0;
461
 
462
        s += 1;
463
        year = simple_strtoul(s, NULL, 0);
464
        if (year && year < 100) {       /* 2-digit year */
465
                year += 1900;
466
                if (year < 1996)        /* no dates < spec 1.0 */
467
                        year += 100;
468
        }
469
 
470
        return year;
471
}
472
 
473
/**
474
 *      dmi_get_slot - return dmi_ident[slot]
475
 *      @slot:  index into dmi_ident[]
476
 */
477
char *dmi_get_slot(int slot)
478
{
479
        return(dmi_ident[slot]);
480
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.