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
31#define GSMI_SHUTDOWN_CLEAN 0
32
33#define GSMI_SHUTDOWN_NMIWDT 1
34#define GSMI_SHUTDOWN_PANIC 2
35#define GSMI_SHUTDOWN_OOPS 3
36#define GSMI_SHUTDOWN_DIE 4
37#define GSMI_SHUTDOWN_MCE 5
38#define GSMI_SHUTDOWN_SOFTWDT 6
39#define GSMI_SHUTDOWN_MBE 7
40#define GSMI_SHUTDOWN_TRIPLE 8
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
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
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
75#define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
76
77
78struct gsmi_buf {
79 u8 *start;
80 size_t length;
81 dma_addr_t handle;
82 u32 address;
83};
84
85struct gsmi_device {
86 struct platform_device *pdev;
87 struct gsmi_buf *name_buf;
88 struct gsmi_buf *data_buf;
89 struct gsmi_buf *param_buf;
90 spinlock_t lock;
91 u16 smi_cmd;
92 int handshake_type;
93 struct dma_pool *dma_pool;
94} gsmi_dev;
95
96
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
118struct gsmi_log_entry_type_1 {
119 u16 type;
120 u32 instance;
121} __packed;
122
123
124
125
126
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
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
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
172
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
182
183
184
185
186
187
188 if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_CF) {
189
190
191
192
193
194
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
209
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
224
225
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
238 switch (result) {
239 case GSMI_SUCCESS:
240 break;
241 case GSMI_VAR_NOT_FOUND:
242
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
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
322 memcpy(¶m.guid, vendor, sizeof(param.guid));
323
324
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
329 memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
330
331
332 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
333 memcpy(gsmi_dev.param_buf->start, ¶m, 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
341 ret = EFI_NOT_FOUND;
342 } else {
343
344 memcpy(¶m, gsmi_dev.param_buf->start, sizeof(param));
345
346
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
351 memcpy(data, gsmi_dev.data_buf->start, *data_size);
352
353
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
377 if (*name_size != GSMI_BUF_SIZE)
378 return EFI_BAD_BUFFER_SIZE;
379
380
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
387 memcpy(¶m.guid, vendor, sizeof(param.guid));
388
389
390 memcpy(gsmi_dev.name_buf->start, name, *name_size);
391
392
393 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
394 memcpy(gsmi_dev.param_buf->start, ¶m, 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
402 ret = EFI_NOT_FOUND;
403 } else {
404
405 memcpy(¶m, gsmi_dev.param_buf->start, sizeof(param));
406
407
408 memcpy(name, gsmi_dev.name_buf->start, GSMI_BUF_SIZE);
409 *name_size = utf16_strlen(name, GSMI_BUF_SIZE / 2) * 2;
410
411
412 memcpy(vendor, ¶m.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
446 memcpy(¶m.guid, vendor, sizeof(param.guid));
447
448
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
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
457 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
458 memcpy(gsmi_dev.param_buf->start, ¶m, 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
488 if (count < sizeof(u32))
489 return -EINVAL;
490 param.type = *(u32 *)buf;
491 count -= sizeof(u32);
492 buf += sizeof(u32);
493
494
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
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
506 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
507 memcpy(gsmi_dev.param_buf->start, ¶m, 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
542
543
544 if (val > 100)
545 return -EINVAL;
546
547
548 param.percentage = val;
549 param.data_type = 0;
550
551 spin_lock_irqsave(&gsmi_dev.lock, flags);
552
553
554 memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
555 memcpy(gsmi_dev.param_buf->start, ¶m, 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
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
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
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
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, ¶m, 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
683
684
685
686
687
688
689
690static u64 __init local_hash_64(u64 val, unsigned bits)
691{
692 u64 hash = val;
693
694
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
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
740
741
742
743
744
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
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
763 if (acpi_gbl_FADT.smi_command == 0) {
764 pr_info("gsmi: missing smi_command\n");
765 return -ENODEV;
766 }
767
768
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
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
794 spin_lock_init(&gsmi_dev.lock);
795
796
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
808
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
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 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
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
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_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");
941