aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-20 01:36:52 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-05-20 01:36:52 -0400
commit880102e78547c1db158a17e36cf0cdd98e7ad710 (patch)
tree3fff9cc54c44dafe275cfabefb96c589e08d971d /drivers/firmware
parent3d07f0e83d4323d2cd45cc583f7cf1957aca3cac (diff)
parent39ab05c8e0b519ff0a04a869f065746e6e8c3d95 (diff)
Merge remote branch 'origin/master' into merge
Manual merge of arch/powerpc/kernel/smp.c and add missing scheduler_ipi() call to arch/powerpc/platforms/cell/interrupt.c Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/Kconfig2
-rw-r--r--drivers/firmware/Makefile2
-rw-r--r--drivers/firmware/edd.c22
-rw-r--r--drivers/firmware/efivars.c21
-rw-r--r--drivers/firmware/google/Kconfig31
-rw-r--r--drivers/firmware/google/Makefile3
-rw-r--r--drivers/firmware/google/gsmi.c940
-rw-r--r--drivers/firmware/google/memconsole.c166
-rw-r--r--drivers/firmware/iscsi_ibft_find.c51
9 files changed, 1202 insertions, 36 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index b3a25a55ba23..efba163595db 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -157,4 +157,6 @@ config SIGMA
157 If unsure, say N here. Drivers that need these helpers will select 157 If unsure, say N here. Drivers that need these helpers will select
158 this option automatically. 158 this option automatically.
159 159
160source "drivers/firmware/google/Kconfig"
161
160endmenu 162endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 00bb0b80a79f..47338c979126 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
13obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o 13obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o 14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
15obj-$(CONFIG_SIGMA) += sigma.o 15obj-$(CONFIG_SIGMA) += sigma.o
16
17obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 96c25d93eed1..f1b7f659d3c9 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -531,8 +531,8 @@ static int
531edd_has_edd30(struct edd_device *edev) 531edd_has_edd30(struct edd_device *edev)
532{ 532{
533 struct edd_info *info; 533 struct edd_info *info;
534 int i, nonzero_path = 0; 534 int i;
535 char c; 535 u8 csum = 0;
536 536
537 if (!edev) 537 if (!edev)
538 return 0; 538 return 0;
@@ -544,16 +544,16 @@ edd_has_edd30(struct edd_device *edev)
544 return 0; 544 return 0;
545 } 545 }
546 546
547 for (i = 30; i <= 73; i++) { 547
548 c = *(((uint8_t *) info) + i + 4); 548 /* We support only T13 spec */
549 if (c) { 549 if (info->params.device_path_info_length != 44)
550 nonzero_path++; 550 return 0;
551 break; 551
552 } 552 for (i = 30; i < info->params.device_path_info_length + 30; i++)
553 } 553 csum += *(((u8 *)&info->params) + i);
554 if (!nonzero_path) { 554
555 if (csum)
555 return 0; 556 return 0;
556 }
557 557
558 return 1; 558 return 1;
559} 559}
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index ff0c373e3bbf..a2d2f1f0d4f3 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -677,8 +677,8 @@ create_efivars_bin_attributes(struct efivars *efivars)
677 677
678 return 0; 678 return 0;
679out_free: 679out_free:
680 kfree(efivars->new_var); 680 kfree(efivars->del_var);
681 efivars->new_var = NULL; 681 efivars->del_var = NULL;
682 kfree(efivars->new_var); 682 kfree(efivars->new_var);
683 efivars->new_var = NULL; 683 efivars->new_var = NULL;
684 return error; 684 return error;
@@ -803,6 +803,8 @@ efivars_init(void)
803 ops.set_variable = efi.set_variable; 803 ops.set_variable = efi.set_variable;
804 ops.get_next_variable = efi.get_next_variable; 804 ops.get_next_variable = efi.get_next_variable;
805 error = register_efivars(&__efivars, &ops, efi_kobj); 805 error = register_efivars(&__efivars, &ops, efi_kobj);
806 if (error)
807 goto err_put;
806 808
807 /* Don't forget the systab entry */ 809 /* Don't forget the systab entry */
808 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); 810 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
@@ -810,18 +812,25 @@ efivars_init(void)
810 printk(KERN_ERR 812 printk(KERN_ERR
811 "efivars: Sysfs attribute export failed with error %d.\n", 813 "efivars: Sysfs attribute export failed with error %d.\n",
812 error); 814 error);
813 unregister_efivars(&__efivars); 815 goto err_unregister;
814 kobject_put(efi_kobj);
815 } 816 }
816 817
818 return 0;
819
820err_unregister:
821 unregister_efivars(&__efivars);
822err_put:
823 kobject_put(efi_kobj);
817 return error; 824 return error;
818} 825}
819 826
820static void __exit 827static void __exit
821efivars_exit(void) 828efivars_exit(void)
822{ 829{
823 unregister_efivars(&__efivars); 830 if (efi_enabled) {
824 kobject_put(efi_kobj); 831 unregister_efivars(&__efivars);
832 kobject_put(efi_kobj);
833 }
825} 834}
826 835
827module_init(efivars_init); 836module_init(efivars_init);
diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
new file mode 100644
index 000000000000..87096b6ca5c9
--- /dev/null
+++ b/drivers/firmware/google/Kconfig
@@ -0,0 +1,31 @@
1config GOOGLE_FIRMWARE
2 bool "Google Firmware Drivers"
3 depends on X86
4 default n
5 help
6 These firmware drivers are used by Google's servers. They are
7 only useful if you are working directly on one of their
8 proprietary servers. If in doubt, say "N".
9
10menu "Google Firmware Drivers"
11 depends on GOOGLE_FIRMWARE
12
13config GOOGLE_SMI
14 tristate "SMI interface for Google platforms"
15 depends on ACPI && DMI
16 select EFI_VARS
17 help
18 Say Y here if you want to enable SMI callbacks for Google
19 platforms. This provides an interface for writing to and
20 clearing the EFI event log and reading and writing NVRAM
21 variables.
22
23config GOOGLE_MEMCONSOLE
24 tristate "Firmware Memory Console"
25 depends on DMI
26 help
27 This option enables the kernel to search for a firmware log in
28 the EBDA on Google servers. If found, this log is exported to
29 userland in the file /sys/firmware/log.
30
31endmenu
diff --git a/drivers/firmware/google/Makefile b/drivers/firmware/google/Makefile
new file mode 100644
index 000000000000..54a294e3cb61
--- /dev/null
+++ b/drivers/firmware/google/Makefile
@@ -0,0 +1,3 @@
1
2obj-$(CONFIG_GOOGLE_SMI) += gsmi.o
3obj-$(CONFIG_GOOGLE_MEMCONSOLE) += memconsole.o
diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
new file mode 100644
index 000000000000..fa7f0b3e81dd
--- /dev/null
+++ b/drivers/firmware/google/gsmi.c
@@ -0,0 +1,940 @@
1/*
2 * Copyright 2010 Google Inc. All Rights Reserved.
3 * Author: dlaurie@google.com (Duncan Laurie)
4 *
5 * Re-worked to expose sysfs APIs by mikew@google.com (Mike Waychison)
6 *
7 * EFI SMI interface for Google platforms
8 */
9
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/types.h>
13#include <linux/device.h>
14#include <linux/platform_device.h>
15#include <linux/errno.h>
16#include <linux/string.h>
17#include <linux/spinlock.h>
18#include <linux/dma-mapping.h>
19#include <linux/dmapool.h>
20#include <linux/fs.h>
21#include <linux/slab.h>
22#include <linux/ioctl.h>
23#include <linux/acpi.h>
24#include <linux/io.h>
25#include <linux/uaccess.h>
26#include <linux/dmi.h>
27#include <linux/kdebug.h>
28#include <linux/reboot.h>
29#include <linux/efi.h>
30
31#define GSMI_SHUTDOWN_CLEAN 0 /* Clean Shutdown */
32/* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
33#define GSMI_SHUTDOWN_NMIWDT 1 /* NMI Watchdog */
34#define GSMI_SHUTDOWN_PANIC 2 /* Panic */
35#define GSMI_SHUTDOWN_OOPS 3 /* Oops */
36#define GSMI_SHUTDOWN_DIE 4 /* Die -- No longer meaningful */
37#define GSMI_SHUTDOWN_MCE 5 /* Machine Check */
38#define GSMI_SHUTDOWN_SOFTWDT 6 /* Software Watchdog */
39#define GSMI_SHUTDOWN_MBE 7 /* Uncorrected ECC */
40#define GSMI_SHUTDOWN_TRIPLE 8 /* Triple Fault */
41
42#define DRIVER_VERSION "1.0"
43#define GSMI_GUID_SIZE 16
44#define GSMI_BUF_SIZE 1024
45#define GSMI_BUF_ALIGN sizeof(u64)
46#define GSMI_CALLBACK 0xef
47
48/* SMI return codes */
49#define GSMI_SUCCESS 0x00
50#define GSMI_UNSUPPORTED2 0x03
51#define GSMI_LOG_FULL 0x0b
52#define GSMI_VAR_NOT_FOUND 0x0e
53#define GSMI_HANDSHAKE_SPIN 0x7d
54#define GSMI_HANDSHAKE_CF 0x7e
55#define GSMI_HANDSHAKE_NONE 0x7f
56#define GSMI_INVALID_PARAMETER 0x82
57#define GSMI_UNSUPPORTED 0x83
58#define GSMI_BUFFER_TOO_SMALL 0x85
59#define GSMI_NOT_READY 0x86
60#define GSMI_DEVICE_ERROR 0x87
61#define GSMI_NOT_FOUND 0x8e
62
63#define QUIRKY_BOARD_HASH 0x78a30a50
64
65/* Internally used commands passed to the firmware */
66#define GSMI_CMD_GET_NVRAM_VAR 0x01
67#define GSMI_CMD_GET_NEXT_VAR 0x02
68#define GSMI_CMD_SET_NVRAM_VAR 0x03
69#define GSMI_CMD_SET_EVENT_LOG 0x08
70#define GSMI_CMD_CLEAR_EVENT_LOG 0x09
71#define GSMI_CMD_CLEAR_CONFIG 0x20
72#define GSMI_CMD_HANDSHAKE_TYPE 0xC1
73
74/* Magic entry type for kernel events */
75#define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
76
77/* SMI buffers must be in 32bit physical address space */
78struct gsmi_buf {
79 u8 *start; /* start of buffer */
80 size_t length; /* length of buffer */
81 dma_addr_t handle; /* dma allocation handle */
82 u32 address; /* physical address of buffer */
83};
84
85struct gsmi_device {
86 struct platform_device *pdev; /* platform device */
87 struct gsmi_buf *name_buf; /* variable name buffer */
88 struct gsmi_buf *data_buf; /* generic data buffer */
89 struct gsmi_buf *param_buf; /* parameter buffer */
90 spinlock_t lock; /* serialize access to SMIs */
91 u16 smi_cmd; /* SMI command port */
92 int handshake_type; /* firmware handler interlock type */
93 struct dma_pool *dma_pool; /* DMA buffer pool */
94} gsmi_dev;
95
96/* Packed structures for communicating with the firmware */
97struct gsmi_nvram_var_param {
98 efi_guid_t guid;
99 u32 name_ptr;
100 u32 attributes;
101 u32 data_len;
102 u32 data_ptr;
103} __packed;
104
105struct gsmi_get_next_var_param {
106 u8 guid[GSMI_GUID_SIZE];
107 u32 name_ptr;
108 u32 name_len;
109} __packed;
110
111struct gsmi_set_eventlog_param {
112 u32 data_ptr;
113 u32 data_len;
114 u32 type;
115} __packed;
116
117/* Event log formats */
118struct gsmi_log_entry_type_1 {
119 u16 type;
120 u32 instance;
121} __packed;
122
123
124/*
125 * Some platforms don't have explicit SMI handshake
126 * and need to wait for SMI to complete.
127 */
128#define GSMI_DEFAULT_SPINCOUNT 0x10000
129static unsigned int spincount = GSMI_DEFAULT_SPINCOUNT;
130module_param(spincount, uint, 0600);
131MODULE_PARM_DESC(spincount,
132 "The number of loop iterations to use when using the spin handshake.");
133
134static struct gsmi_buf *gsmi_buf_alloc(void)
135{
136 struct gsmi_buf *smibuf;
137
138 smibuf = kzalloc(sizeof(*smibuf), GFP_KERNEL);
139 if (!smibuf) {
140 printk(KERN_ERR "gsmi: out of memory\n");
141 return NULL;
142 }
143
144 /* allocate buffer in 32bit address space */
145 smibuf->start = dma_pool_alloc(gsmi_dev.dma_pool, GFP_KERNEL,
146 &smibuf->handle);
147 if (!smibuf->start) {
148 printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
149 kfree(smibuf);
150 return NULL;
151 }
152
153 /* fill in the buffer handle */
154 smibuf->length = GSMI_BUF_SIZE;
155 smibuf->address = (u32)virt_to_phys(smibuf->start);
156
157 return smibuf;
158}
159
160static void gsmi_buf_free(struct gsmi_buf *smibuf)
161{
162 if (smibuf) {
163 if (smibuf->start)
164 dma_pool_free(gsmi_dev.dma_pool, smibuf->start,
165 smibuf->handle);
166 kfree(smibuf);
167 }
168}
169
170/*
171 * Make a call to gsmi func(sub). GSMI error codes are translated to
172 * in-kernel errnos (0 on success, -ERRNO on error).
173 */
174static int gsmi_exec(u8 func, u8 sub)
175{
176 u16 cmd = (sub << 8) | func;
177 u16 result = 0;
178 int rc = 0;
179
180 /*
181 * AH : Subfunction number
182 * AL : Function number
183 * EBX : Parameter block address
184 * DX : SMI command port
185 *
186 * Three protocols here. See also the comment in gsmi_init().
187 */
188 if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_CF) {
189 /*
190 * If handshake_type == HANDSHAKE_CF then set CF on the
191 * way in and wait for the handler to clear it; this avoids
192 * corrupting register state on those chipsets which have
193 * a delay between writing the SMI trigger register and
194 * entering SMM.
195 */
196 asm volatile (
197 "stc\n"
198 "outb %%al, %%dx\n"
199 "1: jc 1b\n"
200 : "=a" (result)
201 : "0" (cmd),
202 "d" (gsmi_dev.smi_cmd),
203 "b" (gsmi_dev.param_buf->address)
204 : "memory", "cc"
205 );
206 } else if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_SPIN) {
207 /*
208 * If handshake_type == HANDSHAKE_SPIN we spin a
209 * hundred-ish usecs to ensure the SMI has triggered.
210 */
211 asm volatile (
212 "outb %%al, %%dx\n"
213 "1: loop 1b\n"
214 : "=a" (result)
215 : "0" (cmd),
216 "d" (gsmi_dev.smi_cmd),
217 "b" (gsmi_dev.param_buf->address),
218 "c" (spincount)
219 : "memory", "cc"
220 );
221 } else {
222 /*
223 * If handshake_type == HANDSHAKE_NONE we do nothing;
224 * either we don't need to or it's legacy firmware that
225 * doesn't understand the CF protocol.
226 */
227 asm volatile (
228 "outb %%al, %%dx\n\t"
229 : "=a" (result)
230 : "0" (cmd),
231 "d" (gsmi_dev.smi_cmd),
232 "b" (gsmi_dev.param_buf->address)
233 : "memory", "cc"
234 );
235 }
236
237 /* check return code from SMI handler */
238 switch (result) {
239 case GSMI_SUCCESS:
240 break;
241 case GSMI_VAR_NOT_FOUND:
242 /* not really an error, but let the caller know */
243 rc = 1;
244 break;
245 case GSMI_INVALID_PARAMETER:
246 printk(KERN_ERR "gsmi: exec 0x%04x: Invalid parameter\n", cmd);
247 rc = -EINVAL;
248 break;
249 case GSMI_BUFFER_TOO_SMALL:
250 printk(KERN_ERR "gsmi: exec 0x%04x: Buffer too small\n", cmd);
251 rc = -ENOMEM;
252 break;
253 case GSMI_UNSUPPORTED:
254 case GSMI_UNSUPPORTED2:
255 if (sub != GSMI_CMD_HANDSHAKE_TYPE)
256 printk(KERN_ERR "gsmi: exec 0x%04x: Not supported\n",
257 cmd);
258 rc = -ENOSYS;
259 break;
260 case GSMI_NOT_READY:
261 printk(KERN_ERR "gsmi: exec 0x%04x: Not ready\n", cmd);
262 rc = -EBUSY;
263 break;
264 case GSMI_DEVICE_ERROR:
265 printk(KERN_ERR "gsmi: exec 0x%04x: Device error\n", cmd);
266 rc = -EFAULT;
267 break;
268 case GSMI_NOT_FOUND:
269 printk(KERN_ERR "gsmi: exec 0x%04x: Data not found\n", cmd);
270 rc = -ENOENT;
271 break;
272 case GSMI_LOG_FULL:
273 printk(KERN_ERR "gsmi: exec 0x%04x: Log full\n", cmd);
274 rc = -ENOSPC;
275 break;
276 case GSMI_HANDSHAKE_CF:
277 case GSMI_HANDSHAKE_SPIN:
278 case GSMI_HANDSHAKE_NONE:
279 rc = result;
280 break;
281 default:
282 printk(KERN_ERR "gsmi: exec 0x%04x: Unknown error 0x%04x\n",
283 cmd, result);
284 rc = -ENXIO;
285 }
286
287 return rc;
288}
289
290/* Return the number of unicode characters in data */
291static size_t
292utf16_strlen(efi_char16_t *data, unsigned long maxlength)
293{
294 unsigned long length = 0;
295
296 while (*data++ != 0 && length < maxlength)
297 length++;
298 return length;
299}
300
301static efi_status_t gsmi_get_variable(efi_char16_t *name,
302 efi_guid_t *vendor, u32 *attr,
303 unsigned long *data_size,
304 void *data)
305{
306 struct gsmi_nvram_var_param param = {
307 .name_ptr = gsmi_dev.name_buf->address,
308 .data_ptr = gsmi_dev.data_buf->address,
309 .data_len = (u32)*data_size,
310 };
311 efi_status_t ret = EFI_SUCCESS;
312 unsigned long flags;
313 size_t name_len = utf16_strlen(name, GSMI_BUF_SIZE / 2);
314 int rc;
315
316 if (name_len >= GSMI_BUF_SIZE / 2)
317 return EFI_BAD_BUFFER_SIZE;
318
319 spin_lock_irqsave(&gsmi_dev.lock, flags);
320
321 /* Vendor guid */
322 memcpy(&param.guid, vendor, sizeof(param.guid));
323
324 /* variable name, already in UTF-16 */
325 memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
326 memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
327
328 /* data pointer */
329 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
330
331 /* parameter buffer */
332 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
333 memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
334
335 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NVRAM_VAR);
336 if (rc < 0) {
337 printk(KERN_ERR "gsmi: Get Variable failed\n");
338 ret = EFI_LOAD_ERROR;
339 } else if (rc == 1) {
340 /* variable was not found */
341 ret = EFI_NOT_FOUND;
342 } else {
343 /* Get the arguments back */
344 memcpy(&param, gsmi_dev.param_buf->start, sizeof(param));
345
346 /* The size reported is the min of all of our buffers */
347 *data_size = min(*data_size, gsmi_dev.data_buf->length);
348 *data_size = min_t(unsigned long, *data_size, param.data_len);
349
350 /* Copy data back to return buffer. */
351 memcpy(data, gsmi_dev.data_buf->start, *data_size);
352
353 /* All variables are have the following attributes */
354 *attr = EFI_VARIABLE_NON_VOLATILE |
355 EFI_VARIABLE_BOOTSERVICE_ACCESS |
356 EFI_VARIABLE_RUNTIME_ACCESS;
357 }
358
359 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
360
361 return ret;
362}
363
364static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
365 efi_char16_t *name,
366 efi_guid_t *vendor)
367{
368 struct gsmi_get_next_var_param param = {
369 .name_ptr = gsmi_dev.name_buf->address,
370 .name_len = gsmi_dev.name_buf->length,
371 };
372 efi_status_t ret = EFI_SUCCESS;
373 int rc;
374 unsigned long flags;
375
376 /* For the moment, only support buffers that exactly match in size */
377 if (*name_size != GSMI_BUF_SIZE)
378 return EFI_BAD_BUFFER_SIZE;
379
380 /* Let's make sure the thing is at least null-terminated */
381 if (utf16_strlen(name, GSMI_BUF_SIZE / 2) == GSMI_BUF_SIZE / 2)
382 return EFI_INVALID_PARAMETER;
383
384 spin_lock_irqsave(&gsmi_dev.lock, flags);
385
386 /* guid */
387 memcpy(&param.guid, vendor, sizeof(param.guid));
388
389 /* variable name, already in UTF-16 */
390 memcpy(gsmi_dev.name_buf->start, name, *name_size);
391
392 /* parameter buffer */
393 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
394 memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
395
396 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NEXT_VAR);
397 if (rc < 0) {
398 printk(KERN_ERR "gsmi: Get Next Variable Name failed\n");
399 ret = EFI_LOAD_ERROR;
400 } else if (rc == 1) {
401 /* variable not found -- end of list */
402 ret = EFI_NOT_FOUND;
403 } else {
404 /* copy variable data back to return buffer */
405 memcpy(&param, gsmi_dev.param_buf->start, sizeof(param));
406
407 /* Copy the name back */
408 memcpy(name, gsmi_dev.name_buf->start, GSMI_BUF_SIZE);
409 *name_size = utf16_strlen(name, GSMI_BUF_SIZE / 2) * 2;
410
411 /* copy guid to return buffer */
412 memcpy(vendor, &param.guid, sizeof(param.guid));
413 ret = EFI_SUCCESS;
414 }
415
416 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
417
418 return ret;
419}
420
421static efi_status_t gsmi_set_variable(efi_char16_t *name,
422 efi_guid_t *vendor,
423 unsigned long attr,
424 unsigned long data_size,
425 void *data)
426{
427 struct gsmi_nvram_var_param param = {
428 .name_ptr = gsmi_dev.name_buf->address,
429 .data_ptr = gsmi_dev.data_buf->address,
430 .data_len = (u32)data_size,
431 .attributes = EFI_VARIABLE_NON_VOLATILE |
432 EFI_VARIABLE_BOOTSERVICE_ACCESS |
433 EFI_VARIABLE_RUNTIME_ACCESS,
434 };
435 size_t name_len = utf16_strlen(name, GSMI_BUF_SIZE / 2);
436 efi_status_t ret = EFI_SUCCESS;
437 int rc;
438 unsigned long flags;
439
440 if (name_len >= GSMI_BUF_SIZE / 2)
441 return EFI_BAD_BUFFER_SIZE;
442
443 spin_lock_irqsave(&gsmi_dev.lock, flags);
444
445 /* guid */
446 memcpy(&param.guid, vendor, sizeof(param.guid));
447
448 /* variable name, already in UTF-16 */
449 memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
450 memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
451
452 /* data pointer */
453 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
454 memcpy(gsmi_dev.data_buf->start, data, data_size);
455
456 /* parameter buffer */
457 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
458 memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
459
460 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_NVRAM_VAR);
461 if (rc < 0) {
462 printk(KERN_ERR "gsmi: Set Variable failed\n");
463 ret = EFI_INVALID_PARAMETER;
464 }
465
466 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
467
468 return ret;
469}
470
471static const struct efivar_operations efivar_ops = {
472 .get_variable = gsmi_get_variable,
473 .set_variable = gsmi_set_variable,
474 .get_next_variable = gsmi_get_next_variable,
475};
476
477static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
478 struct bin_attribute *bin_attr,
479 char *buf, loff_t pos, size_t count)
480{
481 struct gsmi_set_eventlog_param param = {
482 .data_ptr = gsmi_dev.data_buf->address,
483 };
484 int rc = 0;
485 unsigned long flags;
486
487 /* Pull the type out */
488 if (count < sizeof(u32))
489 return -EINVAL;
490 param.type = *(u32 *)buf;
491 count -= sizeof(u32);
492 buf += sizeof(u32);
493
494 /* The remaining buffer is the data payload */
495 if (count > gsmi_dev.data_buf->length)
496 return -EINVAL;
497 param.data_len = count - sizeof(u32);
498
499 spin_lock_irqsave(&gsmi_dev.lock, flags);
500
501 /* data pointer */
502 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
503 memcpy(gsmi_dev.data_buf->start, buf, param.data_len);
504
505 /* parameter buffer */
506 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
507 memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
508
509 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
510 if (rc < 0)
511 printk(KERN_ERR "gsmi: Set Event Log failed\n");
512
513 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
514
515 return rc;
516
517}
518
519static struct bin_attribute eventlog_bin_attr = {
520 .attr = {.name = "append_to_eventlog", .mode = 0200},
521 .write = eventlog_write,
522};
523
524static ssize_t gsmi_clear_eventlog_store(struct kobject *kobj,
525 struct kobj_attribute *attr,
526 const char *buf, size_t count)
527{
528 int rc;
529 unsigned long flags;
530 unsigned long val;
531 struct {
532 u32 percentage;
533 u32 data_type;
534 } param;
535
536 rc = strict_strtoul(buf, 0, &val);
537 if (rc)
538 return rc;
539
540 /*
541 * Value entered is a percentage, 0 through 100, anything else
542 * is invalid.
543 */
544 if (val > 100)
545 return -EINVAL;
546
547 /* data_type here selects the smbios event log. */
548 param.percentage = val;
549 param.data_type = 0;
550
551 spin_lock_irqsave(&gsmi_dev.lock, flags);
552
553 /* parameter buffer */
554 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
555 memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
556
557 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_EVENT_LOG);
558
559 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
560
561 if (rc)
562 return rc;
563 return count;
564}
565
566static struct kobj_attribute gsmi_clear_eventlog_attr = {
567 .attr = {.name = "clear_eventlog", .mode = 0200},
568 .store = gsmi_clear_eventlog_store,
569};
570
571static ssize_t gsmi_clear_config_store(struct kobject *kobj,
572 struct kobj_attribute *attr,
573 const char *buf, size_t count)
574{
575 int rc;
576 unsigned long flags;
577
578 spin_lock_irqsave(&gsmi_dev.lock, flags);
579
580 /* clear parameter buffer */
581 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
582
583 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_CONFIG);
584
585 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
586
587 if (rc)
588 return rc;
589 return count;
590}
591
592static struct kobj_attribute gsmi_clear_config_attr = {
593 .attr = {.name = "clear_config", .mode = 0200},
594 .store = gsmi_clear_config_store,
595};
596
597static const struct attribute *gsmi_attrs[] = {
598 &gsmi_clear_config_attr.attr,
599 &gsmi_clear_eventlog_attr.attr,
600 NULL,
601};
602
603static int gsmi_shutdown_reason(int reason)
604{
605 struct gsmi_log_entry_type_1 entry = {
606 .type = GSMI_LOG_ENTRY_TYPE_KERNEL,
607 .instance = reason,
608 };
609 struct gsmi_set_eventlog_param param = {
610 .data_len = sizeof(entry),
611 .type = 1,
612 };
613 static int saved_reason;
614 int rc = 0;
615 unsigned long flags;
616
617 /* avoid duplicate entries in the log */
618 if (saved_reason & (1 << reason))
619 return 0;
620
621 spin_lock_irqsave(&gsmi_dev.lock, flags);
622
623 saved_reason |= (1 << reason);
624
625 /* data pointer */
626 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
627 memcpy(gsmi_dev.data_buf->start, &entry, sizeof(entry));
628
629 /* parameter buffer */
630 param.data_ptr = gsmi_dev.data_buf->address;
631 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
632 memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
633
634 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
635
636 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
637
638 if (rc < 0)
639 printk(KERN_ERR "gsmi: Log Shutdown Reason failed\n");
640 else
641 printk(KERN_EMERG "gsmi: Log Shutdown Reason 0x%02x\n",
642 reason);
643
644 return rc;
645}
646
647static int gsmi_reboot_callback(struct notifier_block *nb,
648 unsigned long reason, void *arg)
649{
650 gsmi_shutdown_reason(GSMI_SHUTDOWN_CLEAN);
651 return NOTIFY_DONE;
652}
653
654static struct notifier_block gsmi_reboot_notifier = {
655 .notifier_call = gsmi_reboot_callback
656};
657
658static int gsmi_die_callback(struct notifier_block *nb,
659 unsigned long reason, void *arg)
660{
661 if (reason == DIE_OOPS)
662 gsmi_shutdown_reason(GSMI_SHUTDOWN_OOPS);
663 return NOTIFY_DONE;
664}
665
666static struct notifier_block gsmi_die_notifier = {
667 .notifier_call = gsmi_die_callback
668};
669
670static int gsmi_panic_callback(struct notifier_block *nb,
671 unsigned long reason, void *arg)
672{
673 gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
674 return NOTIFY_DONE;
675}
676
677static struct notifier_block gsmi_panic_notifier = {
678 .notifier_call = gsmi_panic_callback,
679};
680
681/*
682 * This hash function was blatantly copied from include/linux/hash.h.
683 * It is used by this driver to obfuscate a board name that requires a
684 * quirk within this driver.
685 *
686 * Please do not remove this copy of the function as any changes to the
687 * global utility hash_64() function would break this driver's ability
688 * to identify a board and provide the appropriate quirk -- mikew@google.com
689 */
690static u64 __init local_hash_64(u64 val, unsigned bits)
691{
692 u64 hash = val;
693
694 /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
695 u64 n = hash;
696 n <<= 18;
697 hash -= n;
698 n <<= 33;
699 hash -= n;
700 n <<= 3;
701 hash += n;
702 n <<= 3;
703 hash -= n;
704 n <<= 4;
705 hash += n;
706 n <<= 2;
707 hash += n;
708
709 /* High bits are more random, so use them. */
710 return hash >> (64 - bits);
711}
712
713static u32 __init hash_oem_table_id(char s[8])
714{
715 u64 input;
716 memcpy(&input, s, 8);
717 return local_hash_64(input, 32);
718}
719
720static struct dmi_system_id gsmi_dmi_table[] __initdata = {
721 {
722 .ident = "Google Board",
723 .matches = {
724 DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
725 },
726 },
727 {}
728};
729MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
730
731static __init int gsmi_system_valid(void)
732{
733 u32 hash;
734
735 if (!dmi_check_system(gsmi_dmi_table))
736 return -ENODEV;
737
738 /*
739 * Only newer firmware supports the gsmi interface. All older
740 * firmware that didn't support this interface used to plug the
741 * table name in the first four bytes of the oem_table_id field.
742 * Newer firmware doesn't do that though, so use that as the
743 * discriminant factor. We have to do this in order to
744 * whitewash our board names out of the public driver.
745 */
746 if (!strncmp(acpi_gbl_FADT.header.oem_table_id, "FACP", 4)) {
747 printk(KERN_INFO "gsmi: Board is too old\n");
748 return -ENODEV;
749 }
750
751 /* Disable on board with 1.0 BIOS due to Google bug 2602657 */
752 hash = hash_oem_table_id(acpi_gbl_FADT.header.oem_table_id);
753 if (hash == QUIRKY_BOARD_HASH) {
754 const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
755 if (strncmp(bios_ver, "1.0", 3) == 0) {
756 pr_info("gsmi: disabled on this board's BIOS %s\n",
757 bios_ver);
758 return -ENODEV;
759 }
760 }
761
762 /* check for valid SMI command port in ACPI FADT */
763 if (acpi_gbl_FADT.smi_command == 0) {
764 pr_info("gsmi: missing smi_command\n");
765 return -ENODEV;
766 }
767
768 /* Found */
769 return 0;
770}
771
772static struct kobject *gsmi_kobj;
773static struct efivars efivars;
774
775static __init int gsmi_init(void)
776{
777 unsigned long flags;
778 int ret;
779
780 ret = gsmi_system_valid();
781 if (ret)
782 return ret;
783
784 gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
785
786 /* register device */
787 gsmi_dev.pdev = platform_device_register_simple("gsmi", -1, NULL, 0);
788 if (IS_ERR(gsmi_dev.pdev)) {
789 printk(KERN_ERR "gsmi: unable to register platform device\n");
790 return PTR_ERR(gsmi_dev.pdev);
791 }
792
793 /* SMI access needs to be serialized */
794 spin_lock_init(&gsmi_dev.lock);
795
796 /* SMI callbacks require 32bit addresses */
797 gsmi_dev.pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
798 gsmi_dev.pdev->dev.dma_mask =
799 &gsmi_dev.pdev->dev.coherent_dma_mask;
800 ret = -ENOMEM;
801 gsmi_dev.dma_pool = dma_pool_create("gsmi", &gsmi_dev.pdev->dev,
802 GSMI_BUF_SIZE, GSMI_BUF_ALIGN, 0);
803 if (!gsmi_dev.dma_pool)
804 goto out_err;
805
806 /*
807 * pre-allocate buffers because sometimes we are called when
808 * this is not feasible: oops, panic, die, mce, etc
809 */
810 gsmi_dev.name_buf = gsmi_buf_alloc();
811 if (!gsmi_dev.name_buf) {
812 printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
813 goto out_err;
814 }
815
816 gsmi_dev.data_buf = gsmi_buf_alloc();
817 if (!gsmi_dev.data_buf) {
818 printk(KERN_ERR "gsmi: failed to allocate data buffer\n");
819 goto out_err;
820 }
821
822 gsmi_dev.param_buf = gsmi_buf_alloc();
823 if (!gsmi_dev.param_buf) {
824 printk(KERN_ERR "gsmi: failed to allocate param buffer\n");
825 goto out_err;
826 }
827
828 /*
829 * Determine type of handshake used to serialize the SMI
830 * entry. See also gsmi_exec().
831 *
832 * There's a "behavior" present on some chipsets where writing the
833 * SMI trigger register in the southbridge doesn't result in an
834 * immediate SMI. Rather, the processor can execute "a few" more
835 * instructions before the SMI takes effect. To ensure synchronous
836 * behavior, implement a handshake between the kernel driver and the
837 * firmware handler to spin until released. This ioctl determines
838 * the type of handshake.
839 *
840 * NONE: The firmware handler does not implement any
841 * handshake. Either it doesn't need to, or it's legacy firmware
842 * that doesn't know it needs to and never will.
843 *
844 * CF: The firmware handler will clear the CF in the saved
845 * state before returning. The driver may set the CF and test for
846 * it to clear before proceeding.
847 *
848 * SPIN: The firmware handler does not implement any handshake
849 * but the driver should spin for a hundred or so microseconds
850 * to ensure the SMI has triggered.
851 *
852 * Finally, the handler will return -ENOSYS if
853 * GSMI_CMD_HANDSHAKE_TYPE is unimplemented, which implies
854 * HANDSHAKE_NONE.
855 */
856 spin_lock_irqsave(&gsmi_dev.lock, flags);
857 gsmi_dev.handshake_type = GSMI_HANDSHAKE_SPIN;
858 gsmi_dev.handshake_type =
859 gsmi_exec(GSMI_CALLBACK, GSMI_CMD_HANDSHAKE_TYPE);
860 if (gsmi_dev.handshake_type == -ENOSYS)
861 gsmi_dev.handshake_type = GSMI_HANDSHAKE_NONE;
862 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
863
864 /* Remove and clean up gsmi if the handshake could not complete. */
865 if (gsmi_dev.handshake_type == -ENXIO) {
866 printk(KERN_INFO "gsmi version " DRIVER_VERSION
867 " failed to load\n");
868 ret = -ENODEV;
869 goto out_err;
870 }
871
872 printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
873
874 /* Register in the firmware directory */
875 ret = -ENOMEM;
876 gsmi_kobj = kobject_create_and_add("gsmi", firmware_kobj);
877 if (!gsmi_kobj) {
878 printk(KERN_INFO "gsmi: Failed to create firmware kobj\n");
879 goto out_err;
880 }
881
882 /* Setup eventlog access */
883 ret = sysfs_create_bin_file(gsmi_kobj, &eventlog_bin_attr);
884 if (ret) {
885 printk(KERN_INFO "gsmi: Failed to setup eventlog");
886 goto out_err;
887 }
888
889 /* Other attributes */
890 ret = sysfs_create_files(gsmi_kobj, gsmi_attrs);
891 if (ret) {
892 printk(KERN_INFO "gsmi: Failed to add attrs");
893 goto out_err;
894 }
895
896 if (register_efivars(&efivars, &efivar_ops, gsmi_kobj)) {
897 printk(KERN_INFO "gsmi: Failed to register efivars\n");
898 goto out_err;
899 }
900
901 register_reboot_notifier(&gsmi_reboot_notifier);
902 register_die_notifier(&gsmi_die_notifier);
903 atomic_notifier_chain_register(&panic_notifier_list,
904 &gsmi_panic_notifier);
905
906 return 0;
907
908 out_err:
909 kobject_put(gsmi_kobj);
910 gsmi_buf_free(gsmi_dev.param_buf);
911 gsmi_buf_free(gsmi_dev.data_buf);
912 gsmi_buf_free(gsmi_dev.name_buf);
913 if (gsmi_dev.dma_pool)
914 dma_pool_destroy(gsmi_dev.dma_pool);
915 platform_device_unregister(gsmi_dev.pdev);
916 pr_info("gsmi: failed to load: %d\n", ret);
917 return ret;
918}
919
920static void __exit gsmi_exit(void)
921{
922 unregister_reboot_notifier(&gsmi_reboot_notifier);
923 unregister_die_notifier(&gsmi_die_notifier);
924 atomic_notifier_chain_unregister(&panic_notifier_list,
925 &gsmi_panic_notifier);
926 unregister_efivars(&efivars);
927
928 kobject_put(gsmi_kobj);
929 gsmi_buf_free(gsmi_dev.param_buf);
930 gsmi_buf_free(gsmi_dev.data_buf);
931 gsmi_buf_free(gsmi_dev.name_buf);
932 dma_pool_destroy(gsmi_dev.dma_pool);
933 platform_device_unregister(gsmi_dev.pdev);
934}
935
936module_init(gsmi_init);
937module_exit(gsmi_exit);
938
939MODULE_AUTHOR("Google, Inc.");
940MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
new file mode 100644
index 000000000000..2a90ba613613
--- /dev/null
+++ b/drivers/firmware/google/memconsole.c
@@ -0,0 +1,166 @@
1/*
2 * memconsole.c
3 *
4 * Infrastructure for importing the BIOS memory based console
5 * into the kernel log ringbuffer.
6 *
7 * Copyright 2010 Google Inc. All rights reserved.
8 */
9
10#include <linux/ctype.h>
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/string.h>
14#include <linux/sysfs.h>
15#include <linux/kobject.h>
16#include <linux/module.h>
17#include <linux/dmi.h>
18#include <asm/bios_ebda.h>
19
20#define BIOS_MEMCONSOLE_V1_MAGIC 0xDEADBABE
21#define BIOS_MEMCONSOLE_V2_MAGIC (('M')|('C'<<8)|('O'<<16)|('N'<<24))
22
23struct biosmemcon_ebda {
24 u32 signature;
25 union {
26 struct {
27 u8 enabled;
28 u32 buffer_addr;
29 u16 start;
30 u16 end;
31 u16 num_chars;
32 u8 wrapped;
33 } __packed v1;
34 struct {
35 u32 buffer_addr;
36 /* Misdocumented as number of pages! */
37 u16 num_bytes;
38 u16 start;
39 u16 end;
40 } __packed v2;
41 };
42} __packed;
43
44static char *memconsole_baseaddr;
45static size_t memconsole_length;
46
47static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
48 struct bin_attribute *bin_attr, char *buf,
49 loff_t pos, size_t count)
50{
51 return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr,
52 memconsole_length);
53}
54
55static struct bin_attribute memconsole_bin_attr = {
56 .attr = {.name = "log", .mode = 0444},
57 .read = memconsole_read,
58};
59
60
61static void found_v1_header(struct biosmemcon_ebda *hdr)
62{
63 printk(KERN_INFO "BIOS console v1 EBDA structure found at %p\n", hdr);
64 printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
65 "start = %d, end = %d, num = %d\n",
66 hdr->v1.buffer_addr, hdr->v1.start,
67 hdr->v1.end, hdr->v1.num_chars);
68
69 memconsole_length = hdr->v1.num_chars;
70 memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr);
71}
72
73static void found_v2_header(struct biosmemcon_ebda *hdr)
74{
75 printk(KERN_INFO "BIOS console v2 EBDA structure found at %p\n", hdr);
76 printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
77 "start = %d, end = %d, num_bytes = %d\n",
78 hdr->v2.buffer_addr, hdr->v2.start,
79 hdr->v2.end, hdr->v2.num_bytes);
80
81 memconsole_length = hdr->v2.end - hdr->v2.start;
82 memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr
83 + hdr->v2.start);
84}
85
86/*
87 * Search through the EBDA for the BIOS Memory Console, and
88 * set the global variables to point to it. Return true if found.
89 */
90static bool found_memconsole(void)
91{
92 unsigned int address;
93 size_t length, cur;
94
95 address = get_bios_ebda();
96 if (!address) {
97 printk(KERN_INFO "BIOS EBDA non-existent.\n");
98 return false;
99 }
100
101 /* EBDA length is byte 0 of EBDA (in KB) */
102 length = *(u8 *)phys_to_virt(address);
103 length <<= 10; /* convert to bytes */
104
105 /*
106 * Search through EBDA for BIOS memory console structure
107 * note: signature is not necessarily dword-aligned
108 */
109 for (cur = 0; cur < length; cur++) {
110 struct biosmemcon_ebda *hdr = phys_to_virt(address + cur);
111
112 /* memconsole v1 */
113 if (hdr->signature == BIOS_MEMCONSOLE_V1_MAGIC) {
114 found_v1_header(hdr);
115 return true;
116 }
117
118 /* memconsole v2 */
119 if (hdr->signature == BIOS_MEMCONSOLE_V2_MAGIC) {
120 found_v2_header(hdr);
121 return true;
122 }
123 }
124
125 printk(KERN_INFO "BIOS console EBDA structure not found!\n");
126 return false;
127}
128
129static struct dmi_system_id memconsole_dmi_table[] __initdata = {
130 {
131 .ident = "Google Board",
132 .matches = {
133 DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
134 },
135 },
136 {}
137};
138MODULE_DEVICE_TABLE(dmi, memconsole_dmi_table);
139
140static int __init memconsole_init(void)
141{
142 int ret;
143
144 if (!dmi_check_system(memconsole_dmi_table))
145 return -ENODEV;
146
147 if (!found_memconsole())
148 return -ENODEV;
149
150 memconsole_bin_attr.size = memconsole_length;
151
152 ret = sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr);
153
154 return ret;
155}
156
157static void __exit memconsole_exit(void)
158{
159 sysfs_remove_bin_file(firmware_kobj, &memconsole_bin_attr);
160}
161
162module_init(memconsole_init);
163module_exit(memconsole_exit);
164
165MODULE_AUTHOR("Google, Inc.");
166MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index 2192456dfd68..f032e446fc11 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -42,7 +42,20 @@
42struct acpi_table_ibft *ibft_addr; 42struct acpi_table_ibft *ibft_addr;
43EXPORT_SYMBOL_GPL(ibft_addr); 43EXPORT_SYMBOL_GPL(ibft_addr);
44 44
45#define IBFT_SIGN "iBFT" 45static const struct {
46 char *sign;
47} ibft_signs[] = {
48#ifdef CONFIG_ACPI
49 /*
50 * One spec says "IBFT", the other says "iBFT". We have to check
51 * for both.
52 */
53 { ACPI_SIG_IBFT },
54#endif
55 { "iBFT" },
56 { "BIFT" }, /* Broadcom iSCSI Offload */
57};
58
46#define IBFT_SIGN_LEN 4 59#define IBFT_SIGN_LEN 4
47#define IBFT_START 0x80000 /* 512kB */ 60#define IBFT_START 0x80000 /* 512kB */
48#define IBFT_END 0x100000 /* 1MB */ 61#define IBFT_END 0x100000 /* 1MB */
@@ -62,6 +75,7 @@ static int __init find_ibft_in_mem(void)
62 unsigned long pos; 75 unsigned long pos;
63 unsigned int len = 0; 76 unsigned int len = 0;
64 void *virt; 77 void *virt;
78 int i;
65 79
66 for (pos = IBFT_START; pos < IBFT_END; pos += 16) { 80 for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
67 /* The table can't be inside the VGA BIOS reserved space, 81 /* The table can't be inside the VGA BIOS reserved space,
@@ -69,18 +83,23 @@ static int __init find_ibft_in_mem(void)
69 if (pos == VGA_MEM) 83 if (pos == VGA_MEM)
70 pos += VGA_SIZE; 84 pos += VGA_SIZE;
71 virt = isa_bus_to_virt(pos); 85 virt = isa_bus_to_virt(pos);
72 if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { 86
73 unsigned long *addr = 87 for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) {
74 (unsigned long *)isa_bus_to_virt(pos + 4); 88 if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) ==
75 len = *addr; 89 0) {
76 /* if the length of the table extends past 1M, 90 unsigned long *addr =
77 * the table cannot be valid. */ 91 (unsigned long *)isa_bus_to_virt(pos + 4);
78 if (pos + len <= (IBFT_END-1)) { 92 len = *addr;
79 ibft_addr = (struct acpi_table_ibft *)virt; 93 /* if the length of the table extends past 1M,
80 break; 94 * the table cannot be valid. */
95 if (pos + len <= (IBFT_END-1)) {
96 ibft_addr = (struct acpi_table_ibft *)virt;
97 goto done;
98 }
81 } 99 }
82 } 100 }
83 } 101 }
102done:
84 return len; 103 return len;
85} 104}
86/* 105/*
@@ -89,18 +108,12 @@ static int __init find_ibft_in_mem(void)
89 */ 108 */
90unsigned long __init find_ibft_region(unsigned long *sizep) 109unsigned long __init find_ibft_region(unsigned long *sizep)
91{ 110{
92 111 int i;
93 ibft_addr = NULL; 112 ibft_addr = NULL;
94 113
95#ifdef CONFIG_ACPI 114#ifdef CONFIG_ACPI
96 /* 115 for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++)
97 * One spec says "IBFT", the other says "iBFT". We have to check 116 acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft);
98 * for both.
99 */
100 if (!ibft_addr)
101 acpi_table_parse(ACPI_SIG_IBFT, acpi_find_ibft);
102 if (!ibft_addr)
103 acpi_table_parse(IBFT_SIGN, acpi_find_ibft);
104#endif /* CONFIG_ACPI */ 117#endif /* CONFIG_ACPI */
105 118
106 /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will 119 /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will