5633018c34afa0261889f0626831420c9fe648e1
[firefly-linux-kernel-4.4.55.git] / drivers / firmware / efivars.c
1 /*
2  * EFI Variables - efivars.c
3  *
4  * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
5  * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
6  *
7  * This code takes all variables accessible from EFI runtime and
8  *  exports them via sysfs
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * Changelog:
25  *
26  *  17 May 2004 - Matt Domsch <Matt_Domsch@dell.com>
27  *   remove check for efi_enabled in exit
28  *   add MODULE_VERSION
29  *
30  *  26 Apr 2004 - Matt Domsch <Matt_Domsch@dell.com>
31  *   minor bug fixes
32  *
33  *  21 Apr 2004 - Matt Tolentino <matthew.e.tolentino@intel.com)
34  *   converted driver to export variable information via sysfs
35  *   and moved to drivers/firmware directory
36  *   bumped revision number to v0.07 to reflect conversion & move
37  *
38  *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
39  *   fix locking per Peter Chubb's findings
40  *
41  *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
42  *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
43  *
44  *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
45  *   use list_for_each_safe when deleting vars.
46  *   remove ifdef CONFIG_SMP around include <linux/smp.h>
47  *   v0.04 release to linux-ia64@linuxia64.org
48  *
49  *  20 April 2001 - Matt Domsch <Matt_Domsch@dell.com>
50  *   Moved vars from /proc/efi to /proc/efi/vars, and made
51  *   efi.c own the /proc/efi directory.
52  *   v0.03 release to linux-ia64@linuxia64.org
53  *
54  *  26 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
55  *   At the request of Stephane, moved ownership of /proc/efi
56  *   to efi.c, and now efivars lives under /proc/efi/vars.
57  *
58  *  12 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
59  *   Feedback received from Stephane Eranian incorporated.
60  *   efivar_write() checks copy_from_user() return value.
61  *   efivar_read/write() returns proper errno.
62  *   v0.02 release to linux-ia64@linuxia64.org
63  *
64  *  26 February 2001 - Matt Domsch <Matt_Domsch@dell.com>
65  *   v0.01 release to linux-ia64@linuxia64.org
66  */
67
68 #include <linux/capability.h>
69 #include <linux/types.h>
70 #include <linux/errno.h>
71 #include <linux/init.h>
72 #include <linux/mm.h>
73 #include <linux/module.h>
74 #include <linux/string.h>
75 #include <linux/smp.h>
76 #include <linux/efi.h>
77 #include <linux/sysfs.h>
78 #include <linux/kobject.h>
79 #include <linux/device.h>
80 #include <linux/slab.h>
81
82 #include <asm/uaccess.h>
83
84 #define EFIVARS_VERSION "0.08"
85 #define EFIVARS_DATE "2004-May-17"
86
87 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
88 MODULE_DESCRIPTION("sysfs interface to EFI Variables");
89 MODULE_LICENSE("GPL");
90 MODULE_VERSION(EFIVARS_VERSION);
91
92 struct efivars {
93         /*
94          * ->lock protects two things:
95          * 1) ->list - adds, removals, reads, writes
96          * 2) efi.[gs]et_variable() calls.
97          * It must not be held when creating sysfs entries or calling kmalloc.
98          * efi.get_next_variable() is only called from efivars_init(),
99          * which is protected by the BKL, so that path is safe.
100          */
101         spinlock_t lock;
102         struct list_head list;
103         struct kset *kset;
104         struct bin_attribute *new_var, *del_var;
105 };
106
107 /*
108  * The maximum size of VariableName + Data = 1024
109  * Therefore, it's reasonable to save that much
110  * space in each part of the structure,
111  * and we use a page for reading/writing.
112  */
113
114 struct efi_variable {
115         efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
116         efi_guid_t    VendorGuid;
117         unsigned long DataSize;
118         __u8          Data[1024];
119         efi_status_t  Status;
120         __u32         Attributes;
121 } __attribute__((packed));
122
123
124 struct efivar_entry {
125         struct efivars *efivars;
126         struct efi_variable var;
127         struct list_head list;
128         struct kobject kobj;
129 };
130
131 struct efivar_attribute {
132         struct attribute attr;
133         ssize_t (*show) (struct efivar_entry *entry, char *buf);
134         ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
135 };
136
137
138 #define EFIVAR_ATTR(_name, _mode, _show, _store) \
139 struct efivar_attribute efivar_attr_##_name = { \
140         .attr = {.name = __stringify(_name), .mode = _mode}, \
141         .show = _show, \
142         .store = _store, \
143 };
144
145 #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
146 #define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
147
148 /*
149  * Prototype for sysfs creation function
150  */
151 static int
152 efivar_create_sysfs_entry(struct efivars *efivars,
153                           unsigned long variable_name_size,
154                           efi_char16_t *variable_name,
155                           efi_guid_t *vendor_guid);
156
157 /* Return the number of unicode characters in data */
158 static unsigned long
159 utf8_strlen(efi_char16_t *data, unsigned long maxlength)
160 {
161         unsigned long length = 0;
162
163         while (*data++ != 0 && length < maxlength)
164                 length++;
165         return length;
166 }
167
168 /*
169  * Return the number of bytes is the length of this string
170  * Note: this is NOT the same as the number of unicode characters
171  */
172 static inline unsigned long
173 utf8_strsize(efi_char16_t *data, unsigned long maxlength)
174 {
175         return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
176 }
177
178 static efi_status_t
179 get_var_data(struct efivars *efivars, struct efi_variable *var)
180 {
181         efi_status_t status;
182
183         spin_lock(&efivars->lock);
184         var->DataSize = 1024;
185         status = efi.get_variable(var->VariableName,
186                                 &var->VendorGuid,
187                                 &var->Attributes,
188                                 &var->DataSize,
189                                 var->Data);
190         spin_unlock(&efivars->lock);
191         if (status != EFI_SUCCESS) {
192                 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
193                         status);
194         }
195         return status;
196 }
197
198 static ssize_t
199 efivar_guid_read(struct efivar_entry *entry, char *buf)
200 {
201         struct efi_variable *var = &entry->var;
202         char *str = buf;
203
204         if (!entry || !buf)
205                 return 0;
206
207         efi_guid_unparse(&var->VendorGuid, str);
208         str += strlen(str);
209         str += sprintf(str, "\n");
210
211         return str - buf;
212 }
213
214 static ssize_t
215 efivar_attr_read(struct efivar_entry *entry, char *buf)
216 {
217         struct efi_variable *var = &entry->var;
218         char *str = buf;
219         efi_status_t status;
220
221         if (!entry || !buf)
222                 return -EINVAL;
223
224         status = get_var_data(entry->efivars, var);
225         if (status != EFI_SUCCESS)
226                 return -EIO;
227
228         if (var->Attributes & 0x1)
229                 str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
230         if (var->Attributes & 0x2)
231                 str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
232         if (var->Attributes & 0x4)
233                 str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
234         return str - buf;
235 }
236
237 static ssize_t
238 efivar_size_read(struct efivar_entry *entry, char *buf)
239 {
240         struct efi_variable *var = &entry->var;
241         char *str = buf;
242         efi_status_t status;
243
244         if (!entry || !buf)
245                 return -EINVAL;
246
247         status = get_var_data(entry->efivars, var);
248         if (status != EFI_SUCCESS)
249                 return -EIO;
250
251         str += sprintf(str, "0x%lx\n", var->DataSize);
252         return str - buf;
253 }
254
255 static ssize_t
256 efivar_data_read(struct efivar_entry *entry, char *buf)
257 {
258         struct efi_variable *var = &entry->var;
259         efi_status_t status;
260
261         if (!entry || !buf)
262                 return -EINVAL;
263
264         status = get_var_data(entry->efivars, var);
265         if (status != EFI_SUCCESS)
266                 return -EIO;
267
268         memcpy(buf, var->Data, var->DataSize);
269         return var->DataSize;
270 }
271 /*
272  * We allow each variable to be edited via rewriting the
273  * entire efi variable structure.
274  */
275 static ssize_t
276 efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
277 {
278         struct efi_variable *new_var, *var = &entry->var;
279         struct efivars *efivars = entry->efivars;
280         efi_status_t status = EFI_NOT_FOUND;
281
282         if (count != sizeof(struct efi_variable))
283                 return -EINVAL;
284
285         new_var = (struct efi_variable *)buf;
286         /*
287          * If only updating the variable data, then the name
288          * and guid should remain the same
289          */
290         if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
291                 efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
292                 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
293                 return -EINVAL;
294         }
295
296         if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
297                 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
298                 return -EINVAL;
299         }
300
301         spin_lock(&efivars->lock);
302         status = efi.set_variable(new_var->VariableName,
303                                         &new_var->VendorGuid,
304                                         new_var->Attributes,
305                                         new_var->DataSize,
306                                         new_var->Data);
307
308         spin_unlock(&efivars->lock);
309
310         if (status != EFI_SUCCESS) {
311                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
312                         status);
313                 return -EIO;
314         }
315
316         memcpy(&entry->var, new_var, count);
317         return count;
318 }
319
320 static ssize_t
321 efivar_show_raw(struct efivar_entry *entry, char *buf)
322 {
323         struct efi_variable *var = &entry->var;
324         efi_status_t status;
325
326         if (!entry || !buf)
327                 return 0;
328
329         status = get_var_data(entry->efivars, var);
330         if (status != EFI_SUCCESS)
331                 return -EIO;
332
333         memcpy(buf, var, sizeof(*var));
334         return sizeof(*var);
335 }
336
337 /*
338  * Generic read/write functions that call the specific functions of
339  * the atttributes...
340  */
341 static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
342                                 char *buf)
343 {
344         struct efivar_entry *var = to_efivar_entry(kobj);
345         struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
346         ssize_t ret = -EIO;
347
348         if (!capable(CAP_SYS_ADMIN))
349                 return -EACCES;
350
351         if (efivar_attr->show) {
352                 ret = efivar_attr->show(var, buf);
353         }
354         return ret;
355 }
356
357 static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
358                                 const char *buf, size_t count)
359 {
360         struct efivar_entry *var = to_efivar_entry(kobj);
361         struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
362         ssize_t ret = -EIO;
363
364         if (!capable(CAP_SYS_ADMIN))
365                 return -EACCES;
366
367         if (efivar_attr->store)
368                 ret = efivar_attr->store(var, buf, count);
369
370         return ret;
371 }
372
373 static const struct sysfs_ops efivar_attr_ops = {
374         .show = efivar_attr_show,
375         .store = efivar_attr_store,
376 };
377
378 static void efivar_release(struct kobject *kobj)
379 {
380         struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
381         kfree(var);
382 }
383
384 static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
385 static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
386 static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
387 static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
388 static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
389
390 static struct attribute *def_attrs[] = {
391         &efivar_attr_guid.attr,
392         &efivar_attr_size.attr,
393         &efivar_attr_attributes.attr,
394         &efivar_attr_data.attr,
395         &efivar_attr_raw_var.attr,
396         NULL,
397 };
398
399 static struct kobj_type efivar_ktype = {
400         .release = efivar_release,
401         .sysfs_ops = &efivar_attr_ops,
402         .default_attrs = def_attrs,
403 };
404
405 static inline void
406 efivar_unregister(struct efivar_entry *var)
407 {
408         kobject_put(&var->kobj);
409 }
410
411
412 static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
413                              struct bin_attribute *bin_attr,
414                              char *buf, loff_t pos, size_t count)
415 {
416         struct efi_variable *new_var = (struct efi_variable *)buf;
417         struct efivars *efivars = bin_attr->private;
418         struct efivar_entry *search_efivar, *n;
419         unsigned long strsize1, strsize2;
420         efi_status_t status = EFI_NOT_FOUND;
421         int found = 0;
422
423         if (!capable(CAP_SYS_ADMIN))
424                 return -EACCES;
425
426         spin_lock(&efivars->lock);
427
428         /*
429          * Does this variable already exist?
430          */
431         list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
432                 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
433                 strsize2 = utf8_strsize(new_var->VariableName, 1024);
434                 if (strsize1 == strsize2 &&
435                         !memcmp(&(search_efivar->var.VariableName),
436                                 new_var->VariableName, strsize1) &&
437                         !efi_guidcmp(search_efivar->var.VendorGuid,
438                                 new_var->VendorGuid)) {
439                         found = 1;
440                         break;
441                 }
442         }
443         if (found) {
444                 spin_unlock(&efivars->lock);
445                 return -EINVAL;
446         }
447
448         /* now *really* create the variable via EFI */
449         status = efi.set_variable(new_var->VariableName,
450                         &new_var->VendorGuid,
451                         new_var->Attributes,
452                         new_var->DataSize,
453                         new_var->Data);
454
455         if (status != EFI_SUCCESS) {
456                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
457                         status);
458                 spin_unlock(&efivars->lock);
459                 return -EIO;
460         }
461         spin_unlock(&efivars->lock);
462
463         /* Create the entry in sysfs.  Locking is not required here */
464         status = efivar_create_sysfs_entry(efivars,
465                                            utf8_strsize(new_var->VariableName,
466                                                         1024),
467                                            new_var->VariableName,
468                                            &new_var->VendorGuid);
469         if (status) {
470                 printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");
471         }
472         return count;
473 }
474
475 static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
476                              struct bin_attribute *bin_attr,
477                              char *buf, loff_t pos, size_t count)
478 {
479         struct efi_variable *del_var = (struct efi_variable *)buf;
480         struct efivars *efivars = bin_attr->private;
481         struct efivar_entry *search_efivar, *n;
482         unsigned long strsize1, strsize2;
483         efi_status_t status = EFI_NOT_FOUND;
484         int found = 0;
485
486         if (!capable(CAP_SYS_ADMIN))
487                 return -EACCES;
488
489         spin_lock(&efivars->lock);
490
491         /*
492          * Does this variable already exist?
493          */
494         list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
495                 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
496                 strsize2 = utf8_strsize(del_var->VariableName, 1024);
497                 if (strsize1 == strsize2 &&
498                         !memcmp(&(search_efivar->var.VariableName),
499                                 del_var->VariableName, strsize1) &&
500                         !efi_guidcmp(search_efivar->var.VendorGuid,
501                                 del_var->VendorGuid)) {
502                         found = 1;
503                         break;
504                 }
505         }
506         if (!found) {
507                 spin_unlock(&efivars->lock);
508                 return -EINVAL;
509         }
510         /* force the Attributes/DataSize to 0 to ensure deletion */
511         del_var->Attributes = 0;
512         del_var->DataSize = 0;
513
514         status = efi.set_variable(del_var->VariableName,
515                         &del_var->VendorGuid,
516                         del_var->Attributes,
517                         del_var->DataSize,
518                         del_var->Data);
519
520         if (status != EFI_SUCCESS) {
521                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
522                         status);
523                 spin_unlock(&efivars->lock);
524                 return -EIO;
525         }
526         list_del(&search_efivar->list);
527         /* We need to release this lock before unregistering. */
528         spin_unlock(&efivars->lock);
529         efivar_unregister(search_efivar);
530
531         /* It's dead Jim.... */
532         return count;
533 }
534
535 /*
536  * Let's not leave out systab information that snuck into
537  * the efivars driver
538  */
539 static ssize_t systab_show(struct kobject *kobj,
540                            struct kobj_attribute *attr, char *buf)
541 {
542         char *str = buf;
543
544         if (!kobj || !buf)
545                 return -EINVAL;
546
547         if (efi.mps != EFI_INVALID_TABLE_ADDR)
548                 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
549         if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
550                 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
551         if (efi.acpi != EFI_INVALID_TABLE_ADDR)
552                 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
553         if (efi.smbios != EFI_INVALID_TABLE_ADDR)
554                 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
555         if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
556                 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
557         if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
558                 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
559         if (efi.uga != EFI_INVALID_TABLE_ADDR)
560                 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
561
562         return str - buf;
563 }
564
565 static struct kobj_attribute efi_attr_systab =
566                         __ATTR(systab, 0400, systab_show, NULL);
567
568 static struct attribute *efi_subsys_attrs[] = {
569         &efi_attr_systab.attr,
570         NULL,   /* maybe more in the future? */
571 };
572
573 static struct attribute_group efi_subsys_attr_group = {
574         .attrs = efi_subsys_attrs,
575 };
576
577 static struct kobject *efi_kobj;
578
579 /*
580  * efivar_create_sysfs_entry()
581  * Requires:
582  *    variable_name_size = number of bytes required to hold
583  *                         variable_name (not counting the NULL
584  *                         character at the end.
585  *    efivars->lock is not held on entry or exit.
586  * Returns 1 on failure, 0 on success
587  */
588 static int
589 efivar_create_sysfs_entry(struct efivars *efivars,
590                           unsigned long variable_name_size,
591                           efi_char16_t *variable_name,
592                           efi_guid_t *vendor_guid)
593 {
594         int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
595         char *short_name;
596         struct efivar_entry *new_efivar;
597
598         short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
599         new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
600
601         if (!short_name || !new_efivar)  {
602                 kfree(short_name);
603                 kfree(new_efivar);
604                 return 1;
605         }
606
607         new_efivar->efivars = efivars;
608         memcpy(new_efivar->var.VariableName, variable_name,
609                 variable_name_size);
610         memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
611
612         /* Convert Unicode to normal chars (assume top bits are 0),
613            ala UTF-8 */
614         for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
615                 short_name[i] = variable_name[i] & 0xFF;
616         }
617         /* This is ugly, but necessary to separate one vendor's
618            private variables from another's.         */
619
620         *(short_name + strlen(short_name)) = '-';
621         efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
622
623         new_efivar->kobj.kset = efivars->kset;
624         i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
625                                  "%s", short_name);
626         if (i) {
627                 kfree(short_name);
628                 kfree(new_efivar);
629                 return 1;
630         }
631
632         kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
633         kfree(short_name);
634         short_name = NULL;
635
636         spin_lock(&efivars->lock);
637         list_add(&new_efivar->list, &efivars->list);
638         spin_unlock(&efivars->lock);
639
640         return 0;
641 }
642
643 static int
644 create_efivars_bin_attributes(struct efivars *efivars)
645 {
646         struct bin_attribute *attr;
647         int error;
648
649         /* new_var */
650         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
651         if (!attr)
652                 return -ENOMEM;
653
654         attr->attr.name = "new_var";
655         attr->attr.mode = 0200;
656         attr->write = efivar_create;
657         attr->private = efivars;
658         efivars->new_var = attr;
659
660         /* del_var */
661         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
662         if (!attr) {
663                 error = -ENOMEM;
664                 goto out_free;
665         }
666         attr->attr.name = "del_var";
667         attr->attr.mode = 0200;
668         attr->write = efivar_delete;
669         attr->private = efivars;
670         efivars->del_var = attr;
671
672         sysfs_bin_attr_init(efivars->new_var);
673         sysfs_bin_attr_init(efivars->del_var);
674
675         /* Register */
676         error = sysfs_create_bin_file(&efivars->kset->kobj,
677                                       efivars->new_var);
678         if (error) {
679                 printk(KERN_ERR "efivars: unable to create new_var sysfs file"
680                         " due to error %d\n", error);
681                 goto out_free;
682         }
683         error = sysfs_create_bin_file(&efivars->kset->kobj,
684                                       efivars->del_var);
685         if (error) {
686                 printk(KERN_ERR "efivars: unable to create del_var sysfs file"
687                         " due to error %d\n", error);
688                 sysfs_remove_bin_file(&efivars->kset->kobj,
689                                       efivars->new_var);
690                 goto out_free;
691         }
692
693         return 0;
694 out_free:
695         kfree(efivars->new_var);
696         efivars->new_var = NULL;
697         kfree(efivars->new_var);
698         efivars->new_var = NULL;
699         return error;
700 }
701
702 static struct efivars __efivars;
703
704 /*
705  * For now we register the efi subsystem with the firmware subsystem
706  * and the vars subsystem with the efi subsystem.  In the future, it
707  * might make sense to split off the efi subsystem into its own
708  * driver, but for now only efivars will register with it, so just
709  * include it here.
710  */
711
712 static int __init
713 efivars_init(void)
714 {
715         efi_status_t status = EFI_NOT_FOUND;
716         efi_guid_t vendor_guid;
717         efi_char16_t *variable_name;
718         unsigned long variable_name_size = 1024;
719         struct efivars *efivars = &__efivars;
720         int error = 0;
721
722         if (!efi_enabled)
723                 return -ENODEV;
724
725         variable_name = kzalloc(variable_name_size, GFP_KERNEL);
726         if (!variable_name) {
727                 printk(KERN_ERR "efivars: Memory allocation failed.\n");
728                 return -ENOMEM;
729         }
730
731         printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
732                EFIVARS_DATE);
733
734         /* For now we'll register the efi directory at /sys/firmware/efi */
735         efi_kobj = kobject_create_and_add("efi", firmware_kobj);
736         if (!efi_kobj) {
737                 printk(KERN_ERR "efivars: Firmware registration failed.\n");
738                 error = -ENOMEM;
739                 goto out_free;
740         }
741
742         spin_lock_init(&efivars->lock);
743         INIT_LIST_HEAD(&efivars->list);
744
745         efivars->kset = kset_create_and_add("vars", NULL, efi_kobj);
746         if (!efivars->kset) {
747                 printk(KERN_ERR "efivars: Subsystem registration failed.\n");
748                 error = -ENOMEM;
749                 goto out_firmware_unregister;
750         }
751
752         /*
753          * Per EFI spec, the maximum storage allocated for both
754          * the variable name and variable data is 1024 bytes.
755          */
756
757         do {
758                 variable_name_size = 1024;
759
760                 status = efi.get_next_variable(&variable_name_size,
761                                                 variable_name,
762                                                 &vendor_guid);
763                 switch (status) {
764                 case EFI_SUCCESS:
765                         efivar_create_sysfs_entry(efivars,
766                                                   variable_name_size,
767                                                   variable_name,
768                                                   &vendor_guid);
769                         break;
770                 case EFI_NOT_FOUND:
771                         break;
772                 default:
773                         printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
774                                 status);
775                         status = EFI_NOT_FOUND;
776                         break;
777                 }
778         } while (status != EFI_NOT_FOUND);
779
780         error = create_efivars_bin_attributes(efivars);
781
782         /* Don't forget the systab entry */
783         error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
784         if (error)
785                 printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error);
786         else
787                 goto out_free;
788
789         kset_unregister(efivars->kset);
790
791 out_firmware_unregister:
792         kobject_put(efi_kobj);
793
794 out_free:
795         kfree(variable_name);
796
797         return error;
798 }
799
800 static void __exit
801 efivars_exit(void)
802 {
803         struct efivars *efivars = &__efivars;
804         struct efivar_entry *entry, *n;
805
806         list_for_each_entry_safe(entry, n, &efivars->list, list) {
807                 spin_lock(&efivars->lock);
808                 list_del(&entry->list);
809                 spin_unlock(&efivars->lock);
810                 efivar_unregister(entry);
811         }
812         if (efivars->new_var)
813                 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
814         if (efivars->del_var)
815                 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
816         kfree(efivars->new_var);
817         kfree(efivars->del_var);
818         kset_unregister(efivars->kset);
819         kobject_put(efi_kobj);
820 }
821
822 module_init(efivars_init);
823 module_exit(efivars_exit);
824