Merge remote-tracking branch 'origin/develop-3.0' into develop-3.0-jb
[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 /*
93  * The maximum size of VariableName + Data = 1024
94  * Therefore, it's reasonable to save that much
95  * space in each part of the structure,
96  * and we use a page for reading/writing.
97  */
98
99 struct efi_variable {
100         efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
101         efi_guid_t    VendorGuid;
102         unsigned long DataSize;
103         __u8          Data[1024];
104         efi_status_t  Status;
105         __u32         Attributes;
106 } __attribute__((packed));
107
108
109 struct efivar_entry {
110         struct efivars *efivars;
111         struct efi_variable var;
112         struct list_head list;
113         struct kobject kobj;
114 };
115
116 struct efivar_attribute {
117         struct attribute attr;
118         ssize_t (*show) (struct efivar_entry *entry, char *buf);
119         ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
120 };
121
122
123 #define EFIVAR_ATTR(_name, _mode, _show, _store) \
124 struct efivar_attribute efivar_attr_##_name = { \
125         .attr = {.name = __stringify(_name), .mode = _mode}, \
126         .show = _show, \
127         .store = _store, \
128 };
129
130 #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
131 #define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
132
133 /*
134  * Prototype for sysfs creation function
135  */
136 static int
137 efivar_create_sysfs_entry(struct efivars *efivars,
138                           unsigned long variable_name_size,
139                           efi_char16_t *variable_name,
140                           efi_guid_t *vendor_guid);
141
142 /* Return the number of unicode characters in data */
143 static unsigned long
144 utf16_strnlen(efi_char16_t *s, size_t maxlength)
145 {
146         unsigned long length = 0;
147
148         while (*s++ != 0 && length < maxlength)
149                 length++;
150         return length;
151 }
152
153 static inline unsigned long
154 utf16_strlen(efi_char16_t *s)
155 {
156         return utf16_strnlen(s, ~0UL);
157 }
158
159 /*
160  * Return the number of bytes is the length of this string
161  * Note: this is NOT the same as the number of unicode characters
162  */
163 static inline unsigned long
164 utf16_strsize(efi_char16_t *data, unsigned long maxlength)
165 {
166         return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
167 }
168
169 static bool
170 validate_device_path(struct efi_variable *var, int match, u8 *buffer,
171                      unsigned long len)
172 {
173         struct efi_generic_dev_path *node;
174         int offset = 0;
175
176         node = (struct efi_generic_dev_path *)buffer;
177
178         if (len < sizeof(*node))
179                 return false;
180
181         while (offset <= len - sizeof(*node) &&
182                node->length >= sizeof(*node) &&
183                 node->length <= len - offset) {
184                 offset += node->length;
185
186                 if ((node->type == EFI_DEV_END_PATH ||
187                      node->type == EFI_DEV_END_PATH2) &&
188                     node->sub_type == EFI_DEV_END_ENTIRE)
189                         return true;
190
191                 node = (struct efi_generic_dev_path *)(buffer + offset);
192         }
193
194         /*
195          * If we're here then either node->length pointed past the end
196          * of the buffer or we reached the end of the buffer without
197          * finding a device path end node.
198          */
199         return false;
200 }
201
202 static bool
203 validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
204                     unsigned long len)
205 {
206         /* An array of 16-bit integers */
207         if ((len % 2) != 0)
208                 return false;
209
210         return true;
211 }
212
213 static bool
214 validate_load_option(struct efi_variable *var, int match, u8 *buffer,
215                      unsigned long len)
216 {
217         u16 filepathlength;
218         int i, desclength = 0, namelen;
219
220         namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
221
222         /* Either "Boot" or "Driver" followed by four digits of hex */
223         for (i = match; i < match+4; i++) {
224                 if (var->VariableName[i] > 127 ||
225                     hex_to_bin(var->VariableName[i] & 0xff) < 0)
226                         return true;
227         }
228
229         /* Reject it if there's 4 digits of hex and then further content */
230         if (namelen > match + 4)
231                 return false;
232
233         /* A valid entry must be at least 8 bytes */
234         if (len < 8)
235                 return false;
236
237         filepathlength = buffer[4] | buffer[5] << 8;
238
239         /*
240          * There's no stored length for the description, so it has to be
241          * found by hand
242          */
243         desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
244
245         /* Each boot entry must have a descriptor */
246         if (!desclength)
247                 return false;
248
249         /*
250          * If the sum of the length of the description, the claimed filepath
251          * length and the original header are greater than the length of the
252          * variable, it's malformed
253          */
254         if ((desclength + filepathlength + 6) > len)
255                 return false;
256
257         /*
258          * And, finally, check the filepath
259          */
260         return validate_device_path(var, match, buffer + desclength + 6,
261                                     filepathlength);
262 }
263
264 static bool
265 validate_uint16(struct efi_variable *var, int match, u8 *buffer,
266                 unsigned long len)
267 {
268         /* A single 16-bit integer */
269         if (len != 2)
270                 return false;
271
272         return true;
273 }
274
275 static bool
276 validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
277                       unsigned long len)
278 {
279         int i;
280
281         for (i = 0; i < len; i++) {
282                 if (buffer[i] > 127)
283                         return false;
284
285                 if (buffer[i] == 0)
286                         return true;
287         }
288
289         return false;
290 }
291
292 struct variable_validate {
293         char *name;
294         bool (*validate)(struct efi_variable *var, int match, u8 *data,
295                          unsigned long len);
296 };
297
298 static const struct variable_validate variable_validate[] = {
299         { "BootNext", validate_uint16 },
300         { "BootOrder", validate_boot_order },
301         { "DriverOrder", validate_boot_order },
302         { "Boot*", validate_load_option },
303         { "Driver*", validate_load_option },
304         { "ConIn", validate_device_path },
305         { "ConInDev", validate_device_path },
306         { "ConOut", validate_device_path },
307         { "ConOutDev", validate_device_path },
308         { "ErrOut", validate_device_path },
309         { "ErrOutDev", validate_device_path },
310         { "Timeout", validate_uint16 },
311         { "Lang", validate_ascii_string },
312         { "PlatformLang", validate_ascii_string },
313         { "", NULL },
314 };
315
316 static bool
317 validate_var(struct efi_variable *var, u8 *data, unsigned long len)
318 {
319         int i;
320         u16 *unicode_name = var->VariableName;
321
322         for (i = 0; variable_validate[i].validate != NULL; i++) {
323                 const char *name = variable_validate[i].name;
324                 int match;
325
326                 for (match = 0; ; match++) {
327                         char c = name[match];
328                         u16 u = unicode_name[match];
329
330                         /* All special variables are plain ascii */
331                         if (u > 127)
332                                 return true;
333
334                         /* Wildcard in the matching name means we've matched */
335                         if (c == '*')
336                                 return variable_validate[i].validate(var,
337                                                              match, data, len);
338
339                         /* Case sensitive match */
340                         if (c != u)
341                                 break;
342
343                         /* Reached the end of the string while matching */
344                         if (!c)
345                                 return variable_validate[i].validate(var,
346                                                              match, data, len);
347                 }
348         }
349
350         return true;
351 }
352
353 static efi_status_t
354 get_var_data(struct efivars *efivars, struct efi_variable *var)
355 {
356         efi_status_t status;
357
358         spin_lock(&efivars->lock);
359         var->DataSize = 1024;
360         status = efivars->ops->get_variable(var->VariableName,
361                                             &var->VendorGuid,
362                                             &var->Attributes,
363                                             &var->DataSize,
364                                             var->Data);
365         spin_unlock(&efivars->lock);
366         if (status != EFI_SUCCESS) {
367                 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
368                         status);
369         }
370         return status;
371 }
372
373 static ssize_t
374 efivar_guid_read(struct efivar_entry *entry, char *buf)
375 {
376         struct efi_variable *var = &entry->var;
377         char *str = buf;
378
379         if (!entry || !buf)
380                 return 0;
381
382         efi_guid_unparse(&var->VendorGuid, str);
383         str += strlen(str);
384         str += sprintf(str, "\n");
385
386         return str - buf;
387 }
388
389 static ssize_t
390 efivar_attr_read(struct efivar_entry *entry, char *buf)
391 {
392         struct efi_variable *var = &entry->var;
393         char *str = buf;
394         efi_status_t status;
395
396         if (!entry || !buf)
397                 return -EINVAL;
398
399         status = get_var_data(entry->efivars, var);
400         if (status != EFI_SUCCESS)
401                 return -EIO;
402
403         if (var->Attributes & 0x1)
404                 str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
405         if (var->Attributes & 0x2)
406                 str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
407         if (var->Attributes & 0x4)
408                 str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
409         return str - buf;
410 }
411
412 static ssize_t
413 efivar_size_read(struct efivar_entry *entry, char *buf)
414 {
415         struct efi_variable *var = &entry->var;
416         char *str = buf;
417         efi_status_t status;
418
419         if (!entry || !buf)
420                 return -EINVAL;
421
422         status = get_var_data(entry->efivars, var);
423         if (status != EFI_SUCCESS)
424                 return -EIO;
425
426         str += sprintf(str, "0x%lx\n", var->DataSize);
427         return str - buf;
428 }
429
430 static ssize_t
431 efivar_data_read(struct efivar_entry *entry, char *buf)
432 {
433         struct efi_variable *var = &entry->var;
434         efi_status_t status;
435
436         if (!entry || !buf)
437                 return -EINVAL;
438
439         status = get_var_data(entry->efivars, var);
440         if (status != EFI_SUCCESS)
441                 return -EIO;
442
443         memcpy(buf, var->Data, var->DataSize);
444         return var->DataSize;
445 }
446 /*
447  * We allow each variable to be edited via rewriting the
448  * entire efi variable structure.
449  */
450 static ssize_t
451 efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
452 {
453         struct efi_variable *new_var, *var = &entry->var;
454         struct efivars *efivars = entry->efivars;
455         efi_status_t status = EFI_NOT_FOUND;
456
457         if (count != sizeof(struct efi_variable))
458                 return -EINVAL;
459
460         new_var = (struct efi_variable *)buf;
461         /*
462          * If only updating the variable data, then the name
463          * and guid should remain the same
464          */
465         if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
466                 efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
467                 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
468                 return -EINVAL;
469         }
470
471         if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
472                 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
473                 return -EINVAL;
474         }
475
476         if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
477             validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
478                 printk(KERN_ERR "efivars: Malformed variable content\n");
479                 return -EINVAL;
480         }
481
482         spin_lock(&efivars->lock);
483         status = efivars->ops->set_variable(new_var->VariableName,
484                                             &new_var->VendorGuid,
485                                             new_var->Attributes,
486                                             new_var->DataSize,
487                                             new_var->Data);
488
489         spin_unlock(&efivars->lock);
490
491         if (status != EFI_SUCCESS) {
492                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
493                         status);
494                 return -EIO;
495         }
496
497         memcpy(&entry->var, new_var, count);
498         return count;
499 }
500
501 static ssize_t
502 efivar_show_raw(struct efivar_entry *entry, char *buf)
503 {
504         struct efi_variable *var = &entry->var;
505         efi_status_t status;
506
507         if (!entry || !buf)
508                 return 0;
509
510         status = get_var_data(entry->efivars, var);
511         if (status != EFI_SUCCESS)
512                 return -EIO;
513
514         memcpy(buf, var, sizeof(*var));
515         return sizeof(*var);
516 }
517
518 /*
519  * Generic read/write functions that call the specific functions of
520  * the attributes...
521  */
522 static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
523                                 char *buf)
524 {
525         struct efivar_entry *var = to_efivar_entry(kobj);
526         struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
527         ssize_t ret = -EIO;
528
529         if (!capable(CAP_SYS_ADMIN))
530                 return -EACCES;
531
532         if (efivar_attr->show) {
533                 ret = efivar_attr->show(var, buf);
534         }
535         return ret;
536 }
537
538 static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
539                                 const char *buf, size_t count)
540 {
541         struct efivar_entry *var = to_efivar_entry(kobj);
542         struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
543         ssize_t ret = -EIO;
544
545         if (!capable(CAP_SYS_ADMIN))
546                 return -EACCES;
547
548         if (efivar_attr->store)
549                 ret = efivar_attr->store(var, buf, count);
550
551         return ret;
552 }
553
554 static const struct sysfs_ops efivar_attr_ops = {
555         .show = efivar_attr_show,
556         .store = efivar_attr_store,
557 };
558
559 static void efivar_release(struct kobject *kobj)
560 {
561         struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
562         kfree(var);
563 }
564
565 static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
566 static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
567 static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
568 static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
569 static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
570
571 static struct attribute *def_attrs[] = {
572         &efivar_attr_guid.attr,
573         &efivar_attr_size.attr,
574         &efivar_attr_attributes.attr,
575         &efivar_attr_data.attr,
576         &efivar_attr_raw_var.attr,
577         NULL,
578 };
579
580 static struct kobj_type efivar_ktype = {
581         .release = efivar_release,
582         .sysfs_ops = &efivar_attr_ops,
583         .default_attrs = def_attrs,
584 };
585
586 static inline void
587 efivar_unregister(struct efivar_entry *var)
588 {
589         kobject_put(&var->kobj);
590 }
591
592
593 static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
594                              struct bin_attribute *bin_attr,
595                              char *buf, loff_t pos, size_t count)
596 {
597         struct efi_variable *new_var = (struct efi_variable *)buf;
598         struct efivars *efivars = bin_attr->private;
599         struct efivar_entry *search_efivar, *n;
600         unsigned long strsize1, strsize2;
601         efi_status_t status = EFI_NOT_FOUND;
602         int found = 0;
603
604         if (!capable(CAP_SYS_ADMIN))
605                 return -EACCES;
606
607         if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
608             validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
609                 printk(KERN_ERR "efivars: Malformed variable content\n");
610                 return -EINVAL;
611         }
612
613         spin_lock(&efivars->lock);
614
615         /*
616          * Does this variable already exist?
617          */
618         list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
619                 strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
620                 strsize2 = utf16_strsize(new_var->VariableName, 1024);
621                 if (strsize1 == strsize2 &&
622                         !memcmp(&(search_efivar->var.VariableName),
623                                 new_var->VariableName, strsize1) &&
624                         !efi_guidcmp(search_efivar->var.VendorGuid,
625                                 new_var->VendorGuid)) {
626                         found = 1;
627                         break;
628                 }
629         }
630         if (found) {
631                 spin_unlock(&efivars->lock);
632                 return -EINVAL;
633         }
634
635         /* now *really* create the variable via EFI */
636         status = efivars->ops->set_variable(new_var->VariableName,
637                                             &new_var->VendorGuid,
638                                             new_var->Attributes,
639                                             new_var->DataSize,
640                                             new_var->Data);
641
642         if (status != EFI_SUCCESS) {
643                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
644                         status);
645                 spin_unlock(&efivars->lock);
646                 return -EIO;
647         }
648         spin_unlock(&efivars->lock);
649
650         /* Create the entry in sysfs.  Locking is not required here */
651         status = efivar_create_sysfs_entry(efivars,
652                                            utf16_strsize(new_var->VariableName,
653                                                          1024),
654                                            new_var->VariableName,
655                                            &new_var->VendorGuid);
656         if (status) {
657                 printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");
658         }
659         return count;
660 }
661
662 static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
663                              struct bin_attribute *bin_attr,
664                              char *buf, loff_t pos, size_t count)
665 {
666         struct efi_variable *del_var = (struct efi_variable *)buf;
667         struct efivars *efivars = bin_attr->private;
668         struct efivar_entry *search_efivar, *n;
669         unsigned long strsize1, strsize2;
670         efi_status_t status = EFI_NOT_FOUND;
671         int found = 0;
672
673         if (!capable(CAP_SYS_ADMIN))
674                 return -EACCES;
675
676         spin_lock(&efivars->lock);
677
678         /*
679          * Does this variable already exist?
680          */
681         list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
682                 strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
683                 strsize2 = utf16_strsize(del_var->VariableName, 1024);
684                 if (strsize1 == strsize2 &&
685                         !memcmp(&(search_efivar->var.VariableName),
686                                 del_var->VariableName, strsize1) &&
687                         !efi_guidcmp(search_efivar->var.VendorGuid,
688                                 del_var->VendorGuid)) {
689                         found = 1;
690                         break;
691                 }
692         }
693         if (!found) {
694                 spin_unlock(&efivars->lock);
695                 return -EINVAL;
696         }
697         /* force the Attributes/DataSize to 0 to ensure deletion */
698         del_var->Attributes = 0;
699         del_var->DataSize = 0;
700
701         status = efivars->ops->set_variable(del_var->VariableName,
702                                             &del_var->VendorGuid,
703                                             del_var->Attributes,
704                                             del_var->DataSize,
705                                             del_var->Data);
706
707         if (status != EFI_SUCCESS) {
708                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
709                         status);
710                 spin_unlock(&efivars->lock);
711                 return -EIO;
712         }
713         list_del(&search_efivar->list);
714         /* We need to release this lock before unregistering. */
715         spin_unlock(&efivars->lock);
716         efivar_unregister(search_efivar);
717
718         /* It's dead Jim.... */
719         return count;
720 }
721
722 /*
723  * Let's not leave out systab information that snuck into
724  * the efivars driver
725  */
726 static ssize_t systab_show(struct kobject *kobj,
727                            struct kobj_attribute *attr, char *buf)
728 {
729         char *str = buf;
730
731         if (!kobj || !buf)
732                 return -EINVAL;
733
734         if (efi.mps != EFI_INVALID_TABLE_ADDR)
735                 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
736         if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
737                 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
738         if (efi.acpi != EFI_INVALID_TABLE_ADDR)
739                 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
740         if (efi.smbios != EFI_INVALID_TABLE_ADDR)
741                 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
742         if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
743                 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
744         if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
745                 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
746         if (efi.uga != EFI_INVALID_TABLE_ADDR)
747                 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
748
749         return str - buf;
750 }
751
752 static struct kobj_attribute efi_attr_systab =
753                         __ATTR(systab, 0400, systab_show, NULL);
754
755 static struct attribute *efi_subsys_attrs[] = {
756         &efi_attr_systab.attr,
757         NULL,   /* maybe more in the future? */
758 };
759
760 static struct attribute_group efi_subsys_attr_group = {
761         .attrs = efi_subsys_attrs,
762 };
763
764 static struct kobject *efi_kobj;
765
766 /*
767  * efivar_create_sysfs_entry()
768  * Requires:
769  *    variable_name_size = number of bytes required to hold
770  *                         variable_name (not counting the NULL
771  *                         character at the end.
772  *    efivars->lock is not held on entry or exit.
773  * Returns 1 on failure, 0 on success
774  */
775 static int
776 efivar_create_sysfs_entry(struct efivars *efivars,
777                           unsigned long variable_name_size,
778                           efi_char16_t *variable_name,
779                           efi_guid_t *vendor_guid)
780 {
781         int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
782         char *short_name;
783         struct efivar_entry *new_efivar;
784
785         short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
786         new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
787
788         if (!short_name || !new_efivar)  {
789                 kfree(short_name);
790                 kfree(new_efivar);
791                 return 1;
792         }
793
794         new_efivar->efivars = efivars;
795         memcpy(new_efivar->var.VariableName, variable_name,
796                 variable_name_size);
797         memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
798
799         /* Convert Unicode to normal chars (assume top bits are 0),
800            ala UTF-8 */
801         for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
802                 short_name[i] = variable_name[i] & 0xFF;
803         }
804         /* This is ugly, but necessary to separate one vendor's
805            private variables from another's.         */
806
807         *(short_name + strlen(short_name)) = '-';
808         efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
809
810         new_efivar->kobj.kset = efivars->kset;
811         i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
812                                  "%s", short_name);
813         if (i) {
814                 kfree(short_name);
815                 kfree(new_efivar);
816                 return 1;
817         }
818
819         kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
820         kfree(short_name);
821         short_name = NULL;
822
823         spin_lock(&efivars->lock);
824         list_add(&new_efivar->list, &efivars->list);
825         spin_unlock(&efivars->lock);
826
827         return 0;
828 }
829
830 static int
831 create_efivars_bin_attributes(struct efivars *efivars)
832 {
833         struct bin_attribute *attr;
834         int error;
835
836         /* new_var */
837         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
838         if (!attr)
839                 return -ENOMEM;
840
841         attr->attr.name = "new_var";
842         attr->attr.mode = 0200;
843         attr->write = efivar_create;
844         attr->private = efivars;
845         efivars->new_var = attr;
846
847         /* del_var */
848         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
849         if (!attr) {
850                 error = -ENOMEM;
851                 goto out_free;
852         }
853         attr->attr.name = "del_var";
854         attr->attr.mode = 0200;
855         attr->write = efivar_delete;
856         attr->private = efivars;
857         efivars->del_var = attr;
858
859         sysfs_bin_attr_init(efivars->new_var);
860         sysfs_bin_attr_init(efivars->del_var);
861
862         /* Register */
863         error = sysfs_create_bin_file(&efivars->kset->kobj,
864                                       efivars->new_var);
865         if (error) {
866                 printk(KERN_ERR "efivars: unable to create new_var sysfs file"
867                         " due to error %d\n", error);
868                 goto out_free;
869         }
870         error = sysfs_create_bin_file(&efivars->kset->kobj,
871                                       efivars->del_var);
872         if (error) {
873                 printk(KERN_ERR "efivars: unable to create del_var sysfs file"
874                         " due to error %d\n", error);
875                 sysfs_remove_bin_file(&efivars->kset->kobj,
876                                       efivars->new_var);
877                 goto out_free;
878         }
879
880         return 0;
881 out_free:
882         kfree(efivars->del_var);
883         efivars->del_var = NULL;
884         kfree(efivars->new_var);
885         efivars->new_var = NULL;
886         return error;
887 }
888
889 void unregister_efivars(struct efivars *efivars)
890 {
891         struct efivar_entry *entry, *n;
892
893         list_for_each_entry_safe(entry, n, &efivars->list, list) {
894                 spin_lock(&efivars->lock);
895                 list_del(&entry->list);
896                 spin_unlock(&efivars->lock);
897                 efivar_unregister(entry);
898         }
899         if (efivars->new_var)
900                 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
901         if (efivars->del_var)
902                 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
903         kfree(efivars->new_var);
904         kfree(efivars->del_var);
905         kset_unregister(efivars->kset);
906 }
907 EXPORT_SYMBOL_GPL(unregister_efivars);
908
909 int register_efivars(struct efivars *efivars,
910                      const struct efivar_operations *ops,
911                      struct kobject *parent_kobj)
912 {
913         efi_status_t status = EFI_NOT_FOUND;
914         efi_guid_t vendor_guid;
915         efi_char16_t *variable_name;
916         unsigned long variable_name_size = 1024;
917         int error = 0;
918
919         variable_name = kzalloc(variable_name_size, GFP_KERNEL);
920         if (!variable_name) {
921                 printk(KERN_ERR "efivars: Memory allocation failed.\n");
922                 return -ENOMEM;
923         }
924
925         spin_lock_init(&efivars->lock);
926         INIT_LIST_HEAD(&efivars->list);
927         efivars->ops = ops;
928
929         efivars->kset = kset_create_and_add("vars", NULL, parent_kobj);
930         if (!efivars->kset) {
931                 printk(KERN_ERR "efivars: Subsystem registration failed.\n");
932                 error = -ENOMEM;
933                 goto out;
934         }
935
936         /*
937          * Per EFI spec, the maximum storage allocated for both
938          * the variable name and variable data is 1024 bytes.
939          */
940
941         do {
942                 variable_name_size = 1024;
943
944                 status = ops->get_next_variable(&variable_name_size,
945                                                 variable_name,
946                                                 &vendor_guid);
947                 switch (status) {
948                 case EFI_SUCCESS:
949                         efivar_create_sysfs_entry(efivars,
950                                                   variable_name_size,
951                                                   variable_name,
952                                                   &vendor_guid);
953                         break;
954                 case EFI_NOT_FOUND:
955                         break;
956                 default:
957                         printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
958                                 status);
959                         status = EFI_NOT_FOUND;
960                         break;
961                 }
962         } while (status != EFI_NOT_FOUND);
963
964         error = create_efivars_bin_attributes(efivars);
965         if (error)
966                 unregister_efivars(efivars);
967
968 out:
969         kfree(variable_name);
970
971         return error;
972 }
973 EXPORT_SYMBOL_GPL(register_efivars);
974
975 static struct efivars __efivars;
976 static struct efivar_operations ops;
977
978 /*
979  * For now we register the efi subsystem with the firmware subsystem
980  * and the vars subsystem with the efi subsystem.  In the future, it
981  * might make sense to split off the efi subsystem into its own
982  * driver, but for now only efivars will register with it, so just
983  * include it here.
984  */
985
986 static int __init
987 efivars_init(void)
988 {
989         int error = 0;
990
991         printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
992                EFIVARS_DATE);
993
994         if (!efi_enabled)
995                 return 0;
996
997         /* For now we'll register the efi directory at /sys/firmware/efi */
998         efi_kobj = kobject_create_and_add("efi", firmware_kobj);
999         if (!efi_kobj) {
1000                 printk(KERN_ERR "efivars: Firmware registration failed.\n");
1001                 return -ENOMEM;
1002         }
1003
1004         ops.get_variable = efi.get_variable;
1005         ops.set_variable = efi.set_variable;
1006         ops.get_next_variable = efi.get_next_variable;
1007         error = register_efivars(&__efivars, &ops, efi_kobj);
1008         if (error)
1009                 goto err_put;
1010
1011         /* Don't forget the systab entry */
1012         error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
1013         if (error) {
1014                 printk(KERN_ERR
1015                        "efivars: Sysfs attribute export failed with error %d.\n",
1016                        error);
1017                 goto err_unregister;
1018         }
1019
1020         return 0;
1021
1022 err_unregister:
1023         unregister_efivars(&__efivars);
1024 err_put:
1025         kobject_put(efi_kobj);
1026         return error;
1027 }
1028
1029 static void __exit
1030 efivars_exit(void)
1031 {
1032         if (efi_enabled) {
1033                 unregister_efivars(&__efivars);
1034                 kobject_put(efi_kobj);
1035         }
1036 }
1037
1038 module_init(efivars_init);
1039 module_exit(efivars_exit);
1040