Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 7441
b: refs/heads/master
c: ebad6a4
h: refs/heads/master
i:
  7439: 96bfad2
v: v3
  • Loading branch information
Andrey Panin authored and Linus Torvalds committed Sep 7, 2005
1 parent 63fd5a0 commit f2c89e5
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c3c7120d552989be94c9137989be5abb6da8954f
refs/heads/master: ebad6a4230bdb5927495e28bc7837f515bf667a7
102 changes: 90 additions & 12 deletions trunk/arch/i386/kernel/dmi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@
#include <linux/bootmem.h>


struct dmi_header {
u8 type;
u8 length;
u16 handle;
};


static char * __init dmi_string(struct dmi_header *dm, u8 s)
{
u8 *bp = ((u8 *) dm) + dm->length;
Expand Down Expand Up @@ -88,6 +81,7 @@ static int __init dmi_checksum(u8 *buf)
}

static char *dmi_ident[DMI_STRING_MAX];
static LIST_HEAD(dmi_devices);

/*
* Save a DMI string
Expand All @@ -106,32 +100,87 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
dmi_ident[slot] = p;
}

static void __init dmi_save_devices(struct dmi_header *dm)
{
int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
struct dmi_device *dev;

for (i = 0; i < count; i++) {
char *d = ((char *) dm) + (i * 2);

/* Skip disabled device */
if ((*d & 0x80) == 0)
continue;

dev = alloc_bootmem(sizeof(*dev));
if (!dev) {
printk(KERN_ERR "dmi_save_devices: out of memory.\n");
break;
}

dev->type = *d++ & 0x7f;
dev->name = dmi_string(dm, *d);
dev->device_data = NULL;

list_add(&dev->list, &dmi_devices);
}
}

static void __init dmi_save_ipmi_device(struct dmi_header *dm)
{
struct dmi_device *dev;
void * data;

data = alloc_bootmem(dm->length);
if (data == NULL) {
printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
return;
}

memcpy(data, dm, dm->length);

dev = alloc_bootmem(sizeof(*dev));
if (!dev) {
printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
return;
}

dev->type = DMI_DEV_TYPE_IPMI;
dev->name = "IPMI controller";
dev->device_data = data;

list_add(&dev->list, &dmi_devices);
}

/*
* Process a DMI table entry. Right now all we care about are the BIOS
* and machine entries. For 2.5 we should pull the smbus controller info
* out of here.
*/
static void __init dmi_decode(struct dmi_header *dm)
{
u8 *data __attribute__((__unused__)) = (u8 *)dm;

switch(dm->type) {
case 0:
case 0: /* BIOS Information */
dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
dmi_save_ident(dm, DMI_BIOS_DATE, 8);
break;
case 1:
case 1: /* System Information */
dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
break;
case 2:
case 2: /* Base Board Information */
dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
dmi_save_ident(dm, DMI_BOARD_NAME, 5);
dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
break;
case 10: /* Onboard Devices Information */
dmi_save_devices(dm);
break;
case 38: /* IPMI Device Information */
dmi_save_ipmi_device(dm);
}
}

Expand Down Expand Up @@ -221,3 +270,32 @@ char *dmi_get_system_info(int field)
return dmi_ident[field];
}
EXPORT_SYMBOL(dmi_get_system_info);

/**
* dmi_find_device - find onboard device by type/name
* @type: device type or %DMI_DEV_TYPE_ANY to match all device types
* @desc: device name string or %NULL to match all
* @from: previous device found in search, or %NULL for new search.
*
* Iterates through the list of known onboard devices. If a device is
* found with a matching @vendor and @device, a pointer to its device
* structure is returned. Otherwise, %NULL is returned.
* A new search is initiated by passing %NULL to the @from argument.
* If @from is not %NULL, searches continue from next device.
*/
struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from)
{
struct list_head *d, *head = from ? &from->list : &dmi_devices;

for(d = head->next; d != &dmi_devices; d = d->next) {
struct dmi_device *dev = list_entry(d, struct dmi_device, list);

if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) &&
((name == NULL) || (strcmp(dev->name, name) == 0)))
return dev;
}

return NULL;
}
EXPORT_SYMBOL(dmi_find_device);
36 changes: 33 additions & 3 deletions trunk/include/linux/dmi.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef __DMI_H__
#define __DMI_H__

#include <linux/list.h>

enum dmi_field {
DMI_NONE,
DMI_BIOS_VENDOR,
Expand All @@ -16,6 +18,24 @@ enum dmi_field {
DMI_STRING_MAX,
};

enum dmi_device_type {
DMI_DEV_TYPE_ANY = 0,
DMI_DEV_TYPE_OTHER,
DMI_DEV_TYPE_UNKNOWN,
DMI_DEV_TYPE_VIDEO,
DMI_DEV_TYPE_SCSI,
DMI_DEV_TYPE_ETHERNET,
DMI_DEV_TYPE_TOKENRING,
DMI_DEV_TYPE_SOUND,
DMI_DEV_TYPE_IPMI = -1
};

struct dmi_header {
u8 type;
u8 length;
u16 handle;
};

/*
* DMI callbacks for problem boards
*/
Expand All @@ -26,22 +46,32 @@ struct dmi_strmatch {

struct dmi_system_id {
int (*callback)(struct dmi_system_id *);
char *ident;
const char *ident;
struct dmi_strmatch matches[4];
void *driver_data;
};

#define DMI_MATCH(a,b) { a, b }
#define DMI_MATCH(a, b) { a, b }

struct dmi_device {
struct list_head list;
int type;
const char *name;
void *device_data; /* Type specific data */
};

#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)

extern int dmi_check_system(struct dmi_system_id *list);
extern char * dmi_get_system_info(int field);

extern struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from);
#else

static inline int dmi_check_system(struct dmi_system_id *list) { return 0; }
static inline char * dmi_get_system_info(int field) { return NULL; }
static struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from) { return NULL; }

#endif

Expand Down

0 comments on commit f2c89e5

Please sign in to comment.