aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/Kconfig32
-rw-r--r--drivers/firmware/Makefile4
-rw-r--r--drivers/firmware/dcdbas.c4
-rw-r--r--drivers/firmware/dmi-sysfs.c696
-rw-r--r--drivers/firmware/dmi_scan.c39
-rw-r--r--drivers/firmware/edd.c24
-rw-r--r--drivers/firmware/efivars.c350
-rw-r--r--drivers/firmware/google/Kconfig32
-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.c4
-rw-r--r--drivers/firmware/iscsi_ibft_find.c53
-rw-r--r--drivers/firmware/pcdp.h4
-rw-r--r--drivers/firmware/sigma.c115
15 files changed, 2289 insertions, 177 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 280c9b5ad9e3..efba163595db 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -27,7 +27,7 @@ config EDD_OFF
27 using the kernel parameter 'edd={on|skipmbr|off}'. 27 using the kernel parameter 'edd={on|skipmbr|off}'.
28 28
29config FIRMWARE_MEMMAP 29config FIRMWARE_MEMMAP
30 bool "Add firmware-provided memory map to sysfs" if EMBEDDED 30 bool "Add firmware-provided memory map to sysfs" if EXPERT
31 default X86 31 default X86
32 help 32 help
33 Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap. 33 Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap.
@@ -74,7 +74,8 @@ config EFI_PCDP
74 74
75 You must also enable the appropriate drivers (serial, VGA, etc.) 75 You must also enable the appropriate drivers (serial, VGA, etc.)
76 76
77 See <http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf> 77 See DIG64_HCDPv20_042804.pdf available from
78 <http://www.dig64.org/specifications/>
78 79
79config DELL_RBU 80config DELL_RBU
80 tristate "BIOS update support for DELL systems via sysfs" 81 tristate "BIOS update support for DELL systems via sysfs"
@@ -112,6 +113,17 @@ config DMIID
112 information from userspace through /sys/class/dmi/id/ or if you want 113 information from userspace through /sys/class/dmi/id/ or if you want
113 DMI-based module auto-loading. 114 DMI-based module auto-loading.
114 115
116config DMI_SYSFS
117 tristate "DMI table support in sysfs"
118 depends on SYSFS && DMI
119 default n
120 help
121 Say Y or M here to enable the exporting of the raw DMI table
122 data via sysfs. This is useful for consuming the data without
123 requiring any access to /dev/mem at all. Tables are found
124 under /sys/firmware/dmi when this option is enabled and
125 loaded.
126
115config ISCSI_IBFT_FIND 127config ISCSI_IBFT_FIND
116 bool "iSCSI Boot Firmware Table Attributes" 128 bool "iSCSI Boot Firmware Table Attributes"
117 depends on X86 129 depends on X86
@@ -125,7 +137,7 @@ config ISCSI_IBFT_FIND
125config ISCSI_IBFT 137config ISCSI_IBFT
126 tristate "iSCSI Boot Firmware Table Attributes module" 138 tristate "iSCSI Boot Firmware Table Attributes module"
127 select ISCSI_BOOT_SYSFS 139 select ISCSI_BOOT_SYSFS
128 depends on ISCSI_IBFT_FIND && SCSI 140 depends on ISCSI_IBFT_FIND && SCSI && SCSI_LOWLEVEL
129 default n 141 default n
130 help 142 help
131 This option enables support for detection and exposing of iSCSI 143 This option enables support for detection and exposing of iSCSI
@@ -133,4 +145,18 @@ config ISCSI_IBFT
133 detect iSCSI boot parameters dynamically during system boot, say Y. 145 detect iSCSI boot parameters dynamically during system boot, say Y.
134 Otherwise, say N. 146 Otherwise, say N.
135 147
148config SIGMA
149 tristate "SigmaStudio firmware loader"
150 depends on I2C
151 select CRC32
152 default n
153 help
154 Enable helper functions for working with Analog Devices SigmaDSP
155 parts and binary firmwares produced by Analog Devices SigmaStudio.
156
157 If unsure, say N here. Drivers that need these helpers will select
158 this option automatically.
159
160source "drivers/firmware/google/Kconfig"
161
136endmenu 162endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 1c3c17343dbe..47338c979126 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4obj-$(CONFIG_DMI) += dmi_scan.o 4obj-$(CONFIG_DMI) += dmi_scan.o
5obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o
5obj-$(CONFIG_EDD) += edd.o 6obj-$(CONFIG_EDD) += edd.o
6obj-$(CONFIG_EFI_VARS) += efivars.o 7obj-$(CONFIG_EFI_VARS) += efivars.o
7obj-$(CONFIG_EFI_PCDP) += pcdp.o 8obj-$(CONFIG_EFI_PCDP) += pcdp.o
@@ -11,3 +12,6 @@ obj-$(CONFIG_DMIID) += dmi-id.o
11obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o 12obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
12obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o 13obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
13obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o 14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
15obj-$(CONFIG_SIGMA) += sigma.o
16
17obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 69ad529d92fb..ea5ac2dc1233 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -268,8 +268,10 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
268 } 268 }
269 269
270 /* generate SMI */ 270 /* generate SMI */
271 /* inb to force posted write through and make SMI happen now */
271 asm volatile ( 272 asm volatile (
272 "outb %b0,%w1" 273 "outb %b0,%w1\n"
274 "inb %w1"
273 : /* no output args */ 275 : /* no output args */
274 : "a" (smi_cmd->command_code), 276 : "a" (smi_cmd->command_code),
275 "d" (smi_cmd->command_address), 277 "d" (smi_cmd->command_address),
diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c
new file mode 100644
index 000000000000..eb26d62e5188
--- /dev/null
+++ b/drivers/firmware/dmi-sysfs.c
@@ -0,0 +1,696 @@
1/*
2 * dmi-sysfs.c
3 *
4 * This module exports the DMI tables read-only to userspace through the
5 * sysfs file system.
6 *
7 * Data is currently found below
8 * /sys/firmware/dmi/...
9 *
10 * DMI attributes are presented in attribute files with names
11 * formatted using %d-%d, so that the first integer indicates the
12 * structure type (0-255), and the second field is the instance of that
13 * entry.
14 *
15 * Copyright 2011 Google, Inc.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/kobject.h>
23#include <linux/dmi.h>
24#include <linux/capability.h>
25#include <linux/slab.h>
26#include <linux/list.h>
27#include <linux/io.h>
28
29#define MAX_ENTRY_TYPE 255 /* Most of these aren't used, but we consider
30 the top entry type is only 8 bits */
31
32struct dmi_sysfs_entry {
33 struct dmi_header dh;
34 struct kobject kobj;
35 int instance;
36 int position;
37 struct list_head list;
38 struct kobject *child;
39};
40
41/*
42 * Global list of dmi_sysfs_entry. Even though this should only be
43 * manipulated at setup and teardown, the lazy nature of the kobject
44 * system means we get lazy removes.
45 */
46static LIST_HEAD(entry_list);
47static DEFINE_SPINLOCK(entry_list_lock);
48
49/* dmi_sysfs_attribute - Top level attribute. used by all entries. */
50struct dmi_sysfs_attribute {
51 struct attribute attr;
52 ssize_t (*show)(struct dmi_sysfs_entry *entry, char *buf);
53};
54
55#define DMI_SYSFS_ATTR(_entry, _name) \
56struct dmi_sysfs_attribute dmi_sysfs_attr_##_entry##_##_name = { \
57 .attr = {.name = __stringify(_name), .mode = 0400}, \
58 .show = dmi_sysfs_##_entry##_##_name, \
59}
60
61/*
62 * dmi_sysfs_mapped_attribute - Attribute where we require the entry be
63 * mapped in. Use in conjunction with dmi_sysfs_specialize_attr_ops.
64 */
65struct dmi_sysfs_mapped_attribute {
66 struct attribute attr;
67 ssize_t (*show)(struct dmi_sysfs_entry *entry,
68 const struct dmi_header *dh,
69 char *buf);
70};
71
72#define DMI_SYSFS_MAPPED_ATTR(_entry, _name) \
73struct dmi_sysfs_mapped_attribute dmi_sysfs_attr_##_entry##_##_name = { \
74 .attr = {.name = __stringify(_name), .mode = 0400}, \
75 .show = dmi_sysfs_##_entry##_##_name, \
76}
77
78/*************************************************
79 * Generic DMI entry support.
80 *************************************************/
81static void dmi_entry_free(struct kobject *kobj)
82{
83 kfree(kobj);
84}
85
86static struct dmi_sysfs_entry *to_entry(struct kobject *kobj)
87{
88 return container_of(kobj, struct dmi_sysfs_entry, kobj);
89}
90
91static struct dmi_sysfs_attribute *to_attr(struct attribute *attr)
92{
93 return container_of(attr, struct dmi_sysfs_attribute, attr);
94}
95
96static ssize_t dmi_sysfs_attr_show(struct kobject *kobj,
97 struct attribute *_attr, char *buf)
98{
99 struct dmi_sysfs_entry *entry = to_entry(kobj);
100 struct dmi_sysfs_attribute *attr = to_attr(_attr);
101
102 /* DMI stuff is only ever admin visible */
103 if (!capable(CAP_SYS_ADMIN))
104 return -EACCES;
105
106 return attr->show(entry, buf);
107}
108
109static const struct sysfs_ops dmi_sysfs_attr_ops = {
110 .show = dmi_sysfs_attr_show,
111};
112
113typedef ssize_t (*dmi_callback)(struct dmi_sysfs_entry *,
114 const struct dmi_header *dh, void *);
115
116struct find_dmi_data {
117 struct dmi_sysfs_entry *entry;
118 dmi_callback callback;
119 void *private;
120 int instance_countdown;
121 ssize_t ret;
122};
123
124static void find_dmi_entry_helper(const struct dmi_header *dh,
125 void *_data)
126{
127 struct find_dmi_data *data = _data;
128 struct dmi_sysfs_entry *entry = data->entry;
129
130 /* Is this the entry we want? */
131 if (dh->type != entry->dh.type)
132 return;
133
134 if (data->instance_countdown != 0) {
135 /* try the next instance? */
136 data->instance_countdown--;
137 return;
138 }
139
140 /*
141 * Don't ever revisit the instance. Short circuit later
142 * instances by letting the instance_countdown run negative
143 */
144 data->instance_countdown--;
145
146 /* Found the entry */
147 data->ret = data->callback(entry, dh, data->private);
148}
149
150/* State for passing the read parameters through dmi_find_entry() */
151struct dmi_read_state {
152 char *buf;
153 loff_t pos;
154 size_t count;
155};
156
157static ssize_t find_dmi_entry(struct dmi_sysfs_entry *entry,
158 dmi_callback callback, void *private)
159{
160 struct find_dmi_data data = {
161 .entry = entry,
162 .callback = callback,
163 .private = private,
164 .instance_countdown = entry->instance,
165 .ret = -EIO, /* To signal the entry disappeared */
166 };
167 int ret;
168
169 ret = dmi_walk(find_dmi_entry_helper, &data);
170 /* This shouldn't happen, but just in case. */
171 if (ret)
172 return -EINVAL;
173 return data.ret;
174}
175
176/*
177 * Calculate and return the byte length of the dmi entry identified by
178 * dh. This includes both the formatted portion as well as the
179 * unformatted string space, including the two trailing nul characters.
180 */
181static size_t dmi_entry_length(const struct dmi_header *dh)
182{
183 const char *p = (const char *)dh;
184
185 p += dh->length;
186
187 while (p[0] || p[1])
188 p++;
189
190 return 2 + p - (const char *)dh;
191}
192
193/*************************************************
194 * Support bits for specialized DMI entry support
195 *************************************************/
196struct dmi_entry_attr_show_data {
197 struct attribute *attr;
198 char *buf;
199};
200
201static ssize_t dmi_entry_attr_show_helper(struct dmi_sysfs_entry *entry,
202 const struct dmi_header *dh,
203 void *_data)
204{
205 struct dmi_entry_attr_show_data *data = _data;
206 struct dmi_sysfs_mapped_attribute *attr;
207
208 attr = container_of(data->attr,
209 struct dmi_sysfs_mapped_attribute, attr);
210 return attr->show(entry, dh, data->buf);
211}
212
213static ssize_t dmi_entry_attr_show(struct kobject *kobj,
214 struct attribute *attr,
215 char *buf)
216{
217 struct dmi_entry_attr_show_data data = {
218 .attr = attr,
219 .buf = buf,
220 };
221 /* Find the entry according to our parent and call the
222 * normalized show method hanging off of the attribute */
223 return find_dmi_entry(to_entry(kobj->parent),
224 dmi_entry_attr_show_helper, &data);
225}
226
227static const struct sysfs_ops dmi_sysfs_specialize_attr_ops = {
228 .show = dmi_entry_attr_show,
229};
230
231/*************************************************
232 * Specialized DMI entry support.
233 *************************************************/
234
235/*** Type 15 - System Event Table ***/
236
237#define DMI_SEL_ACCESS_METHOD_IO8 0x00
238#define DMI_SEL_ACCESS_METHOD_IO2x8 0x01
239#define DMI_SEL_ACCESS_METHOD_IO16 0x02
240#define DMI_SEL_ACCESS_METHOD_PHYS32 0x03
241#define DMI_SEL_ACCESS_METHOD_GPNV 0x04
242
243struct dmi_system_event_log {
244 struct dmi_header header;
245 u16 area_length;
246 u16 header_start_offset;
247 u16 data_start_offset;
248 u8 access_method;
249 u8 status;
250 u32 change_token;
251 union {
252 struct {
253 u16 index_addr;
254 u16 data_addr;
255 } io;
256 u32 phys_addr32;
257 u16 gpnv_handle;
258 u32 access_method_address;
259 };
260 u8 header_format;
261 u8 type_descriptors_supported_count;
262 u8 per_log_type_descriptor_length;
263 u8 supported_log_type_descriptos[0];
264} __packed;
265
266#define DMI_SYSFS_SEL_FIELD(_field) \
267static ssize_t dmi_sysfs_sel_##_field(struct dmi_sysfs_entry *entry, \
268 const struct dmi_header *dh, \
269 char *buf) \
270{ \
271 struct dmi_system_event_log sel; \
272 if (sizeof(sel) > dmi_entry_length(dh)) \
273 return -EIO; \
274 memcpy(&sel, dh, sizeof(sel)); \
275 return sprintf(buf, "%u\n", sel._field); \
276} \
277static DMI_SYSFS_MAPPED_ATTR(sel, _field)
278
279DMI_SYSFS_SEL_FIELD(area_length);
280DMI_SYSFS_SEL_FIELD(header_start_offset);
281DMI_SYSFS_SEL_FIELD(data_start_offset);
282DMI_SYSFS_SEL_FIELD(access_method);
283DMI_SYSFS_SEL_FIELD(status);
284DMI_SYSFS_SEL_FIELD(change_token);
285DMI_SYSFS_SEL_FIELD(access_method_address);
286DMI_SYSFS_SEL_FIELD(header_format);
287DMI_SYSFS_SEL_FIELD(type_descriptors_supported_count);
288DMI_SYSFS_SEL_FIELD(per_log_type_descriptor_length);
289
290static struct attribute *dmi_sysfs_sel_attrs[] = {
291 &dmi_sysfs_attr_sel_area_length.attr,
292 &dmi_sysfs_attr_sel_header_start_offset.attr,
293 &dmi_sysfs_attr_sel_data_start_offset.attr,
294 &dmi_sysfs_attr_sel_access_method.attr,
295 &dmi_sysfs_attr_sel_status.attr,
296 &dmi_sysfs_attr_sel_change_token.attr,
297 &dmi_sysfs_attr_sel_access_method_address.attr,
298 &dmi_sysfs_attr_sel_header_format.attr,
299 &dmi_sysfs_attr_sel_type_descriptors_supported_count.attr,
300 &dmi_sysfs_attr_sel_per_log_type_descriptor_length.attr,
301 NULL,
302};
303
304
305static struct kobj_type dmi_system_event_log_ktype = {
306 .release = dmi_entry_free,
307 .sysfs_ops = &dmi_sysfs_specialize_attr_ops,
308 .default_attrs = dmi_sysfs_sel_attrs,
309};
310
311typedef u8 (*sel_io_reader)(const struct dmi_system_event_log *sel,
312 loff_t offset);
313
314static DEFINE_MUTEX(io_port_lock);
315
316static u8 read_sel_8bit_indexed_io(const struct dmi_system_event_log *sel,
317 loff_t offset)
318{
319 u8 ret;
320
321 mutex_lock(&io_port_lock);
322 outb((u8)offset, sel->io.index_addr);
323 ret = inb(sel->io.data_addr);
324 mutex_unlock(&io_port_lock);
325 return ret;
326}
327
328static u8 read_sel_2x8bit_indexed_io(const struct dmi_system_event_log *sel,
329 loff_t offset)
330{
331 u8 ret;
332
333 mutex_lock(&io_port_lock);
334 outb((u8)offset, sel->io.index_addr);
335 outb((u8)(offset >> 8), sel->io.index_addr + 1);
336 ret = inb(sel->io.data_addr);
337 mutex_unlock(&io_port_lock);
338 return ret;
339}
340
341static u8 read_sel_16bit_indexed_io(const struct dmi_system_event_log *sel,
342 loff_t offset)
343{
344 u8 ret;
345
346 mutex_lock(&io_port_lock);
347 outw((u16)offset, sel->io.index_addr);
348 ret = inb(sel->io.data_addr);
349 mutex_unlock(&io_port_lock);
350 return ret;
351}
352
353static sel_io_reader sel_io_readers[] = {
354 [DMI_SEL_ACCESS_METHOD_IO8] = read_sel_8bit_indexed_io,
355 [DMI_SEL_ACCESS_METHOD_IO2x8] = read_sel_2x8bit_indexed_io,
356 [DMI_SEL_ACCESS_METHOD_IO16] = read_sel_16bit_indexed_io,
357};
358
359static ssize_t dmi_sel_raw_read_io(struct dmi_sysfs_entry *entry,
360 const struct dmi_system_event_log *sel,
361 char *buf, loff_t pos, size_t count)
362{
363 ssize_t wrote = 0;
364
365 sel_io_reader io_reader = sel_io_readers[sel->access_method];
366
367 while (count && pos < sel->area_length) {
368 count--;
369 *(buf++) = io_reader(sel, pos++);
370 wrote++;
371 }
372
373 return wrote;
374}
375
376static ssize_t dmi_sel_raw_read_phys32(struct dmi_sysfs_entry *entry,
377 const struct dmi_system_event_log *sel,
378 char *buf, loff_t pos, size_t count)
379{
380 u8 __iomem *mapped;
381 ssize_t wrote = 0;
382
383 mapped = ioremap(sel->access_method_address, sel->area_length);
384 if (!mapped)
385 return -EIO;
386
387 while (count && pos < sel->area_length) {
388 count--;
389 *(buf++) = readb(mapped + pos++);
390 wrote++;
391 }
392
393 iounmap(mapped);
394 return wrote;
395}
396
397static ssize_t dmi_sel_raw_read_helper(struct dmi_sysfs_entry *entry,
398 const struct dmi_header *dh,
399 void *_state)
400{
401 struct dmi_read_state *state = _state;
402 struct dmi_system_event_log sel;
403
404 if (sizeof(sel) > dmi_entry_length(dh))
405 return -EIO;
406
407 memcpy(&sel, dh, sizeof(sel));
408
409 switch (sel.access_method) {
410 case DMI_SEL_ACCESS_METHOD_IO8:
411 case DMI_SEL_ACCESS_METHOD_IO2x8:
412 case DMI_SEL_ACCESS_METHOD_IO16:
413 return dmi_sel_raw_read_io(entry, &sel, state->buf,
414 state->pos, state->count);
415 case DMI_SEL_ACCESS_METHOD_PHYS32:
416 return dmi_sel_raw_read_phys32(entry, &sel, state->buf,
417 state->pos, state->count);
418 case DMI_SEL_ACCESS_METHOD_GPNV:
419 pr_info("dmi-sysfs: GPNV support missing.\n");
420 return -EIO;
421 default:
422 pr_info("dmi-sysfs: Unknown access method %02x\n",
423 sel.access_method);
424 return -EIO;
425 }
426}
427
428static ssize_t dmi_sel_raw_read(struct file *filp, struct kobject *kobj,
429 struct bin_attribute *bin_attr,
430 char *buf, loff_t pos, size_t count)
431{
432 struct dmi_sysfs_entry *entry = to_entry(kobj->parent);
433 struct dmi_read_state state = {
434 .buf = buf,
435 .pos = pos,
436 .count = count,
437 };
438
439 return find_dmi_entry(entry, dmi_sel_raw_read_helper, &state);
440}
441
442static struct bin_attribute dmi_sel_raw_attr = {
443 .attr = {.name = "raw_event_log", .mode = 0400},
444 .read = dmi_sel_raw_read,
445};
446
447static int dmi_system_event_log(struct dmi_sysfs_entry *entry)
448{
449 int ret;
450
451 entry->child = kzalloc(sizeof(*entry->child), GFP_KERNEL);
452 if (!entry->child)
453 return -ENOMEM;
454 ret = kobject_init_and_add(entry->child,
455 &dmi_system_event_log_ktype,
456 &entry->kobj,
457 "system_event_log");
458 if (ret)
459 goto out_free;
460
461 ret = sysfs_create_bin_file(entry->child, &dmi_sel_raw_attr);
462 if (ret)
463 goto out_del;
464
465 return 0;
466
467out_del:
468 kobject_del(entry->child);
469out_free:
470 kfree(entry->child);
471 return ret;
472}
473
474/*************************************************
475 * Generic DMI entry support.
476 *************************************************/
477
478static ssize_t dmi_sysfs_entry_length(struct dmi_sysfs_entry *entry, char *buf)
479{
480 return sprintf(buf, "%d\n", entry->dh.length);
481}
482
483static ssize_t dmi_sysfs_entry_handle(struct dmi_sysfs_entry *entry, char *buf)
484{
485 return sprintf(buf, "%d\n", entry->dh.handle);
486}
487
488static ssize_t dmi_sysfs_entry_type(struct dmi_sysfs_entry *entry, char *buf)
489{
490 return sprintf(buf, "%d\n", entry->dh.type);
491}
492
493static ssize_t dmi_sysfs_entry_instance(struct dmi_sysfs_entry *entry,
494 char *buf)
495{
496 return sprintf(buf, "%d\n", entry->instance);
497}
498
499static ssize_t dmi_sysfs_entry_position(struct dmi_sysfs_entry *entry,
500 char *buf)
501{
502 return sprintf(buf, "%d\n", entry->position);
503}
504
505static DMI_SYSFS_ATTR(entry, length);
506static DMI_SYSFS_ATTR(entry, handle);
507static DMI_SYSFS_ATTR(entry, type);
508static DMI_SYSFS_ATTR(entry, instance);
509static DMI_SYSFS_ATTR(entry, position);
510
511static struct attribute *dmi_sysfs_entry_attrs[] = {
512 &dmi_sysfs_attr_entry_length.attr,
513 &dmi_sysfs_attr_entry_handle.attr,
514 &dmi_sysfs_attr_entry_type.attr,
515 &dmi_sysfs_attr_entry_instance.attr,
516 &dmi_sysfs_attr_entry_position.attr,
517 NULL,
518};
519
520static ssize_t dmi_entry_raw_read_helper(struct dmi_sysfs_entry *entry,
521 const struct dmi_header *dh,
522 void *_state)
523{
524 struct dmi_read_state *state = _state;
525 size_t entry_length;
526
527 entry_length = dmi_entry_length(dh);
528
529 return memory_read_from_buffer(state->buf, state->count,
530 &state->pos, dh, entry_length);
531}
532
533static ssize_t dmi_entry_raw_read(struct file *filp,
534 struct kobject *kobj,
535 struct bin_attribute *bin_attr,
536 char *buf, loff_t pos, size_t count)
537{
538 struct dmi_sysfs_entry *entry = to_entry(kobj);
539 struct dmi_read_state state = {
540 .buf = buf,
541 .pos = pos,
542 .count = count,
543 };
544
545 return find_dmi_entry(entry, dmi_entry_raw_read_helper, &state);
546}
547
548static const struct bin_attribute dmi_entry_raw_attr = {
549 .attr = {.name = "raw", .mode = 0400},
550 .read = dmi_entry_raw_read,
551};
552
553static void dmi_sysfs_entry_release(struct kobject *kobj)
554{
555 struct dmi_sysfs_entry *entry = to_entry(kobj);
556 sysfs_remove_bin_file(&entry->kobj, &dmi_entry_raw_attr);
557 spin_lock(&entry_list_lock);
558 list_del(&entry->list);
559 spin_unlock(&entry_list_lock);
560 kfree(entry);
561}
562
563static struct kobj_type dmi_sysfs_entry_ktype = {
564 .release = dmi_sysfs_entry_release,
565 .sysfs_ops = &dmi_sysfs_attr_ops,
566 .default_attrs = dmi_sysfs_entry_attrs,
567};
568
569static struct kobject *dmi_kobj;
570static struct kset *dmi_kset;
571
572/* Global count of all instances seen. Only for setup */
573static int __initdata instance_counts[MAX_ENTRY_TYPE + 1];
574
575/* Global positional count of all entries seen. Only for setup */
576static int __initdata position_count;
577
578static void __init dmi_sysfs_register_handle(const struct dmi_header *dh,
579 void *_ret)
580{
581 struct dmi_sysfs_entry *entry;
582 int *ret = _ret;
583
584 /* If a previous entry saw an error, short circuit */
585 if (*ret)
586 return;
587
588 /* Allocate and register a new entry into the entries set */
589 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
590 if (!entry) {
591 *ret = -ENOMEM;
592 return;
593 }
594
595 /* Set the key */
596 memcpy(&entry->dh, dh, sizeof(*dh));
597 entry->instance = instance_counts[dh->type]++;
598 entry->position = position_count++;
599
600 entry->kobj.kset = dmi_kset;
601 *ret = kobject_init_and_add(&entry->kobj, &dmi_sysfs_entry_ktype, NULL,
602 "%d-%d", dh->type, entry->instance);
603
604 if (*ret) {
605 kfree(entry);
606 return;
607 }
608
609 /* Thread on the global list for cleanup */
610 spin_lock(&entry_list_lock);
611 list_add_tail(&entry->list, &entry_list);
612 spin_unlock(&entry_list_lock);
613
614 /* Handle specializations by type */
615 switch (dh->type) {
616 case DMI_ENTRY_SYSTEM_EVENT_LOG:
617 *ret = dmi_system_event_log(entry);
618 break;
619 default:
620 /* No specialization */
621 break;
622 }
623 if (*ret)
624 goto out_err;
625
626 /* Create the raw binary file to access the entry */
627 *ret = sysfs_create_bin_file(&entry->kobj, &dmi_entry_raw_attr);
628 if (*ret)
629 goto out_err;
630
631 return;
632out_err:
633 kobject_put(entry->child);
634 kobject_put(&entry->kobj);
635 return;
636}
637
638static void cleanup_entry_list(void)
639{
640 struct dmi_sysfs_entry *entry, *next;
641
642 /* No locks, we are on our way out */
643 list_for_each_entry_safe(entry, next, &entry_list, list) {
644 kobject_put(entry->child);
645 kobject_put(&entry->kobj);
646 }
647}
648
649static int __init dmi_sysfs_init(void)
650{
651 int error = -ENOMEM;
652 int val;
653
654 /* Set up our directory */
655 dmi_kobj = kobject_create_and_add("dmi", firmware_kobj);
656 if (!dmi_kobj)
657 goto err;
658
659 dmi_kset = kset_create_and_add("entries", NULL, dmi_kobj);
660 if (!dmi_kset)
661 goto err;
662
663 val = 0;
664 error = dmi_walk(dmi_sysfs_register_handle, &val);
665 if (error)
666 goto err;
667 if (val) {
668 error = val;
669 goto err;
670 }
671
672 pr_debug("dmi-sysfs: loaded.\n");
673
674 return 0;
675err:
676 cleanup_entry_list();
677 kset_unregister(dmi_kset);
678 kobject_put(dmi_kobj);
679 return error;
680}
681
682/* clean up everything. */
683static void __exit dmi_sysfs_exit(void)
684{
685 pr_debug("dmi-sysfs: unloading.\n");
686 cleanup_entry_list();
687 kset_unregister(dmi_kset);
688 kobject_put(dmi_kobj);
689}
690
691module_init(dmi_sysfs_init);
692module_exit(dmi_sysfs_exit);
693
694MODULE_AUTHOR("Mike Waychison <mikew@google.com>");
695MODULE_DESCRIPTION("DMI sysfs support");
696MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index b3d22d659990..bcb1126e3d00 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -2,6 +2,7 @@
2#include <linux/string.h> 2#include <linux/string.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/ctype.h>
5#include <linux/dmi.h> 6#include <linux/dmi.h>
6#include <linux/efi.h> 7#include <linux/efi.h>
7#include <linux/bootmem.h> 8#include <linux/bootmem.h>
@@ -361,6 +362,40 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
361 } 362 }
362} 363}
363 364
365static void __init print_filtered(const char *info)
366{
367 const char *p;
368
369 if (!info)
370 return;
371
372 for (p = info; *p; p++)
373 if (isprint(*p))
374 printk(KERN_CONT "%c", *p);
375 else
376 printk(KERN_CONT "\\x%02x", *p & 0xff);
377}
378
379static void __init dmi_dump_ids(void)
380{
381 const char *board; /* Board Name is optional */
382
383 printk(KERN_DEBUG "DMI: ");
384 print_filtered(dmi_get_system_info(DMI_SYS_VENDOR));
385 printk(KERN_CONT " ");
386 print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME));
387 board = dmi_get_system_info(DMI_BOARD_NAME);
388 if (board) {
389 printk(KERN_CONT "/");
390 print_filtered(board);
391 }
392 printk(KERN_CONT ", BIOS ");
393 print_filtered(dmi_get_system_info(DMI_BIOS_VERSION));
394 printk(KERN_CONT " ");
395 print_filtered(dmi_get_system_info(DMI_BIOS_DATE));
396 printk(KERN_CONT "\n");
397}
398
364static int __init dmi_present(const char __iomem *p) 399static int __init dmi_present(const char __iomem *p)
365{ 400{
366 u8 buf[15]; 401 u8 buf[15];
@@ -381,8 +416,10 @@ static int __init dmi_present(const char __iomem *p)
381 buf[14] >> 4, buf[14] & 0xF); 416 buf[14] >> 4, buf[14] & 0xF);
382 else 417 else
383 printk(KERN_INFO "DMI present.\n"); 418 printk(KERN_INFO "DMI present.\n");
384 if (dmi_walk_early(dmi_decode) == 0) 419 if (dmi_walk_early(dmi_decode) == 0) {
420 dmi_dump_ids();
385 return 0; 421 return 0;
422 }
386 } 423 }
387 return 1; 424 return 1;
388} 425}
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index f287fe79edc4..f1b7f659d3c9 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -15,7 +15,7 @@
15 * made in setup.S, copied to safe structures in setup.c, 15 * made in setup.S, copied to safe structures in setup.c,
16 * and presents it in sysfs. 16 * and presents it in sysfs.
17 * 17 *
18 * Please see http://linux.dell.com/edd30/results.html for 18 * Please see http://linux.dell.com/edd/results.html for
19 * the list of BIOSs which have been reported to implement EDD. 19 * the list of BIOSs which have been reported to implement EDD.
20 * 20 *
21 * This program is free software; you can redistribute it and/or modify 21 * This program is free software; you can redistribute it and/or modify
@@ -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 2a62ec6390e0..5f29aafd4462 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -90,17 +90,6 @@ MODULE_LICENSE("GPL");
90MODULE_VERSION(EFIVARS_VERSION); 90MODULE_VERSION(EFIVARS_VERSION);
91 91
92/* 92/*
93 * efivars_lock protects two things:
94 * 1) efivar_list - adds, removals, reads, writes
95 * 2) efi.[gs]et_variable() calls.
96 * It must not be held when creating sysfs entries or calling kmalloc.
97 * efi.get_next_variable() is only called from efivars_init(),
98 * which is protected by the BKL, so that path is safe.
99 */
100static DEFINE_SPINLOCK(efivars_lock);
101static LIST_HEAD(efivar_list);
102
103/*
104 * The maximum size of VariableName + Data = 1024 93 * The maximum size of VariableName + Data = 1024
105 * Therefore, it's reasonable to save that much 94 * Therefore, it's reasonable to save that much
106 * space in each part of the structure, 95 * space in each part of the structure,
@@ -118,6 +107,7 @@ struct efi_variable {
118 107
119 108
120struct efivar_entry { 109struct efivar_entry {
110 struct efivars *efivars;
121 struct efi_variable var; 111 struct efi_variable var;
122 struct list_head list; 112 struct list_head list;
123 struct kobject kobj; 113 struct kobject kobj;
@@ -144,9 +134,10 @@ struct efivar_attribute efivar_attr_##_name = { \
144 * Prototype for sysfs creation function 134 * Prototype for sysfs creation function
145 */ 135 */
146static int 136static int
147efivar_create_sysfs_entry(unsigned long variable_name_size, 137efivar_create_sysfs_entry(struct efivars *efivars,
148 efi_char16_t *variable_name, 138 unsigned long variable_name_size,
149 efi_guid_t *vendor_guid); 139 efi_char16_t *variable_name,
140 efi_guid_t *vendor_guid);
150 141
151/* Return the number of unicode characters in data */ 142/* Return the number of unicode characters in data */
152static unsigned long 143static unsigned long
@@ -170,18 +161,18 @@ utf8_strsize(efi_char16_t *data, unsigned long maxlength)
170} 161}
171 162
172static efi_status_t 163static efi_status_t
173get_var_data(struct efi_variable *var) 164get_var_data(struct efivars *efivars, struct efi_variable *var)
174{ 165{
175 efi_status_t status; 166 efi_status_t status;
176 167
177 spin_lock(&efivars_lock); 168 spin_lock(&efivars->lock);
178 var->DataSize = 1024; 169 var->DataSize = 1024;
179 status = efi.get_variable(var->VariableName, 170 status = efivars->ops->get_variable(var->VariableName,
180 &var->VendorGuid, 171 &var->VendorGuid,
181 &var->Attributes, 172 &var->Attributes,
182 &var->DataSize, 173 &var->DataSize,
183 var->Data); 174 var->Data);
184 spin_unlock(&efivars_lock); 175 spin_unlock(&efivars->lock);
185 if (status != EFI_SUCCESS) { 176 if (status != EFI_SUCCESS) {
186 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", 177 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
187 status); 178 status);
@@ -215,7 +206,7 @@ efivar_attr_read(struct efivar_entry *entry, char *buf)
215 if (!entry || !buf) 206 if (!entry || !buf)
216 return -EINVAL; 207 return -EINVAL;
217 208
218 status = get_var_data(var); 209 status = get_var_data(entry->efivars, var);
219 if (status != EFI_SUCCESS) 210 if (status != EFI_SUCCESS)
220 return -EIO; 211 return -EIO;
221 212
@@ -238,7 +229,7 @@ efivar_size_read(struct efivar_entry *entry, char *buf)
238 if (!entry || !buf) 229 if (!entry || !buf)
239 return -EINVAL; 230 return -EINVAL;
240 231
241 status = get_var_data(var); 232 status = get_var_data(entry->efivars, var);
242 if (status != EFI_SUCCESS) 233 if (status != EFI_SUCCESS)
243 return -EIO; 234 return -EIO;
244 235
@@ -255,7 +246,7 @@ efivar_data_read(struct efivar_entry *entry, char *buf)
255 if (!entry || !buf) 246 if (!entry || !buf)
256 return -EINVAL; 247 return -EINVAL;
257 248
258 status = get_var_data(var); 249 status = get_var_data(entry->efivars, var);
259 if (status != EFI_SUCCESS) 250 if (status != EFI_SUCCESS)
260 return -EIO; 251 return -EIO;
261 252
@@ -270,6 +261,7 @@ static ssize_t
270efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) 261efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
271{ 262{
272 struct efi_variable *new_var, *var = &entry->var; 263 struct efi_variable *new_var, *var = &entry->var;
264 struct efivars *efivars = entry->efivars;
273 efi_status_t status = EFI_NOT_FOUND; 265 efi_status_t status = EFI_NOT_FOUND;
274 266
275 if (count != sizeof(struct efi_variable)) 267 if (count != sizeof(struct efi_variable))
@@ -291,14 +283,14 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
291 return -EINVAL; 283 return -EINVAL;
292 } 284 }
293 285
294 spin_lock(&efivars_lock); 286 spin_lock(&efivars->lock);
295 status = efi.set_variable(new_var->VariableName, 287 status = efivars->ops->set_variable(new_var->VariableName,
296 &new_var->VendorGuid, 288 &new_var->VendorGuid,
297 new_var->Attributes, 289 new_var->Attributes,
298 new_var->DataSize, 290 new_var->DataSize,
299 new_var->Data); 291 new_var->Data);
300 292
301 spin_unlock(&efivars_lock); 293 spin_unlock(&efivars->lock);
302 294
303 if (status != EFI_SUCCESS) { 295 if (status != EFI_SUCCESS) {
304 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 296 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
@@ -319,7 +311,7 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
319 if (!entry || !buf) 311 if (!entry || !buf)
320 return 0; 312 return 0;
321 313
322 status = get_var_data(var); 314 status = get_var_data(entry->efivars, var);
323 if (status != EFI_SUCCESS) 315 if (status != EFI_SUCCESS)
324 return -EIO; 316 return -EIO;
325 317
@@ -329,7 +321,7 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
329 321
330/* 322/*
331 * Generic read/write functions that call the specific functions of 323 * Generic read/write functions that call the specific functions of
332 * the atttributes... 324 * the attributes...
333 */ 325 */
334static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr, 326static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
335 char *buf) 327 char *buf)
@@ -407,6 +399,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
407 char *buf, loff_t pos, size_t count) 399 char *buf, loff_t pos, size_t count)
408{ 400{
409 struct efi_variable *new_var = (struct efi_variable *)buf; 401 struct efi_variable *new_var = (struct efi_variable *)buf;
402 struct efivars *efivars = bin_attr->private;
410 struct efivar_entry *search_efivar, *n; 403 struct efivar_entry *search_efivar, *n;
411 unsigned long strsize1, strsize2; 404 unsigned long strsize1, strsize2;
412 efi_status_t status = EFI_NOT_FOUND; 405 efi_status_t status = EFI_NOT_FOUND;
@@ -415,12 +408,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
415 if (!capable(CAP_SYS_ADMIN)) 408 if (!capable(CAP_SYS_ADMIN))
416 return -EACCES; 409 return -EACCES;
417 410
418 spin_lock(&efivars_lock); 411 spin_lock(&efivars->lock);
419 412
420 /* 413 /*
421 * Does this variable already exist? 414 * Does this variable already exist?
422 */ 415 */
423 list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { 416 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
424 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); 417 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
425 strsize2 = utf8_strsize(new_var->VariableName, 1024); 418 strsize2 = utf8_strsize(new_var->VariableName, 1024);
426 if (strsize1 == strsize2 && 419 if (strsize1 == strsize2 &&
@@ -433,28 +426,31 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
433 } 426 }
434 } 427 }
435 if (found) { 428 if (found) {
436 spin_unlock(&efivars_lock); 429 spin_unlock(&efivars->lock);
437 return -EINVAL; 430 return -EINVAL;
438 } 431 }
439 432
440 /* now *really* create the variable via EFI */ 433 /* now *really* create the variable via EFI */
441 status = efi.set_variable(new_var->VariableName, 434 status = efivars->ops->set_variable(new_var->VariableName,
442 &new_var->VendorGuid, 435 &new_var->VendorGuid,
443 new_var->Attributes, 436 new_var->Attributes,
444 new_var->DataSize, 437 new_var->DataSize,
445 new_var->Data); 438 new_var->Data);
446 439
447 if (status != EFI_SUCCESS) { 440 if (status != EFI_SUCCESS) {
448 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 441 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
449 status); 442 status);
450 spin_unlock(&efivars_lock); 443 spin_unlock(&efivars->lock);
451 return -EIO; 444 return -EIO;
452 } 445 }
453 spin_unlock(&efivars_lock); 446 spin_unlock(&efivars->lock);
454 447
455 /* Create the entry in sysfs. Locking is not required here */ 448 /* Create the entry in sysfs. Locking is not required here */
456 status = efivar_create_sysfs_entry(utf8_strsize(new_var->VariableName, 449 status = efivar_create_sysfs_entry(efivars,
457 1024), new_var->VariableName, &new_var->VendorGuid); 450 utf8_strsize(new_var->VariableName,
451 1024),
452 new_var->VariableName,
453 &new_var->VendorGuid);
458 if (status) { 454 if (status) {
459 printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n"); 455 printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");
460 } 456 }
@@ -466,6 +462,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
466 char *buf, loff_t pos, size_t count) 462 char *buf, loff_t pos, size_t count)
467{ 463{
468 struct efi_variable *del_var = (struct efi_variable *)buf; 464 struct efi_variable *del_var = (struct efi_variable *)buf;
465 struct efivars *efivars = bin_attr->private;
469 struct efivar_entry *search_efivar, *n; 466 struct efivar_entry *search_efivar, *n;
470 unsigned long strsize1, strsize2; 467 unsigned long strsize1, strsize2;
471 efi_status_t status = EFI_NOT_FOUND; 468 efi_status_t status = EFI_NOT_FOUND;
@@ -474,12 +471,12 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
474 if (!capable(CAP_SYS_ADMIN)) 471 if (!capable(CAP_SYS_ADMIN))
475 return -EACCES; 472 return -EACCES;
476 473
477 spin_lock(&efivars_lock); 474 spin_lock(&efivars->lock);
478 475
479 /* 476 /*
480 * Does this variable already exist? 477 * Does this variable already exist?
481 */ 478 */
482 list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { 479 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
483 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); 480 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
484 strsize2 = utf8_strsize(del_var->VariableName, 1024); 481 strsize2 = utf8_strsize(del_var->VariableName, 1024);
485 if (strsize1 == strsize2 && 482 if (strsize1 == strsize2 &&
@@ -492,44 +489,34 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
492 } 489 }
493 } 490 }
494 if (!found) { 491 if (!found) {
495 spin_unlock(&efivars_lock); 492 spin_unlock(&efivars->lock);
496 return -EINVAL; 493 return -EINVAL;
497 } 494 }
498 /* force the Attributes/DataSize to 0 to ensure deletion */ 495 /* force the Attributes/DataSize to 0 to ensure deletion */
499 del_var->Attributes = 0; 496 del_var->Attributes = 0;
500 del_var->DataSize = 0; 497 del_var->DataSize = 0;
501 498
502 status = efi.set_variable(del_var->VariableName, 499 status = efivars->ops->set_variable(del_var->VariableName,
503 &del_var->VendorGuid, 500 &del_var->VendorGuid,
504 del_var->Attributes, 501 del_var->Attributes,
505 del_var->DataSize, 502 del_var->DataSize,
506 del_var->Data); 503 del_var->Data);
507 504
508 if (status != EFI_SUCCESS) { 505 if (status != EFI_SUCCESS) {
509 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 506 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
510 status); 507 status);
511 spin_unlock(&efivars_lock); 508 spin_unlock(&efivars->lock);
512 return -EIO; 509 return -EIO;
513 } 510 }
514 list_del(&search_efivar->list); 511 list_del(&search_efivar->list);
515 /* We need to release this lock before unregistering. */ 512 /* We need to release this lock before unregistering. */
516 spin_unlock(&efivars_lock); 513 spin_unlock(&efivars->lock);
517 efivar_unregister(search_efivar); 514 efivar_unregister(search_efivar);
518 515
519 /* It's dead Jim.... */ 516 /* It's dead Jim.... */
520 return count; 517 return count;
521} 518}
522 519
523static struct bin_attribute var_subsys_attr_new_var = {
524 .attr = {.name = "new_var", .mode = 0200},
525 .write = efivar_create,
526};
527
528static struct bin_attribute var_subsys_attr_del_var = {
529 .attr = {.name = "del_var", .mode = 0200},
530 .write = efivar_delete,
531};
532
533/* 520/*
534 * Let's not leave out systab information that snuck into 521 * Let's not leave out systab information that snuck into
535 * the efivars driver 522 * the efivars driver
@@ -572,8 +559,6 @@ static struct attribute_group efi_subsys_attr_group = {
572 .attrs = efi_subsys_attrs, 559 .attrs = efi_subsys_attrs,
573}; 560};
574 561
575
576static struct kset *vars_kset;
577static struct kobject *efi_kobj; 562static struct kobject *efi_kobj;
578 563
579/* 564/*
@@ -582,13 +567,14 @@ static struct kobject *efi_kobj;
582 * variable_name_size = number of bytes required to hold 567 * variable_name_size = number of bytes required to hold
583 * variable_name (not counting the NULL 568 * variable_name (not counting the NULL
584 * character at the end. 569 * character at the end.
585 * efivars_lock is not held on entry or exit. 570 * efivars->lock is not held on entry or exit.
586 * Returns 1 on failure, 0 on success 571 * Returns 1 on failure, 0 on success
587 */ 572 */
588static int 573static int
589efivar_create_sysfs_entry(unsigned long variable_name_size, 574efivar_create_sysfs_entry(struct efivars *efivars,
590 efi_char16_t *variable_name, 575 unsigned long variable_name_size,
591 efi_guid_t *vendor_guid) 576 efi_char16_t *variable_name,
577 efi_guid_t *vendor_guid)
592{ 578{
593 int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; 579 int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
594 char *short_name; 580 char *short_name;
@@ -603,6 +589,7 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
603 return 1; 589 return 1;
604 } 590 }
605 591
592 new_efivar->efivars = efivars;
606 memcpy(new_efivar->var.VariableName, variable_name, 593 memcpy(new_efivar->var.VariableName, variable_name,
607 variable_name_size); 594 variable_name_size);
608 memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t)); 595 memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
@@ -618,7 +605,7 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
618 *(short_name + strlen(short_name)) = '-'; 605 *(short_name + strlen(short_name)) = '-';
619 efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); 606 efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
620 607
621 new_efivar->kobj.kset = vars_kset; 608 new_efivar->kobj.kset = efivars->kset;
622 i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL, 609 i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
623 "%s", short_name); 610 "%s", short_name);
624 if (i) { 611 if (i) {
@@ -631,22 +618,95 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
631 kfree(short_name); 618 kfree(short_name);
632 short_name = NULL; 619 short_name = NULL;
633 620
634 spin_lock(&efivars_lock); 621 spin_lock(&efivars->lock);
635 list_add(&new_efivar->list, &efivar_list); 622 list_add(&new_efivar->list, &efivars->list);
636 spin_unlock(&efivars_lock); 623 spin_unlock(&efivars->lock);
637 624
638 return 0; 625 return 0;
639} 626}
640/*
641 * For now we register the efi subsystem with the firmware subsystem
642 * and the vars subsystem with the efi subsystem. In the future, it
643 * might make sense to split off the efi subsystem into its own
644 * driver, but for now only efivars will register with it, so just
645 * include it here.
646 */
647 627
648static int __init 628static int
649efivars_init(void) 629create_efivars_bin_attributes(struct efivars *efivars)
630{
631 struct bin_attribute *attr;
632 int error;
633
634 /* new_var */
635 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
636 if (!attr)
637 return -ENOMEM;
638
639 attr->attr.name = "new_var";
640 attr->attr.mode = 0200;
641 attr->write = efivar_create;
642 attr->private = efivars;
643 efivars->new_var = attr;
644
645 /* del_var */
646 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
647 if (!attr) {
648 error = -ENOMEM;
649 goto out_free;
650 }
651 attr->attr.name = "del_var";
652 attr->attr.mode = 0200;
653 attr->write = efivar_delete;
654 attr->private = efivars;
655 efivars->del_var = attr;
656
657 sysfs_bin_attr_init(efivars->new_var);
658 sysfs_bin_attr_init(efivars->del_var);
659
660 /* Register */
661 error = sysfs_create_bin_file(&efivars->kset->kobj,
662 efivars->new_var);
663 if (error) {
664 printk(KERN_ERR "efivars: unable to create new_var sysfs file"
665 " due to error %d\n", error);
666 goto out_free;
667 }
668 error = sysfs_create_bin_file(&efivars->kset->kobj,
669 efivars->del_var);
670 if (error) {
671 printk(KERN_ERR "efivars: unable to create del_var sysfs file"
672 " due to error %d\n", error);
673 sysfs_remove_bin_file(&efivars->kset->kobj,
674 efivars->new_var);
675 goto out_free;
676 }
677
678 return 0;
679out_free:
680 kfree(efivars->del_var);
681 efivars->del_var = NULL;
682 kfree(efivars->new_var);
683 efivars->new_var = NULL;
684 return error;
685}
686
687void unregister_efivars(struct efivars *efivars)
688{
689 struct efivar_entry *entry, *n;
690
691 list_for_each_entry_safe(entry, n, &efivars->list, list) {
692 spin_lock(&efivars->lock);
693 list_del(&entry->list);
694 spin_unlock(&efivars->lock);
695 efivar_unregister(entry);
696 }
697 if (efivars->new_var)
698 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
699 if (efivars->del_var)
700 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
701 kfree(efivars->new_var);
702 kfree(efivars->del_var);
703 kset_unregister(efivars->kset);
704}
705EXPORT_SYMBOL_GPL(unregister_efivars);
706
707int register_efivars(struct efivars *efivars,
708 const struct efivar_operations *ops,
709 struct kobject *parent_kobj)
650{ 710{
651 efi_status_t status = EFI_NOT_FOUND; 711 efi_status_t status = EFI_NOT_FOUND;
652 efi_guid_t vendor_guid; 712 efi_guid_t vendor_guid;
@@ -654,31 +714,21 @@ efivars_init(void)
654 unsigned long variable_name_size = 1024; 714 unsigned long variable_name_size = 1024;
655 int error = 0; 715 int error = 0;
656 716
657 if (!efi_enabled)
658 return -ENODEV;
659
660 variable_name = kzalloc(variable_name_size, GFP_KERNEL); 717 variable_name = kzalloc(variable_name_size, GFP_KERNEL);
661 if (!variable_name) { 718 if (!variable_name) {
662 printk(KERN_ERR "efivars: Memory allocation failed.\n"); 719 printk(KERN_ERR "efivars: Memory allocation failed.\n");
663 return -ENOMEM; 720 return -ENOMEM;
664 } 721 }
665 722
666 printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, 723 spin_lock_init(&efivars->lock);
667 EFIVARS_DATE); 724 INIT_LIST_HEAD(&efivars->list);
725 efivars->ops = ops;
668 726
669 /* For now we'll register the efi directory at /sys/firmware/efi */ 727 efivars->kset = kset_create_and_add("vars", NULL, parent_kobj);
670 efi_kobj = kobject_create_and_add("efi", firmware_kobj); 728 if (!efivars->kset) {
671 if (!efi_kobj) {
672 printk(KERN_ERR "efivars: Firmware registration failed.\n");
673 error = -ENOMEM;
674 goto out_free;
675 }
676
677 vars_kset = kset_create_and_add("vars", NULL, efi_kobj);
678 if (!vars_kset) {
679 printk(KERN_ERR "efivars: Subsystem registration failed.\n"); 729 printk(KERN_ERR "efivars: Subsystem registration failed.\n");
680 error = -ENOMEM; 730 error = -ENOMEM;
681 goto out_firmware_unregister; 731 goto out;
682 } 732 }
683 733
684 /* 734 /*
@@ -689,14 +739,15 @@ efivars_init(void)
689 do { 739 do {
690 variable_name_size = 1024; 740 variable_name_size = 1024;
691 741
692 status = efi.get_next_variable(&variable_name_size, 742 status = ops->get_next_variable(&variable_name_size,
693 variable_name, 743 variable_name,
694 &vendor_guid); 744 &vendor_guid);
695 switch (status) { 745 switch (status) {
696 case EFI_SUCCESS: 746 case EFI_SUCCESS:
697 efivar_create_sysfs_entry(variable_name_size, 747 efivar_create_sysfs_entry(efivars,
698 variable_name, 748 variable_name_size,
699 &vendor_guid); 749 variable_name,
750 &vendor_guid);
700 break; 751 break;
701 case EFI_NOT_FOUND: 752 case EFI_NOT_FOUND:
702 break; 753 break;
@@ -708,53 +759,78 @@ efivars_init(void)
708 } 759 }
709 } while (status != EFI_NOT_FOUND); 760 } while (status != EFI_NOT_FOUND);
710 761
711 /* 762 error = create_efivars_bin_attributes(efivars);
712 * Now add attributes to allow creation of new vars
713 * and deletion of existing ones...
714 */
715 error = sysfs_create_bin_file(&vars_kset->kobj,
716 &var_subsys_attr_new_var);
717 if (error) 763 if (error)
718 printk(KERN_ERR "efivars: unable to create new_var sysfs file" 764 unregister_efivars(efivars);
719 " due to error %d\n", error); 765
720 error = sysfs_create_bin_file(&vars_kset->kobj, 766out:
721 &var_subsys_attr_del_var); 767 kfree(variable_name);
768
769 return error;
770}
771EXPORT_SYMBOL_GPL(register_efivars);
772
773static struct efivars __efivars;
774static struct efivar_operations ops;
775
776/*
777 * For now we register the efi subsystem with the firmware subsystem
778 * and the vars subsystem with the efi subsystem. In the future, it
779 * might make sense to split off the efi subsystem into its own
780 * driver, but for now only efivars will register with it, so just
781 * include it here.
782 */
783
784static int __init
785efivars_init(void)
786{
787 int error = 0;
788
789 printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
790 EFIVARS_DATE);
791
792 if (!efi_enabled)
793 return 0;
794
795 /* For now we'll register the efi directory at /sys/firmware/efi */
796 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
797 if (!efi_kobj) {
798 printk(KERN_ERR "efivars: Firmware registration failed.\n");
799 return -ENOMEM;
800 }
801
802 ops.get_variable = efi.get_variable;
803 ops.set_variable = efi.set_variable;
804 ops.get_next_variable = efi.get_next_variable;
805 error = register_efivars(&__efivars, &ops, efi_kobj);
722 if (error) 806 if (error)
723 printk(KERN_ERR "efivars: unable to create del_var sysfs file" 807 goto err_put;
724 " due to error %d\n", error);
725 808
726 /* Don't forget the systab entry */ 809 /* Don't forget the systab entry */
727 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); 810 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
728 if (error) 811 if (error) {
729 printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); 812 printk(KERN_ERR
730 else 813 "efivars: Sysfs attribute export failed with error %d.\n",
731 goto out_free; 814 error);
815 goto err_unregister;
816 }
732 817
733 kset_unregister(vars_kset); 818 return 0;
734 819
735out_firmware_unregister: 820err_unregister:
821 unregister_efivars(&__efivars);
822err_put:
736 kobject_put(efi_kobj); 823 kobject_put(efi_kobj);
737
738out_free:
739 kfree(variable_name);
740
741 return error; 824 return error;
742} 825}
743 826
744static void __exit 827static void __exit
745efivars_exit(void) 828efivars_exit(void)
746{ 829{
747 struct efivar_entry *entry, *n; 830 if (efi_enabled) {
748 831 unregister_efivars(&__efivars);
749 list_for_each_entry_safe(entry, n, &efivar_list, list) { 832 kobject_put(efi_kobj);
750 spin_lock(&efivars_lock);
751 list_del(&entry->list);
752 spin_unlock(&efivars_lock);
753 efivar_unregister(entry);
754 } 833 }
755
756 kset_unregister(vars_kset);
757 kobject_put(efi_kobj);
758} 834}
759 835
760module_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..2f21b0bfe653
--- /dev/null
+++ b/drivers/firmware/google/Kconfig
@@ -0,0 +1,32 @@
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
17 select EFI_VARS
18 help
19 Say Y here if you want to enable SMI callbacks for Google
20 platforms. This provides an interface for writing to and
21 clearing the EFI event log and reading and writing NVRAM
22 variables.
23
24config GOOGLE_MEMCONSOLE
25 tristate "Firmware Memory Console"
26 depends on DMI
27 help
28 This option enables the kernel to search for a firmware log in
29 the EBDA on Google servers. If found, this log is exported to
30 userland in the file /sys/firmware/log.
31
32endmenu
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.c b/drivers/firmware/iscsi_ibft.c
index 6148a1c67895..ce33f4626957 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -87,8 +87,8 @@
87#define IBFT_ISCSI_VERSION "0.5.0" 87#define IBFT_ISCSI_VERSION "0.5.0"
88#define IBFT_ISCSI_DATE "2010-Feb-25" 88#define IBFT_ISCSI_DATE "2010-Feb-25"
89 89
90MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \ 90MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and "
91Konrad Rzeszutek <ketuzsezr@darnok.org>"); 91 "Konrad Rzeszutek <ketuzsezr@darnok.org>");
92MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information"); 92MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
93MODULE_LICENSE("GPL"); 93MODULE_LICENSE("GPL");
94MODULE_VERSION(IBFT_ISCSI_VERSION); 94MODULE_VERSION(IBFT_ISCSI_VERSION);
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index 2192456dfd68..bfe723266fd8 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,14 @@ 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#ifdef CONFIG_ACPI
112 int i;
113#endif
93 ibft_addr = NULL; 114 ibft_addr = NULL;
94 115
95#ifdef CONFIG_ACPI 116#ifdef CONFIG_ACPI
96 /* 117 for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++)
97 * One spec says "IBFT", the other says "iBFT". We have to check 118 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 */ 119#endif /* CONFIG_ACPI */
105 120
106 /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will 121 /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
index ce910d68bd19..e5530608e00d 100644
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * Definitions for PCDP-defined console devices 2 * Definitions for PCDP-defined console devices
3 * 3 *
4 * v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf 4 * For DIG64_HCDPv10a_01.pdf and DIG64_PCDPv20.pdf (v1.0a and v2.0 resp.),
5 * v2.0: http://www.dig64.org/specifications/DIG64_PCDPv20.pdf 5 * please see <http://www.dig64.org/specifications/>
6 * 6 *
7 * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P. 7 * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P.
8 * Khalid Aziz <khalid.aziz@hp.com> 8 * Khalid Aziz <khalid.aziz@hp.com>
diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c
new file mode 100644
index 000000000000..c19cd2c39fa6
--- /dev/null
+++ b/drivers/firmware/sigma.c
@@ -0,0 +1,115 @@
1/*
2 * Load Analog Devices SigmaStudio firmware files
3 *
4 * Copyright 2009-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/crc32.h>
10#include <linux/delay.h>
11#include <linux/firmware.h>
12#include <linux/kernel.h>
13#include <linux/i2c.h>
14#include <linux/sigma.h>
15
16/* Return: 0==OK, <0==error, =1 ==no more actions */
17static int
18process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw)
19{
20 struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos);
21 size_t len = sigma_action_len(sa);
22 int ret = 0;
23
24 pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
25 sa->instr, sa->addr, len);
26
27 switch (sa->instr) {
28 case SIGMA_ACTION_WRITEXBYTES:
29 case SIGMA_ACTION_WRITESINGLE:
30 case SIGMA_ACTION_WRITESAFELOAD:
31 if (ssfw->fw->size < ssfw->pos + len)
32 return -EINVAL;
33 ret = i2c_master_send(client, (void *)&sa->addr, len);
34 if (ret < 0)
35 return -EINVAL;
36 break;
37
38 case SIGMA_ACTION_DELAY:
39 ret = 0;
40 udelay(len);
41 len = 0;
42 break;
43
44 case SIGMA_ACTION_END:
45 return 1;
46
47 default:
48 return -EINVAL;
49 }
50
51 /* when arrive here ret=0 or sent data */
52 ssfw->pos += sigma_action_size(sa, len);
53 return ssfw->pos == ssfw->fw->size;
54}
55
56static int
57process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw)
58{
59 pr_debug("%s: processing %p\n", __func__, ssfw);
60
61 while (1) {
62 int ret = process_sigma_action(client, ssfw);
63 pr_debug("%s: action returned %i\n", __func__, ret);
64 if (ret == 1)
65 return 0;
66 else if (ret)
67 return ret;
68 }
69}
70
71int process_sigma_firmware(struct i2c_client *client, const char *name)
72{
73 int ret;
74 struct sigma_firmware_header *ssfw_head;
75 struct sigma_firmware ssfw;
76 const struct firmware *fw;
77 u32 crc;
78
79 pr_debug("%s: loading firmware %s\n", __func__, name);
80
81 /* first load the blob */
82 ret = request_firmware(&fw, name, &client->dev);
83 if (ret) {
84 pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
85 return ret;
86 }
87 ssfw.fw = fw;
88
89 /* then verify the header */
90 ret = -EINVAL;
91 if (fw->size < sizeof(*ssfw_head))
92 goto done;
93
94 ssfw_head = (void *)fw->data;
95 if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic)))
96 goto done;
97
98 crc = crc32(0, fw->data, fw->size);
99 pr_debug("%s: crc=%x\n", __func__, crc);
100 if (crc != ssfw_head->crc)
101 goto done;
102
103 ssfw.pos = sizeof(*ssfw_head);
104
105 /* finally process all of the actions */
106 ret = process_sigma_actions(client, &ssfw);
107
108 done:
109 release_firmware(fw);
110
111 pr_debug("%s: loaded %s\n", __func__, name);
112
113 return ret;
114}
115EXPORT_SYMBOL(process_sigma_firmware);