X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Ffirmware%2Fdmi_scan.c;h=0cdadea7a40e9f58cd027697611bf0d18eafd1bd;hb=821f3eff7cdb9d6c7076effabd46c96c322daed1;hp=37deee6c0c1cc5aa4ca575797dea77d6ad792243;hpb=bd3c97a7c718bfb9f1e4f31c16c383a5c6f815eb;p=linux-2.6 diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 37deee6c0c..0cdadea7a4 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -8,9 +8,9 @@ #include #include -static char * __init dmi_string(struct dmi_header *dm, u8 s) +static char * __init dmi_string(const struct dmi_header *dm, u8 s) { - u8 *bp = ((u8 *) dm) + dm->length; + const u8 *bp = ((u8 *) dm) + dm->length; char *str = ""; if (s) { @@ -37,7 +37,7 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s) * pointing to completely the wrong place for example */ static int __init dmi_table(u32 base, int len, int num, - void (*decode)(struct dmi_header *)) + void (*decode)(const struct dmi_header *)) { u8 *buf, *data; int i = 0; @@ -53,7 +53,8 @@ static int __init dmi_table(u32 base, int len, int num, * OR we run off the end of the table (also happens) */ while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { - struct dmi_header *dm = (struct dmi_header *)data; + const struct dmi_header *dm = (const struct dmi_header *)data; + /* * We want to know the total length (formated area and strings) * before decoding to make sure we won't run off the table in @@ -71,7 +72,7 @@ static int __init dmi_table(u32 base, int len, int num, return 0; } -static int __init dmi_checksum(u8 *buf) +static int __init dmi_checksum(const u8 *buf) { u8 sum = 0; int a; @@ -84,13 +85,15 @@ static int __init dmi_checksum(u8 *buf) static char *dmi_ident[DMI_STRING_MAX]; static LIST_HEAD(dmi_devices); +int dmi_available; /* * Save a DMI string */ -static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) +static void __init dmi_save_ident(const struct dmi_header *dm, int slot, int string) { - char *p, *d = (char*) dm; + const char *d = (const char*) dm; + char *p; if (dmi_ident[slot]) return; @@ -102,13 +105,58 @@ 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) +static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int index) +{ + const u8 *d = (u8*) dm + index; + char *s; + int is_ff = 1, is_00 = 1, i; + + if (dmi_ident[slot]) + return; + + for (i = 0; i < 16 && (is_ff || is_00); i++) { + if(d[i] != 0x00) is_ff = 0; + if(d[i] != 0xFF) is_00 = 0; + } + + if (is_ff || is_00) + return; + + s = dmi_alloc(16*2+4+1); + if (!s) + return; + + sprintf(s, + "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], + d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + + dmi_ident[slot] = s; +} + +static void __init dmi_save_type(const struct dmi_header *dm, int slot, int index) +{ + const u8 *d = (u8*) dm + index; + char *s; + + if (dmi_ident[slot]) + return; + + s = dmi_alloc(4); + if (!s) + return; + + sprintf(s, "%u", *d & 0x7F); + dmi_ident[slot] = s; +} + +static void __init dmi_save_devices(const 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 + 1) + (i * 2); + const char *d = (char *)(dm + 1) + (i * 2); /* Skip disabled device */ if ((*d & 0x80) == 0) @@ -127,7 +175,7 @@ static void __init dmi_save_devices(struct dmi_header *dm) } } -static void __init dmi_save_oem_strings_devices(struct dmi_header *dm) +static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm) { int i, count = *(u8 *)(dm + 1); struct dmi_device *dev; @@ -148,7 +196,7 @@ static void __init dmi_save_oem_strings_devices(struct dmi_header *dm) } } -static void __init dmi_save_ipmi_device(struct dmi_header *dm) +static void __init dmi_save_ipmi_device(const struct dmi_header *dm) { struct dmi_device *dev; void * data; @@ -179,7 +227,7 @@ static void __init dmi_save_ipmi_device(struct dmi_header *dm) * 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) +static void __init dmi_decode(const struct dmi_header *dm) { switch(dm->type) { case 0: /* BIOS Information */ @@ -192,11 +240,21 @@ static void __init dmi_decode(struct dmi_header *dm) dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); + dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8); break; 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); + dmi_save_ident(dm, DMI_BOARD_SERIAL, 7); + dmi_save_ident(dm, DMI_BOARD_ASSET_TAG, 8); + break; + case 3: /* Chassis Information */ + dmi_save_ident(dm, DMI_CHASSIS_VENDOR, 4); + dmi_save_type(dm, DMI_CHASSIS_TYPE, 5); + dmi_save_ident(dm, DMI_CHASSIS_VERSION, 6); + dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7); + dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8); break; case 10: /* Onboard Devices Information */ dmi_save_devices(dm); @@ -209,9 +267,10 @@ static void __init dmi_decode(struct dmi_header *dm) } } -static int __init dmi_present(char __iomem *p) +static int __init dmi_present(const char __iomem *p) { u8 buf[15]; + memcpy_fromio(buf, p, 15); if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { u16 num = (buf[13] << 8) | buf[12]; @@ -243,18 +302,20 @@ void __init dmi_scan_machine(void) if (efi.smbios == EFI_INVALID_TABLE_ADDR) goto out; - /* This is called as a core_initcall() because it isn't - * needed during early boot. This also means we can - * iounmap the space when we're done with it. - */ + /* This is called as a core_initcall() because it isn't + * needed during early boot. This also means we can + * iounmap the space when we're done with it. + */ p = dmi_ioremap(efi.smbios, 32); if (p == NULL) goto out; rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ dmi_iounmap(p, 32); - if (!rc) + if (!rc) { + dmi_available = 1; return; + } } else { /* @@ -268,8 +329,10 @@ void __init dmi_scan_machine(void) for (q = p; q < p + 0x10000; q += 16) { rc = dmi_present(q); - if (!rc) + if (!rc) { + dmi_available = 1; return; + } } } out: printk(KERN_INFO "DMI not present or invalid.\n"); @@ -288,10 +351,10 @@ void __init dmi_scan_machine(void) * returns non zero or we hit the end. Callback function is called for * each successful match. Returns the number of matches. */ -int dmi_check_system(struct dmi_system_id *list) +int dmi_check_system(const struct dmi_system_id *list) { int i, count = 0; - struct dmi_system_id *d = list; + const struct dmi_system_id *d = list; while (d->ident) { for (i = 0; i < ARRAY_SIZE(d->matches); i++) { @@ -320,7 +383,7 @@ EXPORT_SYMBOL(dmi_check_system); * Returns one DMI data value, can be used to perform * complex DMI data checks. */ -char *dmi_get_system_info(int field) +const char *dmi_get_system_info(int field) { return dmi_ident[field]; } @@ -331,7 +394,7 @@ EXPORT_SYMBOL(dmi_get_system_info); * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. * @str: Case sensitive Name */ -int dmi_name_in_vendors(char *str) +int dmi_name_in_vendors(const char *str) { static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR, DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, @@ -358,13 +421,15 @@ EXPORT_SYMBOL(dmi_name_in_vendors); * A new search is initiated by passing %NULL as 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) +const struct dmi_device * dmi_find_device(int type, const char *name, + const struct dmi_device *from) { - struct list_head *d, *head = from ? &from->list : &dmi_devices; + const struct list_head *head = from ? &from->list : &dmi_devices; + struct list_head *d; for(d = head->next; d != &dmi_devices; d = d->next) { - struct dmi_device *dev = list_entry(d, struct dmi_device, list); + const 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))) @@ -384,7 +449,7 @@ EXPORT_SYMBOL(dmi_find_device); int dmi_get_year(int field) { int year; - char *s = dmi_get_system_info(field); + const char *s = dmi_get_system_info(field); if (!s) return -1; @@ -404,3 +469,4 @@ int dmi_get_year(int field) return year; } +