rk lcdc:modify Kconfig
[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 & EFI_VARIABLE_NON_VOLATILE)
404                 str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
405         if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
406                 str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
407         if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
408                 str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
409         if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
410                 str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
411         if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
412                 str += sprintf(str,
413                         "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
414         if (var->Attributes &
415                         EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
416                 str += sprintf(str,
417                         "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
418         if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
419                 str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
420         return str - buf;
421 }
422
423 static ssize_t
424 efivar_size_read(struct efivar_entry *entry, char *buf)
425 {
426         struct efi_variable *var = &entry->var;
427         char *str = buf;
428         efi_status_t status;
429
430         if (!entry || !buf)
431                 return -EINVAL;
432
433         status = get_var_data(entry->efivars, var);
434         if (status != EFI_SUCCESS)
435                 return -EIO;
436
437         str += sprintf(str, "0x%lx\n", var->DataSize);
438         return str - buf;
439 }
440
441 static ssize_t
442 efivar_data_read(struct efivar_entry *entry, char *buf)
443 {
444         struct efi_variable *var = &entry->var;
445         efi_status_t status;
446
447         if (!entry || !buf)
448                 return -EINVAL;
449
450         status = get_var_data(entry->efivars, var);
451         if (status != EFI_SUCCESS)
452                 return -EIO;
453
454         memcpy(buf, var->Data, var->DataSize);
455         return var->DataSize;
456 }
457 /*
458  * We allow each variable to be edited via rewriting the
459  * entire efi variable structure.
460  */
461 static ssize_t
462 efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
463 {
464         struct efi_variable *new_var, *var = &entry->var;
465         struct efivars *efivars = entry->efivars;
466         efi_status_t status = EFI_NOT_FOUND;
467
468         if (count != sizeof(struct efi_variable))
469                 return -EINVAL;
470
471         new_var = (struct efi_variable *)buf;
472         /*
473          * If only updating the variable data, then the name
474          * and guid should remain the same
475          */
476         if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
477                 efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
478                 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
479                 return -EINVAL;
480         }
481
482         if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
483                 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
484                 return -EINVAL;
485         }
486
487         if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
488             validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
489                 printk(KERN_ERR "efivars: Malformed variable content\n");
490                 return -EINVAL;
491         }
492
493         spin_lock(&efivars->lock);
494         status = efivars->ops->set_variable(new_var->VariableName,
495                                             &new_var->VendorGuid,
496                                             new_var->Attributes,
497                                             new_var->DataSize,
498                                             new_var->Data);
499
500         spin_unlock(&efivars->lock);
501
502         if (status != EFI_SUCCESS) {
503                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
504                         status);
505                 return -EIO;
506         }
507
508         memcpy(&entry->var, new_var, count);
509         return count;
510 }
511
512 static ssize_t
513 efivar_show_raw(struct efivar_entry *entry, char *buf)
514 {
515         struct efi_variable *var = &entry->var;
516         efi_status_t status;
517
518         if (!entry || !buf)
519                 return 0;
520
521         status = get_var_data(entry->efivars, var);
522         if (status != EFI_SUCCESS)
523                 return -EIO;
524
525         memcpy(buf, var, sizeof(*var));
526         return sizeof(*var);
527 }
528
529 /*
530  * Generic read/write functions that call the specific functions of
531  * the attributes...
532  */
533 static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
534                                 char *buf)
535 {
536         struct efivar_entry *var = to_efivar_entry(kobj);
537         struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
538         ssize_t ret = -EIO;
539
540         if (!capable(CAP_SYS_ADMIN))
541                 return -EACCES;
542
543         if (efivar_attr->show) {
544                 ret = efivar_attr->show(var, buf);
545         }
546         return ret;
547 }
548
549 static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
550                                 const char *buf, size_t count)
551 {
552         struct efivar_entry *var = to_efivar_entry(kobj);
553         struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
554         ssize_t ret = -EIO;
555
556         if (!capable(CAP_SYS_ADMIN))
557                 return -EACCES;
558
559         if (efivar_attr->store)
560                 ret = efivar_attr->store(var, buf, count);
561
562         return ret;
563 }
564
565 static const struct sysfs_ops efivar_attr_ops = {
566         .show = efivar_attr_show,
567         .store = efivar_attr_store,
568 };
569
570 static void efivar_release(struct kobject *kobj)
571 {
572         struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
573         kfree(var);
574 }
575
576 static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
577 static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
578 static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
579 static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
580 static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
581
582 static struct attribute *def_attrs[] = {
583         &efivar_attr_guid.attr,
584         &efivar_attr_size.attr,
585         &efivar_attr_attributes.attr,
586         &efivar_attr_data.attr,
587         &efivar_attr_raw_var.attr,
588         NULL,
589 };
590
591 static struct kobj_type efivar_ktype = {
592         .release = efivar_release,
593         .sysfs_ops = &efivar_attr_ops,
594         .default_attrs = def_attrs,
595 };
596
597 static inline void
598 efivar_unregister(struct efivar_entry *var)
599 {
600         kobject_put(&var->kobj);
601 }
602
603
604 static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
605                              struct bin_attribute *bin_attr,
606                              char *buf, loff_t pos, size_t count)
607 {
608         struct efi_variable *new_var = (struct efi_variable *)buf;
609         struct efivars *efivars = bin_attr->private;
610         struct efivar_entry *search_efivar, *n;
611         unsigned long strsize1, strsize2;
612         efi_status_t status = EFI_NOT_FOUND;
613         int found = 0;
614
615         if (!capable(CAP_SYS_ADMIN))
616                 return -EACCES;
617
618         if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
619             validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
620                 printk(KERN_ERR "efivars: Malformed variable content\n");
621                 return -EINVAL;
622         }
623
624         spin_lock(&efivars->lock);
625
626         /*
627          * Does this variable already exist?
628          */
629         list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
630                 strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
631                 strsize2 = utf16_strsize(new_var->VariableName, 1024);
632                 if (strsize1 == strsize2 &&
633                         !memcmp(&(search_efivar->var.VariableName),
634                                 new_var->VariableName, strsize1) &&
635                         !efi_guidcmp(search_efivar->var.VendorGuid,
636                                 new_var->VendorGuid)) {
637                         found = 1;
638                         break;
639                 }
640         }
641         if (found) {
642                 spin_unlock(&efivars->lock);
643                 return -EINVAL;
644         }
645
646         /* now *really* create the variable via EFI */
647         status = efivars->ops->set_variable(new_var->VariableName,
648                                             &new_var->VendorGuid,
649                                             new_var->Attributes,
650                                             new_var->DataSize,
651                                             new_var->Data);
652
653         if (status != EFI_SUCCESS) {
654                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
655                         status);
656                 spin_unlock(&efivars->lock);
657                 return -EIO;
658         }
659         spin_unlock(&efivars->lock);
660
661         /* Create the entry in sysfs.  Locking is not required here */
662         status = efivar_create_sysfs_entry(efivars,
663                                            utf16_strsize(new_var->VariableName,
664                                                          1024),
665                                            new_var->VariableName,
666                                            &new_var->VendorGuid);
667         if (status) {
668                 printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");
669         }
670         return count;
671 }
672
673 static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
674                              struct bin_attribute *bin_attr,
675                              char *buf, loff_t pos, size_t count)
676 {
677         struct efi_variable *del_var = (struct efi_variable *)buf;
678         struct efivars *efivars = bin_attr->private;
679         struct efivar_entry *search_efivar, *n;
680         unsigned long strsize1, strsize2;
681         efi_status_t status = EFI_NOT_FOUND;
682         int found = 0;
683
684         if (!capable(CAP_SYS_ADMIN))
685                 return -EACCES;
686
687         spin_lock(&efivars->lock);
688
689         /*
690          * Does this variable already exist?
691          */
692         list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
693                 strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
694                 strsize2 = utf16_strsize(del_var->VariableName, 1024);
695                 if (strsize1 == strsize2 &&
696                         !memcmp(&(search_efivar->var.VariableName),
697                                 del_var->VariableName, strsize1) &&
698                         !efi_guidcmp(search_efivar->var.VendorGuid,
699                                 del_var->VendorGuid)) {
700                         found = 1;
701                         break;
702                 }
703         }
704         if (!found) {
705                 spin_unlock(&efivars->lock);
706                 return -EINVAL;
707         }
708         /* force the Attributes/DataSize to 0 to ensure deletion */
709         del_var->Attributes = 0;
710         del_var->DataSize = 0;
711
712         status = efivars->ops->set_variable(del_var->VariableName,
713                                             &del_var->VendorGuid,
714                                             del_var->Attributes,
715                                             del_var->DataSize,
716                                             del_var->Data);
717
718         if (status != EFI_SUCCESS) {
719                 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
720                         status);
721                 spin_unlock(&efivars->lock);
722                 return -EIO;
723         }
724         list_del(&search_efivar->list);
725         /* We need to release this lock before unregistering. */
726         spin_unlock(&efivars->lock);
727         efivar_unregister(search_efivar);
728
729         /* It's dead Jim.... */
730         return count;
731 }
732
733 /*
734  * Let's not leave out systab information that snuck into
735  * the efivars driver
736  */
737 static ssize_t systab_show(struct kobject *kobj,
738                            struct kobj_attribute *attr, char *buf)
739 {
740         char *str = buf;
741
742         if (!kobj || !buf)
743                 return -EINVAL;
744
745         if (efi.mps != EFI_INVALID_TABLE_ADDR)
746                 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
747         if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
748                 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
749         if (efi.acpi != EFI_INVALID_TABLE_ADDR)
750                 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
751         if (efi.smbios != EFI_INVALID_TABLE_ADDR)
752                 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
753         if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
754                 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
755         if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
756                 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
757         if (efi.uga != EFI_INVALID_TABLE_ADDR)
758                 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
759
760         return str - buf;
761 }
762
763 static struct kobj_attribute efi_attr_systab =
764                         __ATTR(systab, 0400, systab_show, NULL);
765
766 static struct attribute *efi_subsys_attrs[] = {
767         &efi_attr_systab.attr,
768         NULL,   /* maybe more in the future? */
769 };
770
771 static struct attribute_group efi_subsys_attr_group = {
772         .attrs = efi_subsys_attrs,
773 };
774
775 static struct kobject *efi_kobj;
776
777 /*
778  * efivar_create_sysfs_entry()
779  * Requires:
780  *    variable_name_size = number of bytes required to hold
781  *                         variable_name (not counting the NULL
782  *                         character at the end.
783  *    efivars->lock is not held on entry or exit.
784  * Returns 1 on failure, 0 on success
785  */
786 static int
787 efivar_create_sysfs_entry(struct efivars *efivars,
788                           unsigned long variable_name_size,
789                           efi_char16_t *variable_name,
790                           efi_guid_t *vendor_guid)
791 {
792         int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
793         char *short_name;
794         struct efivar_entry *new_efivar;
795
796         short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
797         new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
798
799         if (!short_name || !new_efivar)  {
800                 kfree(short_name);
801                 kfree(new_efivar);
802                 return 1;
803         }
804
805         new_efivar->efivars = efivars;
806         memcpy(new_efivar->var.VariableName, variable_name,
807                 variable_name_size);
808         memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
809
810         /* Convert Unicode to normal chars (assume top bits are 0),
811            ala UTF-8 */
812         for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
813                 short_name[i] = variable_name[i] & 0xFF;
814         }
815         /* This is ugly, but necessary to separate one vendor's
816            private variables from another's.         */
817
818         *(short_name + strlen(short_name)) = '-';
819         efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
820
821         new_efivar->kobj.kset = efivars->kset;
822         i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
823                                  "%s", short_name);
824         if (i) {
825                 kfree(short_name);
826                 kfree(new_efivar);
827                 return 1;
828         }
829
830         kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
831         kfree(short_name);
832         short_name = NULL;
833
834         spin_lock(&efivars->lock);
835         list_add(&new_efivar->list, &efivars->list);
836         spin_unlock(&efivars->lock);
837
838         return 0;
839 }
840
841 static int
842 create_efivars_bin_attributes(struct efivars *efivars)
843 {
844         struct bin_attribute *attr;
845         int error;
846
847         /* new_var */
848         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
849         if (!attr)
850                 return -ENOMEM;
851
852         attr->attr.name = "new_var";
853         attr->attr.mode = 0200;
854         attr->write = efivar_create;
855         attr->private = efivars;
856         efivars->new_var = attr;
857
858         /* del_var */
859         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
860         if (!attr) {
861                 error = -ENOMEM;
862                 goto out_free;
863         }
864         attr->attr.name = "del_var";
865         attr->attr.mode = 0200;
866         attr->write = efivar_delete;
867         attr->private = efivars;
868         efivars->del_var = attr;
869
870         sysfs_bin_attr_init(efivars->new_var);
871         sysfs_bin_attr_init(efivars->del_var);
872
873         /* Register */
874         error = sysfs_create_bin_file(&efivars->kset->kobj,
875                                       efivars->new_var);
876         if (error) {
877                 printk(KERN_ERR "efivars: unable to create new_var sysfs file"
878                         " due to error %d\n", error);
879                 goto out_free;
880         }
881         error = sysfs_create_bin_file(&efivars->kset->kobj,
882                                       efivars->del_var);
883         if (error) {
884                 printk(KERN_ERR "efivars: unable to create del_var sysfs file"
885                         " due to error %d\n", error);
886                 sysfs_remove_bin_file(&efivars->kset->kobj,
887                                       efivars->new_var);
888                 goto out_free;
889         }
890
891         return 0;
892 out_free:
893         kfree(efivars->del_var);
894         efivars->del_var = NULL;
895         kfree(efivars->new_var);
896         efivars->new_var = NULL;
897         return error;
898 }
899
900 void unregister_efivars(struct efivars *efivars)
901 {
902         struct efivar_entry *entry, *n;
903
904         list_for_each_entry_safe(entry, n, &efivars->list, list) {
905                 spin_lock(&efivars->lock);
906                 list_del(&entry->list);
907                 spin_unlock(&efivars->lock);
908                 efivar_unregister(entry);
909         }
910         if (efivars->new_var)
911                 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
912         if (efivars->del_var)
913                 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
914         kfree(efivars->new_var);
915         kfree(efivars->del_var);
916         kset_unregister(efivars->kset);
917 }
918 EXPORT_SYMBOL_GPL(unregister_efivars);
919
920 int register_efivars(struct efivars *efivars,
921                      const struct efivar_operations *ops,
922                      struct kobject *parent_kobj)
923 {
924         efi_status_t status = EFI_NOT_FOUND;
925         efi_guid_t vendor_guid;
926         efi_char16_t *variable_name;
927         unsigned long variable_name_size = 1024;
928         int error = 0;
929
930         variable_name = kzalloc(variable_name_size, GFP_KERNEL);
931         if (!variable_name) {
932                 printk(KERN_ERR "efivars: Memory allocation failed.\n");
933                 return -ENOMEM;
934         }
935
936         spin_lock_init(&efivars->lock);
937         INIT_LIST_HEAD(&efivars->list);
938         efivars->ops = ops;
939
940         efivars->kset = kset_create_and_add("vars", NULL, parent_kobj);
941         if (!efivars->kset) {
942                 printk(KERN_ERR "efivars: Subsystem registration failed.\n");
943                 error = -ENOMEM;
944                 goto out;
945         }
946
947         /*
948          * Per EFI spec, the maximum storage allocated for both
949          * the variable name and variable data is 1024 bytes.
950          */
951
952         do {
953                 variable_name_size = 1024;
954
955                 status = ops->get_next_variable(&variable_name_size,
956                                                 variable_name,
957                                                 &vendor_guid);
958                 switch (status) {
959                 case EFI_SUCCESS:
960                         efivar_create_sysfs_entry(efivars,
961                                                   variable_name_size,
962                                                   variable_name,
963                                                   &vendor_guid);
964                         break;
965                 case EFI_NOT_FOUND:
966                         break;
967                 default:
968                         printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
969                                 status);
970                         status = EFI_NOT_FOUND;
971                         break;
972                 }
973         } while (status != EFI_NOT_FOUND);
974
975         error = create_efivars_bin_attributes(efivars);
976         if (error)
977                 unregister_efivars(efivars);
978
979 out:
980         kfree(variable_name);
981
982         return error;
983 }
984 EXPORT_SYMBOL_GPL(register_efivars);
985
986 static struct efivars __efivars;
987 static struct efivar_operations ops;
988
989 /*
990  * For now we register the efi subsystem with the firmware subsystem
991  * and the vars subsystem with the efi subsystem.  In the future, it
992  * might make sense to split off the efi subsystem into its own
993  * driver, but for now only efivars will register with it, so just
994  * include it here.
995  */
996
997 static int __init
998 efivars_init(void)
999 {
1000         int error = 0;
1001
1002         printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
1003                EFIVARS_DATE);
1004
1005         if (!efi_enabled)
1006                 return 0;
1007
1008         /* For now we'll register the efi directory at /sys/firmware/efi */
1009         efi_kobj = kobject_create_and_add("efi", firmware_kobj);
1010         if (!efi_kobj) {
1011                 printk(KERN_ERR "efivars: Firmware registration failed.\n");
1012                 return -ENOMEM;
1013         }
1014
1015         ops.get_variable = efi.get_variable;
1016         ops.set_variable = efi.set_variable;
1017         ops.get_next_variable = efi.get_next_variable;
1018         error = register_efivars(&__efivars, &ops, efi_kobj);
1019         if (error)
1020                 goto err_put;
1021
1022         /* Don't forget the systab entry */
1023         error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
1024         if (error) {
1025                 printk(KERN_ERR
1026                        "efivars: Sysfs attribute export failed with error %d.\n",
1027                        error);
1028                 goto err_unregister;
1029         }
1030
1031         return 0;
1032
1033 err_unregister:
1034         unregister_efivars(&__efivars);
1035 err_put:
1036         kobject_put(efi_kobj);
1037         return error;
1038 }
1039
1040 static void __exit
1041 efivars_exit(void)
1042 {
1043         if (efi_enabled) {
1044                 unregister_efivars(&__efivars);
1045                 kobject_put(efi_kobj);
1046         }
1047 }
1048
1049 module_init(efivars_init);
1050 module_exit(efivars_exit);
1051