1
2
3
4
5
6
7
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#include <linux/module.h>
31
32#define GSMI_SHUTDOWN_CLEAN 0
33
34#define GSMI_SHUTDOWN_NMIWDT 1
35#define GSMI_SHUTDOWN_PANIC 2
36#define GSMI_SHUTDOWN_OOPS 3
37#define GSMI_SHUTDOWN_DIE 4
38#define GSMI_SHUTDOWN_MCE 5
39#define GSMI_SHUTDOWN_SOFTWDT 6
40#define GSMI_SHUTDOWN_MBE 7
41#define GSMI_SHUTDOWN_TRIPLE 8
42
43#define DRIVER_VERSION "1.0"
44#define GSMI_GUID_SIZE 16
45#define GSMI_BUF_SIZE 1024
46#define GSMI_BUF_ALIGN sizeof(u64)
47#define GSMI_CALLBACK 0xef
48
49
50#define GSMI_SUCCESS 0x00
51#define GSMI_UNSUPPORTED2 0x03
52#define GSMI_LOG_FULL 0x0b
53#define GSMI_VAR_NOT_FOUND 0x0e
54#define GSMI_HANDSHAKE_SPIN 0x7d
55#define GSMI_HANDSHAKE_CF 0x7e
56#define GSMI_HANDSHAKE_NONE 0x7f
57#define GSMI_INVALID_PARAMETER 0x82
58#define GSMI_UNSUPPORTED 0x83
59#define GSMI_BUFFER_TOO_SMALL 0x85
60#define GSMI_NOT_READY 0x86
61#define GSMI_DEVICE_ERROR 0x87
62#define GSMI_NOT_FOUND 0x8e
63
64#define QUIRKY_BOARD_HASH 0x78a30a50
65
66
67#define GSMI_CMD_GET_NVRAM_VAR 0x01
68#define GSMI_CMD_GET_NEXT_VAR 0x02
69#define GSMI_CMD_SET_NVRAM_VAR 0x03
70#define GSMI_CMD_SET_EVENT_LOG 0x08
71#define GSMI_CMD_CLEAR_EVENT_LOG 0x09
72#define GSMI_CMD_CLEAR_CONFIG 0x20
73#define GSMI_CMD_HANDSHAKE_TYPE 0xC1
74
75
76#define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
77
78
79struct gsmi_buf {
80 u8 *start;
81 size_t length;
82 dma_addr_t handle;
83 u32 address;
84};
85
86struct gsmi_device {
87 struct platform_device *pdev;
88 struct gsmi_buf *name_buf;
89 struct gsmi_buf *data_buf;
90 struct gsmi_buf *param_buf;
91 spinlock_t lock;
92 u16 smi_cmd;
93 int handshake_type;
94 struct dma_pool *dma_pool;
95} gsmi_dev;
96
97
98struct gsmi_nvram_var_param {
99 efi_guid_t guid;
100 u32 name_ptr;
101 u32 attributes;
102 u32 data_len;
103 u32 data_ptr;
104} __packed;
105
106struct gsmi_get_next_var_param {
107 u8 guid[GSMI_GUID_SIZE];
108 u32 name_ptr;
109 u32 name_len;
110} __packed;
111
112struct gsmi_set_eventlog_param {
113 u32 data_ptr;
114 u32 data_len;
115 u32 type;
116} __packed;
117
118
119struct gsmi_log_entry_type_1 {
120 u16 type;
121 u32 instance;
122} __packed;
123
124
125
126
127
128
129#define GSMI_DEFAULT_SPINCOUNT 0x10000
130static unsigned int spincount = GSMI_DEFAULT_SPINCOUNT;
131module_param(spincount, uint, 0600);
132MODULE_PARM_DESC(spincount,
133 "The number of loop iterations to use when using the spin handshake.");
134
135static struct gsmi_buf *gsmi_buf_alloc(void)
136{
137 struct gsmi_buf *smibuf;
138
139 smibuf = kzalloc(sizeof(*smibuf), GFP_KERNEL);
140 if (!smibuf) {
141 printk(KERN_ERR "gsmi: out of memory\n");
142 return NULL;
143 }
144
145
146 smibuf->start = dma_pool_alloc(gsmi_dev.dma_pool, GFP_KERNEL,
147 &smibuf->handle);
148 if (!smibuf->start) {
149 printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
150 kfree(smibuf);
151 return NULL;
152 }
153
154
155 smibuf->length = GSMI_BUF_SIZE;
156 smibuf->address = (u32)virt_to_phys(smibuf->start);
157
158 return smibuf;
159}
160
161static void gsmi_buf_free(struct gsmi_buf *smibuf)
162{
163 if (smibuf) {
164 if (smibuf->start)
165 dma_pool_free(gsmi_dev.dma_pool, smibuf->start,
166 smibuf->handle);
167 kfree(smibuf);
168 }
169}
170
171
172
173
174
175static int gsmi_exec(u8 func, u8 sub)
176{
177 u16 cmd = (sub << 8) | func;
178 u16 result = 0;
179 int rc = 0;
180
181
182
183
184
185
186
187
188
189 if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_CF) {
190
191
192
193
194
195
196
197 asm volatile (
198 "stc\n"
199 "outb %%al, %%dx\n"
200 "1: jc 1b\n"
201 : "=a" (result)
202 : "0" (cmd),
203 "d" (gsmi_dev.smi_cmd),
204 "b" (gsmi_dev.param_buf->address)
205 : "memory", "cc"
206 );
207 } else if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_SPIN) {
208
209
210
211
212 asm volatile (
213 "outb %%al, %%dx\n"
214 "1: loop 1b\n"
215 : "=a" (result)
216 : "0" (cmd),
217 "d" (gsmi_dev.smi_cmd),
218 "b" (gsmi_dev.param_buf->address),
219 "c" (spincount)
220 : "memory", "cc"
221 );
222 } else {
223
224
225
226
227
228 asm volatile (
229 "outb %%al, %%dx\n\t"
230 : "=a" (result)
231 : "0" (cmd),
232 "d" (gsmi_dev.smi_cmd),
233 "b" (gsmi_dev.param_buf->address)
234 : "memory", "cc"
235 );
236 }
237
238
239 switch (result) {
240 case GSMI_SUCCESS:
241 break;
242 case GSMI_VAR_NOT_FOUND:
243
244 rc = 1;
245 break;
246 case GSMI_INVALID_PARAMETER:
247 printk(KERN_ERR "gsmi: exec 0x%04x: Invalid parameter\n", cmd);
248 rc = -EINVAL;
249 break;
250 case GSMI_BUFFER_TOO_SMALL:
251 printk(KERN_ERR "gsmi: exec 0x%04x: Buffer too small\n", cmd);
252 rc = -ENOMEM;
253 break;
254 case GSMI_UNSUPPORTED:
255 case GSMI_UNSUPPORTED2:
256 if (sub != GSMI_CMD_HANDSHAKE_TYPE)
257 printk(KERN_ERR "gsmi: exec 0x%04x: Not supported\n",
258 cmd);
259 rc = -ENOSYS;
260 break;
261 case GSMI_NOT_READY:
262 printk(KERN_ERR "gsmi: exec 0x%04x: Not ready\n", cmd);
263 rc = -EBUSY;
264 break;
265 case GSMI_DEVICE_ERROR:
266 printk(KERN_ERR "gsmi: exec 0x%04x: Device error\n", cmd);
267 rc = -EFAULT;
268 break;
269 case GSMI_NOT_FOUND:
270 printk(KERN_ERR "gsmi: exec 0x%04x: Data not found\n", cmd);
271 rc = -ENOENT;
272 break;
273 case GSMI_LOG_FULL:
274 printk(KERN_ERR "gsmi: exec 0x%04x: Log full\n", cmd);
275 rc = -ENOSPC;
276 break;
277 case GSMI_HANDSHAKE_CF:
278 case GSMI_HANDSHAKE_SPIN:
279 case GSMI_HANDSHAKE_NONE:
280 rc = result;
281 break;
282 default:
283 printk(KERN_ERR "gsmi: exec 0x%04x: Unknown error 0x%04x\n",
284 cmd, result);
285 rc = -ENXIO;
286 }
287
288 return rc;
289}
290
291
292static size_t
293utf16_strlen(efi_char16_t *data, unsigned long maxlength)
294{
295 unsigned long length = 0;
296
297 while (*data++ != 0 && length < maxlength)
298 length++;
299 return length;
300}
301
302static efi_status_t gsmi_get_variable(efi_char16_t *name,
303 efi_guid_t *vendor, u32 *attr,
304 unsigned long *data_size,
305 void *data)
306{
307 struct gsmi_nvram_var_param param = {
308 .name_ptr = gsmi_dev.name_buf->address,
309 .data_ptr = gsmi_dev.data_buf->address,
310 .data_len = (u32)*data_size,
311 };
312 efi_status_t ret = EFI_SUCCESS;
313 unsigned long flags;
314 size_t name_len = utf16_strlen(name, GSMI_BUF_SIZE / 2);
315 int rc;
316
317 if (name_len >= GSMI_BUF_SIZE / 2)
318 return EFI_BAD_BUFFER_SIZE;
319
320 spin_lock_irqsave(&gsmi_dev.lock, flags);
321
322
323 memcpy(¶m.guid, vendor, sizeof(param.guid));
324
325
326 memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
327 memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
328
329
330 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
331
332
333 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
334 memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
335
336 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NVRAM_VAR);
337 if (rc < 0) {
338 printk(KERN_ERR "gsmi: Get Variable failed\n");
339 ret = EFI_LOAD_ERROR;
340 } else if (rc == 1) {
341
342 ret = EFI_NOT_FOUND;
343 } else {
344
345 memcpy(¶m, gsmi_dev.param_buf->start, sizeof(param));
346
347
348 *data_size = min_t(unsigned long, *data_size,
349 gsmi_dev.data_buf->length);
350 *data_size = min_t(unsigned long, *data_size, param.data_len);
351
352
353 memcpy(data, gsmi_dev.data_buf->start, *data_size);
354
355
356 *attr = EFI_VARIABLE_NON_VOLATILE |
357 EFI_VARIABLE_BOOTSERVICE_ACCESS |
358 EFI_VARIABLE_RUNTIME_ACCESS;
359 }
360
361 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
362
363 return ret;
364}
365
366static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
367 efi_char16_t *name,
368 efi_guid_t *vendor)
369{
370 struct gsmi_get_next_var_param param = {
371 .name_ptr = gsmi_dev.name_buf->address,
372 .name_len = gsmi_dev.name_buf->length,
373 };
374 efi_status_t ret = EFI_SUCCESS;
375 int rc;
376 unsigned long flags;
377
378
379 if (*name_size != GSMI_BUF_SIZE)
380 return EFI_BAD_BUFFER_SIZE;
381
382
383 if (utf16_strlen(name, GSMI_BUF_SIZE / 2) == GSMI_BUF_SIZE / 2)
384 return EFI_INVALID_PARAMETER;
385
386 spin_lock_irqsave(&gsmi_dev.lock, flags);
387
388
389 memcpy(¶m.guid, vendor, sizeof(param.guid));
390
391
392 memcpy(gsmi_dev.name_buf->start, name, *name_size);
393
394
395 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
396 memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
397
398 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NEXT_VAR);
399 if (rc < 0) {
400 printk(KERN_ERR "gsmi: Get Next Variable Name failed\n");
401 ret = EFI_LOAD_ERROR;
402 } else if (rc == 1) {
403
404 ret = EFI_NOT_FOUND;
405 } else {
406
407 memcpy(¶m, gsmi_dev.param_buf->start, sizeof(param));
408
409
410 memcpy(name, gsmi_dev.name_buf->start, GSMI_BUF_SIZE);
411 *name_size = utf16_strlen(name, GSMI_BUF_SIZE / 2) * 2;
412
413
414 memcpy(vendor, ¶m.guid, sizeof(param.guid));
415 ret = EFI_SUCCESS;
416 }
417
418 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
419
420 return ret;
421}
422
423static efi_status_t gsmi_set_variable(efi_char16_t *name,
424 efi_guid_t *vendor,
425 u32 attr,
426 unsigned long data_size,
427 void *data)
428{
429 struct gsmi_nvram_var_param param = {
430 .name_ptr = gsmi_dev.name_buf->address,
431 .data_ptr = gsmi_dev.data_buf->address,
432 .data_len = (u32)data_size,
433 .attributes = EFI_VARIABLE_NON_VOLATILE |
434 EFI_VARIABLE_BOOTSERVICE_ACCESS |
435 EFI_VARIABLE_RUNTIME_ACCESS,
436 };
437 size_t name_len = utf16_strlen(name, GSMI_BUF_SIZE / 2);
438 efi_status_t ret = EFI_SUCCESS;
439 int rc;
440 unsigned long flags;
441
442 if (name_len >= GSMI_BUF_SIZE / 2)
443 return EFI_BAD_BUFFER_SIZE;
444
445 spin_lock_irqsave(&gsmi_dev.lock, flags);
446
447
448 memcpy(¶m.guid, vendor, sizeof(param.guid));
449
450
451 memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
452 memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
453
454
455 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
456 memcpy(gsmi_dev.data_buf->start, data, data_size);
457
458
459 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
460 memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
461
462 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_NVRAM_VAR);
463 if (rc < 0) {
464 printk(KERN_ERR "gsmi: Set Variable failed\n");
465 ret = EFI_INVALID_PARAMETER;
466 }
467
468 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
469
470 return ret;
471}
472
473static const struct efivar_operations efivar_ops = {
474 .get_variable = gsmi_get_variable,
475 .set_variable = gsmi_set_variable,
476 .get_next_variable = gsmi_get_next_variable,
477};
478
479static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
480 struct bin_attribute *bin_attr,
481 char *buf, loff_t pos, size_t count)
482{
483 struct gsmi_set_eventlog_param param = {
484 .data_ptr = gsmi_dev.data_buf->address,
485 };
486 int rc = 0;
487 unsigned long flags;
488
489
490 if (count < sizeof(u32))
491 return -EINVAL;
492 param.type = *(u32 *)buf;
493 count -= sizeof(u32);
494 buf += sizeof(u32);
495
496
497 if (count > gsmi_dev.data_buf->length)
498 return -EINVAL;
499 param.data_len = count - sizeof(u32);
500
501 spin_lock_irqsave(&gsmi_dev.lock, flags);
502
503
504 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
505 memcpy(gsmi_dev.data_buf->start, buf, param.data_len);
506
507
508 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
509 memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
510
511 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
512 if (rc < 0)
513 printk(KERN_ERR "gsmi: Set Event Log failed\n");
514
515 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
516
517 return rc;
518
519}
520
521static struct bin_attribute eventlog_bin_attr = {
522 .attr = {.name = "append_to_eventlog", .mode = 0200},
523 .write = eventlog_write,
524};
525
526static ssize_t gsmi_clear_eventlog_store(struct kobject *kobj,
527 struct kobj_attribute *attr,
528 const char *buf, size_t count)
529{
530 int rc;
531 unsigned long flags;
532 unsigned long val;
533 struct {
534 u32 percentage;
535 u32 data_type;
536 } param;
537
538 rc = strict_strtoul(buf, 0, &val);
539 if (rc)
540 return rc;
541
542
543
544
545
546 if (val > 100)
547 return -EINVAL;
548
549
550 param.percentage = val;
551 param.data_type = 0;
552
553 spin_lock_irqsave(&gsmi_dev.lock, flags);
554
555
556 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
557 memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
558
559 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_EVENT_LOG);
560
561 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
562
563 if (rc)
564 return rc;
565 return count;
566}
567
568static struct kobj_attribute gsmi_clear_eventlog_attr = {
569 .attr = {.name = "clear_eventlog", .mode = 0200},
570 .store = gsmi_clear_eventlog_store,
571};
572
573static ssize_t gsmi_clear_config_store(struct kobject *kobj,
574 struct kobj_attribute *attr,
575 const char *buf, size_t count)
576{
577 int rc;
578 unsigned long flags;
579
580 spin_lock_irqsave(&gsmi_dev.lock, flags);
581
582
583 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
584
585 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_CONFIG);
586
587 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
588
589 if (rc)
590 return rc;
591 return count;
592}
593
594static struct kobj_attribute gsmi_clear_config_attr = {
595 .attr = {.name = "clear_config", .mode = 0200},
596 .store = gsmi_clear_config_store,
597};
598
599static const struct attribute *gsmi_attrs[] = {
600 &gsmi_clear_config_attr.attr,
601 &gsmi_clear_eventlog_attr.attr,
602 NULL,
603};
604
605static int gsmi_shutdown_reason(int reason)
606{
607 struct gsmi_log_entry_type_1 entry = {
608 .type = GSMI_LOG_ENTRY_TYPE_KERNEL,
609 .instance = reason,
610 };
611 struct gsmi_set_eventlog_param param = {
612 .data_len = sizeof(entry),
613 .type = 1,
614 };
615 static int saved_reason;
616 int rc = 0;
617 unsigned long flags;
618
619
620 if (saved_reason & (1 << reason))
621 return 0;
622
623 spin_lock_irqsave(&gsmi_dev.lock, flags);
624
625 saved_reason |= (1 << reason);
626
627
628 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
629 memcpy(gsmi_dev.data_buf->start, &entry, sizeof(entry));
630
631
632 param.data_ptr = gsmi_dev.data_buf->address;
633 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
634 memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
635
636 rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
637
638 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
639
640 if (rc < 0)
641 printk(KERN_ERR "gsmi: Log Shutdown Reason failed\n");
642 else
643 printk(KERN_EMERG "gsmi: Log Shutdown Reason 0x%02x\n",
644 reason);
645
646 return rc;
647}
648
649static int gsmi_reboot_callback(struct notifier_block *nb,
650 unsigned long reason, void *arg)
651{
652 gsmi_shutdown_reason(GSMI_SHUTDOWN_CLEAN);
653 return NOTIFY_DONE;
654}
655
656static struct notifier_block gsmi_reboot_notifier = {
657 .notifier_call = gsmi_reboot_callback
658};
659
660static int gsmi_die_callback(struct notifier_block *nb,
661 unsigned long reason, void *arg)
662{
663 if (reason == DIE_OOPS)
664 gsmi_shutdown_reason(GSMI_SHUTDOWN_OOPS);
665 return NOTIFY_DONE;
666}
667
668static struct notifier_block gsmi_die_notifier = {
669 .notifier_call = gsmi_die_callback
670};
671
672static int gsmi_panic_callback(struct notifier_block *nb,
673 unsigned long reason, void *arg)
674{
675 gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
676 return NOTIFY_DONE;
677}
678
679static struct notifier_block gsmi_panic_notifier = {
680 .notifier_call = gsmi_panic_callback,
681};
682
683
684
685
686
687
688
689
690
691
692static u64 __init local_hash_64(u64 val, unsigned bits)
693{
694 u64 hash = val;
695
696
697 u64 n = hash;
698 n <<= 18;
699 hash -= n;
700 n <<= 33;
701 hash -= n;
702 n <<= 3;
703 hash += n;
704 n <<= 3;
705 hash -= n;
706 n <<= 4;
707 hash += n;
708 n <<= 2;
709 hash += n;
710
711
712 return hash >> (64 - bits);
713}
714
715static u32 __init hash_oem_table_id(char s[8])
716{
717 u64 input;
718 memcpy(&input, s, 8);
719 return local_hash_64(input, 32);
720}
721
722static struct dmi_system_id gsmi_dmi_table[] __initdata = {
723 {
724 .ident = "Google Board",
725 .matches = {
726 DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
727 },
728 },
729 {}
730};
731MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
732
733static __init int gsmi_system_valid(void)
734{
735 u32 hash;
736
737 if (!dmi_check_system(gsmi_dmi_table))
738 return -ENODEV;
739
740
741
742
743
744
745
746
747
748 if (!strncmp(acpi_gbl_FADT.header.oem_table_id, "FACP", 4)) {
749 printk(KERN_INFO "gsmi: Board is too old\n");
750 return -ENODEV;
751 }
752
753
754 hash = hash_oem_table_id(acpi_gbl_FADT.header.oem_table_id);
755 if (hash == QUIRKY_BOARD_HASH) {
756 const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
757 if (strncmp(bios_ver, "1.0", 3) == 0) {
758 pr_info("gsmi: disabled on this board's BIOS %s\n",
759 bios_ver);
760 return -ENODEV;
761 }
762 }
763
764
765 if (acpi_gbl_FADT.smi_command == 0) {
766 pr_info("gsmi: missing smi_command\n");
767 return -ENODEV;
768 }
769
770
771 return 0;
772}
773
774static struct kobject *gsmi_kobj;
775static struct efivars efivars;
776
777static __init int gsmi_init(void)
778{
779 unsigned long flags;
780 int ret;
781
782 ret = gsmi_system_valid();
783 if (ret)
784 return ret;
785
786 gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
787
788
789 gsmi_dev.pdev = platform_device_register_simple("gsmi", -1, NULL, 0);
790 if (IS_ERR(gsmi_dev.pdev)) {
791 printk(KERN_ERR "gsmi: unable to register platform device\n");
792 return PTR_ERR(gsmi_dev.pdev);
793 }
794
795
796 spin_lock_init(&gsmi_dev.lock);
797
798
799 gsmi_dev.pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
800 gsmi_dev.pdev->dev.dma_mask =
801 &gsmi_dev.pdev->dev.coherent_dma_mask;
802 ret = -ENOMEM;
803 gsmi_dev.dma_pool = dma_pool_create("gsmi", &gsmi_dev.pdev->dev,
804 GSMI_BUF_SIZE, GSMI_BUF_ALIGN, 0);
805 if (!gsmi_dev.dma_pool)
806 goto out_err;
807
808
809
810
811
812 gsmi_dev.name_buf = gsmi_buf_alloc();
813 if (!gsmi_dev.name_buf) {
814 printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
815 goto out_err;
816 }
817
818 gsmi_dev.data_buf = gsmi_buf_alloc();
819 if (!gsmi_dev.data_buf) {
820 printk(KERN_ERR "gsmi: failed to allocate data buffer\n");
821 goto out_err;
822 }
823
824 gsmi_dev.param_buf = gsmi_buf_alloc();
825 if (!gsmi_dev.param_buf) {
826 printk(KERN_ERR "gsmi: failed to allocate param buffer\n");
827 goto out_err;
828 }
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858 spin_lock_irqsave(&gsmi_dev.lock, flags);
859 gsmi_dev.handshake_type = GSMI_HANDSHAKE_SPIN;
860 gsmi_dev.handshake_type =
861 gsmi_exec(GSMI_CALLBACK, GSMI_CMD_HANDSHAKE_TYPE);
862 if (gsmi_dev.handshake_type == -ENOSYS)
863 gsmi_dev.handshake_type = GSMI_HANDSHAKE_NONE;
864 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
865
866
867 if (gsmi_dev.handshake_type == -ENXIO) {
868 printk(KERN_INFO "gsmi version " DRIVER_VERSION
869 " failed to load\n");
870 ret = -ENODEV;
871 goto out_err;
872 }
873
874
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
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
890 ret = sysfs_create_files(gsmi_kobj, gsmi_attrs);
891 if (ret) {
892 printk(KERN_INFO "gsmi: Failed to add attrs");
893 goto out_remove_bin_file;
894 }
895
896 ret = register_efivars(&efivars, &efivar_ops, gsmi_kobj);
897 if (ret) {
898 printk(KERN_INFO "gsmi: Failed to register efivars\n");
899 goto out_remove_sysfs_files;
900 }
901
902 register_reboot_notifier(&gsmi_reboot_notifier);
903 register_die_notifier(&gsmi_die_notifier);
904 atomic_notifier_chain_register(&panic_notifier_list,
905 &gsmi_panic_notifier);
906
907 printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
908
909 return 0;
910
911out_remove_sysfs_files:
912 sysfs_remove_files(gsmi_kobj, gsmi_attrs);
913out_remove_bin_file:
914 sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
915out_err:
916 kobject_put(gsmi_kobj);
917 gsmi_buf_free(gsmi_dev.param_buf);
918 gsmi_buf_free(gsmi_dev.data_buf);
919 gsmi_buf_free(gsmi_dev.name_buf);
920 if (gsmi_dev.dma_pool)
921 dma_pool_destroy(gsmi_dev.dma_pool);
922 platform_device_unregister(gsmi_dev.pdev);
923 pr_info("gsmi: failed to load: %d\n", ret);
924 return ret;
925}
926
927static void __exit gsmi_exit(void)
928{
929 unregister_reboot_notifier(&gsmi_reboot_notifier);
930 unregister_die_notifier(&gsmi_die_notifier);
931 atomic_notifier_chain_unregister(&panic_notifier_list,
932 &gsmi_panic_notifier);
933 unregister_efivars(&efivars);
934
935 sysfs_remove_files(gsmi_kobj, gsmi_attrs);
936 sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
937 kobject_put(gsmi_kobj);
938 gsmi_buf_free(gsmi_dev.param_buf);
939 gsmi_buf_free(gsmi_dev.data_buf);
940 gsmi_buf_free(gsmi_dev.name_buf);
941 dma_pool_destroy(gsmi_dev.dma_pool);
942 platform_device_unregister(gsmi_dev.pdev);
943}
944
945module_init(gsmi_init);
946module_exit(gsmi_exit);
947
948MODULE_AUTHOR("Google, Inc.");
949MODULE_LICENSE("GPL");
950