aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/dmi_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r--drivers/firmware/dmi_scan.c73
1 files changed, 67 insertions, 6 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 37deee6c0c1c..f7318b3b51f2 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -84,6 +84,7 @@ static int __init dmi_checksum(u8 *buf)
84 84
85static char *dmi_ident[DMI_STRING_MAX]; 85static char *dmi_ident[DMI_STRING_MAX];
86static LIST_HEAD(dmi_devices); 86static LIST_HEAD(dmi_devices);
87int dmi_available;
87 88
88/* 89/*
89 * Save a DMI string 90 * Save a DMI string
@@ -102,6 +103,51 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
102 dmi_ident[slot] = p; 103 dmi_ident[slot] = p;
103} 104}
104 105
106static void __init dmi_save_uuid(struct dmi_header *dm, int slot, int index)
107{
108 u8 *d = (u8*) dm + index;
109 char *s;
110 int is_ff = 1, is_00 = 1, i;
111
112 if (dmi_ident[slot])
113 return;
114
115 for (i = 0; i < 16 && (is_ff || is_00); i++) {
116 if(d[i] != 0x00) is_ff = 0;
117 if(d[i] != 0xFF) is_00 = 0;
118 }
119
120 if (is_ff || is_00)
121 return;
122
123 s = dmi_alloc(16*2+4+1);
124 if (!s)
125 return;
126
127 sprintf(s,
128 "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
129 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
130 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
131
132 dmi_ident[slot] = s;
133}
134
135static void __init dmi_save_type(struct dmi_header *dm, int slot, int index)
136{
137 u8 *d = (u8*) dm + index;
138 char *s;
139
140 if (dmi_ident[slot])
141 return;
142
143 s = dmi_alloc(4);
144 if (!s)
145 return;
146
147 sprintf(s, "%u", *d & 0x7F);
148 dmi_ident[slot] = s;
149}
150
105static void __init dmi_save_devices(struct dmi_header *dm) 151static void __init dmi_save_devices(struct dmi_header *dm)
106{ 152{
107 int i, count = (dm->length - sizeof(struct dmi_header)) / 2; 153 int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
@@ -192,11 +238,21 @@ static void __init dmi_decode(struct dmi_header *dm)
192 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); 238 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
193 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); 239 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
194 dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); 240 dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
241 dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8);
195 break; 242 break;
196 case 2: /* Base Board Information */ 243 case 2: /* Base Board Information */
197 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); 244 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
198 dmi_save_ident(dm, DMI_BOARD_NAME, 5); 245 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
199 dmi_save_ident(dm, DMI_BOARD_VERSION, 6); 246 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
247 dmi_save_ident(dm, DMI_BOARD_SERIAL, 7);
248 dmi_save_ident(dm, DMI_BOARD_ASSET_TAG, 8);
249 break;
250 case 3: /* Chassis Information */
251 dmi_save_ident(dm, DMI_CHASSIS_VENDOR, 4);
252 dmi_save_type(dm, DMI_CHASSIS_TYPE, 5);
253 dmi_save_ident(dm, DMI_CHASSIS_VERSION, 6);
254 dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7);
255 dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8);
200 break; 256 break;
201 case 10: /* Onboard Devices Information */ 257 case 10: /* Onboard Devices Information */
202 dmi_save_devices(dm); 258 dmi_save_devices(dm);
@@ -243,18 +299,20 @@ void __init dmi_scan_machine(void)
243 if (efi.smbios == EFI_INVALID_TABLE_ADDR) 299 if (efi.smbios == EFI_INVALID_TABLE_ADDR)
244 goto out; 300 goto out;
245 301
246 /* This is called as a core_initcall() because it isn't 302 /* This is called as a core_initcall() because it isn't
247 * needed during early boot. This also means we can 303 * needed during early boot. This also means we can
248 * iounmap the space when we're done with it. 304 * iounmap the space when we're done with it.
249 */ 305 */
250 p = dmi_ioremap(efi.smbios, 32); 306 p = dmi_ioremap(efi.smbios, 32);
251 if (p == NULL) 307 if (p == NULL)
252 goto out; 308 goto out;
253 309
254 rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ 310 rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
255 dmi_iounmap(p, 32); 311 dmi_iounmap(p, 32);
256 if (!rc) 312 if (!rc) {
313 dmi_available = 1;
257 return; 314 return;
315 }
258 } 316 }
259 else { 317 else {
260 /* 318 /*
@@ -268,8 +326,10 @@ void __init dmi_scan_machine(void)
268 326
269 for (q = p; q < p + 0x10000; q += 16) { 327 for (q = p; q < p + 0x10000; q += 16) {
270 rc = dmi_present(q); 328 rc = dmi_present(q);
271 if (!rc) 329 if (!rc) {
330 dmi_available = 1;
272 return; 331 return;
332 }
273 } 333 }
274 } 334 }
275 out: printk(KERN_INFO "DMI not present or invalid.\n"); 335 out: printk(KERN_INFO "DMI not present or invalid.\n");
@@ -404,3 +464,4 @@ int dmi_get_year(int field)
404 464
405 return year; 465 return year;
406} 466}
467