diff options
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r-- | drivers/firmware/dmi_scan.c | 73 |
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 | ||
85 | static char *dmi_ident[DMI_STRING_MAX]; | 85 | static char *dmi_ident[DMI_STRING_MAX]; |
86 | static LIST_HEAD(dmi_devices); | 86 | static LIST_HEAD(dmi_devices); |
87 | int 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 | ||
106 | static 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 | |||
135 | static 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 | |||
105 | static void __init dmi_save_devices(struct dmi_header *dm) | 151 | static 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 | |||