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