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 81#include <asm/uaccess.h> 82 83#define EFIVARS_VERSION "0.08" 84#define EFIVARS_DATE "2004-May-17" 85 86MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>"); 87MODULE_DESCRIPTION("sysfs interface to EFI Variables"); 88MODULE_LICENSE("GPL"); 89MODULE_VERSION(EFIVARS_VERSION); 90 91/* 92 * efivars_lock protects two things: 93 * 1) efivar_list - adds, removals, reads, writes 94 * 2) efi.[gs]et_variable() calls. 95 * It must not be held when creating sysfs entries or calling kmalloc. 96 * efi.get_next_variable() is only called from efivars_init(), 97 * which is protected by the BKL, so that path is safe. 98 */ 99static DEFINE_SPINLOCK(efivars_lock); 100static LIST_HEAD(efivar_list); 101 102/* 103 * The maximum size of VariableName + Data = 1024 104 * Therefore, it's reasonable to save that much 105 * space in each part of the structure, 106 * and we use a page for reading/writing. 107 */ 108 109struct efi_variable { 110 efi_char16_t VariableName[1024/sizeof(efi_char16_t)]; 111 efi_guid_t VendorGuid; 112 unsigned long DataSize; 113 __u8 Data[1024]; 114 efi_status_t Status; 115 __u32 Attributes; 116} __attribute__((packed)); 117 118 119struct efivar_entry { 120 struct efi_variable var; 121 struct list_head list; 122 struct kobject kobj; 123}; 124 125struct efivar_attribute { 126 struct attribute attr; 127 ssize_t (*show) (struct efivar_entry *entry, char *buf); 128 ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count); 129}; 130 131 132#define EFI_ATTR(_name, _mode, _show, _store) \ 133struct subsys_attribute efi_attr_##_name = { \ 134 .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \ 135 .show = _show, \ 136 .store = _store, \ 137}; 138 139#define EFIVAR_ATTR(_name, _mode, _show, _store) \ 140struct efivar_attribute efivar_attr_##_name = { \ 141 .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \ 142 .show = _show, \ 143 .store = _store, \ 144}; 145 146#define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \ 147struct subsys_attribute var_subsys_attr_##_name = { \ 148 .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \ 149 .show = _show, \ 150 .store = _store, \ 151}; 152 153#define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr) 154#define to_efivar_entry(obj) container_of(obj, struct efivar_entry, kobj) 155 156/* 157 * Prototype for sysfs creation function 158 */ 159static int 160efivar_create_sysfs_entry(unsigned long variable_name_size, 161 efi_char16_t *variable_name, 162 efi_guid_t *vendor_guid); 163 164/* Return the number of unicode characters in data */ 165static unsigned long 166utf8_strlen(efi_char16_t *data, unsigned long maxlength) 167{ 168 unsigned long length = 0; 169 170 while (*data++ != 0 && length < maxlength) 171 length++; 172 return length; 173} 174 175/* 176 * Return the number of bytes is the length of this string 177 * Note: this is NOT the same as the number of unicode characters 178 */ 179static inline unsigned long 180utf8_strsize(efi_char16_t *data, unsigned long maxlength) 181{ 182 return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); 183} 184 185static efi_status_t 186get_var_data(struct efi_variable *var) 187{ 188 efi_status_t status; 189 190 spin_lock(&efivars_lock); 191 var->DataSize = 1024; 192 status = efi.get_variable(var->VariableName, 193 &var->VendorGuid, 194 &var->Attributes, 195 &var->DataSize, 196 var->Data); 197 spin_unlock(&efivars_lock); 198 if (status != EFI_SUCCESS) { 199 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", 200 status); 201 } 202 return status; 203} 204 205static ssize_t 206efivar_guid_read(struct efivar_entry *entry, char *buf) 207{ 208 struct efi_variable *var = &entry->var; 209 char *str = buf; 210 211 if (!entry || !buf) 212 return 0; 213 214 efi_guid_unparse(&var->VendorGuid, str); 215 str += strlen(str); 216 str += sprintf(str, "\n"); 217 218 return str - buf; 219} 220 221static ssize_t 222efivar_attr_read(struct efivar_entry *entry, char *buf) 223{ 224 struct efi_variable *var = &entry->var; 225 char *str = buf; 226 efi_status_t status; 227 228 if (!entry || !buf) 229 return -EINVAL; 230 231 status = get_var_data(var); 232 if (status != EFI_SUCCESS) 233 return -EIO; 234 235 if (var->Attributes & 0x1) 236 str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n"); 237 if (var->Attributes & 0x2) 238 str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n"); 239 if (var->Attributes & 0x4) 240 str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n"); 241 return str - buf; 242} 243 244static ssize_t 245efivar_size_read(struct efivar_entry *entry, char *buf) 246{ 247 struct efi_variable *var = &entry->var; 248 char *str = buf; 249 efi_status_t status; 250 251 if (!entry || !buf) 252 return -EINVAL; 253 254 status = get_var_data(var); 255 if (status != EFI_SUCCESS) 256 return -EIO; 257 258 str += sprintf(str, "0x%lx\n", var->DataSize); 259 return str - buf; 260} 261 262static ssize_t 263efivar_data_read(struct efivar_entry *entry, char *buf) 264{ 265 struct efi_variable *var = &entry->var; 266 efi_status_t status; 267 268 if (!entry || !buf) 269 return -EINVAL; 270 271 status = get_var_data(var); 272 if (status != EFI_SUCCESS) 273 return -EIO; 274 275 memcpy(buf, var->Data, var->DataSize); 276 return var->DataSize; 277} 278/* 279 * We allow each variable to be edited via rewriting the 280 * entire efi variable structure. 281 */ 282static ssize_t 283efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) 284{ 285 struct efi_variable *new_var, *var = &entry->var; 286 efi_status_t status = EFI_NOT_FOUND; 287 288 if (count != sizeof(struct efi_variable)) 289 return -EINVAL; 290 291 new_var = (struct efi_variable *)buf; 292 /* 293 * If only updating the variable data, then the name 294 * and guid should remain the same 295 */ 296 if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) || 297 efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) { 298 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n"); 299 return -EINVAL; 300 } 301 302 if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){ 303 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n"); 304 return -EINVAL; 305 } 306 307 spin_lock(&efivars_lock); 308 status = efi.set_variable(new_var->VariableName, 309 &new_var->VendorGuid, 310 new_var->Attributes, 311 new_var->DataSize, 312 new_var->Data); 313 314 spin_unlock(&efivars_lock); 315 316 if (status != EFI_SUCCESS) { 317 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 318 status); 319 return -EIO; 320 } 321 322 memcpy(&entry->var, new_var, count); 323 return count; 324} 325 326static ssize_t 327efivar_show_raw(struct efivar_entry *entry, char *buf) 328{ 329 struct efi_variable *var = &entry->var; 330 efi_status_t status; 331 332 if (!entry || !buf) 333 return 0; 334 335 status = get_var_data(var); 336 if (status != EFI_SUCCESS) 337 return -EIO; 338 339 memcpy(buf, var, sizeof(*var)); 340 return sizeof(*var); 341} 342 343/* 344 * Generic read/write functions that call the specific functions of 345 * the atttributes... 346 */ 347static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr, 348 char *buf) 349{ 350 struct efivar_entry *var = to_efivar_entry(kobj); 351 struct efivar_attribute *efivar_attr = to_efivar_attr(attr); 352 ssize_t ret = -EIO; 353 354 if (!capable(CAP_SYS_ADMIN)) 355 return -EACCES; 356 357 if (efivar_attr->show) { 358 ret = efivar_attr->show(var, buf); 359 } 360 return ret; 361} 362 363static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr, 364 const char *buf, size_t count) 365{ 366 struct efivar_entry *var = to_efivar_entry(kobj); 367 struct efivar_attribute *efivar_attr = to_efivar_attr(attr); 368 ssize_t ret = -EIO; 369 370 if (!capable(CAP_SYS_ADMIN)) 371 return -EACCES; 372 373 if (efivar_attr->store) 374 ret = efivar_attr->store(var, buf, count); 375 376 return ret; 377} 378 379static struct sysfs_ops efivar_attr_ops = { 380 .show = efivar_attr_show, 381 .store = efivar_attr_store, 382}; 383 384static void efivar_release(struct kobject *kobj) 385{ 386 struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); 387 kfree(var); 388} 389 390static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL); 391static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL); 392static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL); 393static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL); 394static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw); 395 396static struct attribute *def_attrs[] = { 397 &efivar_attr_guid.attr, 398 &efivar_attr_size.attr, 399 &efivar_attr_attributes.attr, 400 &efivar_attr_data.attr, 401 &efivar_attr_raw_var.attr, 402 NULL, 403}; 404 405static struct kobj_type ktype_efivar = { 406 .release = efivar_release, 407 .sysfs_ops = &efivar_attr_ops, 408 .default_attrs = def_attrs, 409}; 410 411static ssize_t 412dummy(struct kset *kset, char *buf) 413{ 414 return -ENODEV; 415} 416 417static inline void 418efivar_unregister(struct efivar_entry *var) 419{ 420 kobject_unregister(&var->kobj); 421} 422 423 424static ssize_t 425efivar_create(struct kset *kset, const char *buf, size_t count) 426{ 427 struct efi_variable *new_var = (struct efi_variable *)buf; 428 struct efivar_entry *search_efivar, *n; 429 unsigned long strsize1, strsize2; 430 efi_status_t status = EFI_NOT_FOUND; 431 int found = 0; 432 433 if (!capable(CAP_SYS_ADMIN)) 434 return -EACCES; 435 436 spin_lock(&efivars_lock); 437 438 /* 439 * Does this variable already exist? 440 */ 441 list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { 442 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); 443 strsize2 = utf8_strsize(new_var->VariableName, 1024); 444 if (strsize1 == strsize2 && 445 !memcmp(&(search_efivar->var.VariableName), 446 new_var->VariableName, strsize1) && 447 !efi_guidcmp(search_efivar->var.VendorGuid, 448 new_var->VendorGuid)) { 449 found = 1; 450 break; 451 } 452 } 453 if (found) { 454 spin_unlock(&efivars_lock); 455 return -EINVAL; 456 } 457 458 /* now *really* create the variable via EFI */ 459 status = efi.set_variable(new_var->VariableName, 460 &new_var->VendorGuid, 461 new_var->Attributes, 462 new_var->DataSize, 463 new_var->Data); 464 465 if (status != EFI_SUCCESS) { 466 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 467 status); 468 spin_unlock(&efivars_lock); 469 return -EIO; 470 } 471 spin_unlock(&efivars_lock); 472 473 /* Create the entry in sysfs. Locking is not required here */ 474 status = efivar_create_sysfs_entry(utf8_strsize(new_var->VariableName, 475 1024), new_var->VariableName, &new_var->VendorGuid); 476 if (status) { 477 printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n"); 478 } 479 return count; 480} 481 482static ssize_t 483efivar_delete(struct kset *kset, const char *buf, size_t count) 484{ 485 struct efi_variable *del_var = (struct efi_variable *)buf; 486 struct efivar_entry *search_efivar, *n; 487 unsigned long strsize1, strsize2; 488 efi_status_t status = EFI_NOT_FOUND; 489 int found = 0; 490 491 if (!capable(CAP_SYS_ADMIN)) 492 return -EACCES; 493 494 spin_lock(&efivars_lock); 495 496 /* 497 * Does this variable already exist? 498 */ 499 list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { 500 strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); 501 strsize2 = utf8_strsize(del_var->VariableName, 1024); 502 if (strsize1 == strsize2 && 503 !memcmp(&(search_efivar->var.VariableName), 504 del_var->VariableName, strsize1) && 505 !efi_guidcmp(search_efivar->var.VendorGuid, 506 del_var->VendorGuid)) { 507 found = 1; 508 break; 509 } 510 } 511 if (!found) { 512 spin_unlock(&efivars_lock); 513 return -EINVAL; 514 } 515 /* force the Attributes/DataSize to 0 to ensure deletion */ 516 del_var->Attributes = 0; 517 del_var->DataSize = 0; 518 519 status = efi.set_variable(del_var->VariableName, 520 &del_var->VendorGuid, 521 del_var->Attributes, 522 del_var->DataSize, 523 del_var->Data); 524 525 if (status != EFI_SUCCESS) { 526 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 527 status); 528 spin_unlock(&efivars_lock); 529 return -EIO; 530 } 531 list_del(&search_efivar->list); 532 /* We need to release this lock before unregistering. */ 533 spin_unlock(&efivars_lock); 534 efivar_unregister(search_efivar); 535 536 /* It's dead Jim.... */ 537 return count; 538} 539 540static VAR_SUBSYS_ATTR(new_var, 0200, dummy, efivar_create); 541static VAR_SUBSYS_ATTR(del_var, 0200, dummy, efivar_delete); 542 543static struct subsys_attribute *var_subsys_attrs[] = { 544 &var_subsys_attr_new_var, 545 &var_subsys_attr_del_var, 546 NULL, 547}; 548 549/* 550 * Let's not leave out systab information that snuck into 551 * the efivars driver 552 */ 553static ssize_t 554systab_read(struct kset *kset, char *buf) 555{ 556 char *str = buf; 557 558 if (!kset || !buf) 559 return -EINVAL; 560 561 if (efi.mps != EFI_INVALID_TABLE_ADDR) 562 str += sprintf(str, "MPS=0x%lx\n", efi.mps); 563 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) 564 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20); 565 if (efi.acpi != EFI_INVALID_TABLE_ADDR) 566 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi); 567 if (efi.smbios != EFI_INVALID_TABLE_ADDR) 568 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios); 569 if (efi.hcdp != EFI_INVALID_TABLE_ADDR) 570 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp); 571 if (efi.boot_info != EFI_INVALID_TABLE_ADDR) 572 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info); 573 if (efi.uga != EFI_INVALID_TABLE_ADDR) 574 str += sprintf(str, "UGA=0x%lx\n", efi.uga); 575 576 return str - buf; 577} 578 579static EFI_ATTR(systab, 0400, systab_read, NULL); 580 581static struct subsys_attribute *efi_subsys_attrs[] = { 582 &efi_attr_systab, 583 NULL, /* maybe more in the future? */ 584}; 585 586static decl_subsys(vars, &ktype_efivar, NULL); 587static decl_subsys(efi, NULL, NULL); 588 589/* 590 * efivar_create_sysfs_entry() 591 * Requires: 592 * variable_name_size = number of bytes required to hold 593 * variable_name (not counting the NULL 594 * character at the end. 595 * efivars_lock is not held on entry or exit. 596 * Returns 1 on failure, 0 on success 597 */ 598static int 599efivar_create_sysfs_entry(unsigned long variable_name_size, 600 efi_char16_t *variable_name, 601 efi_guid_t *vendor_guid) 602{ 603 int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; 604 char *short_name; 605 struct efivar_entry *new_efivar; 606 607 short_name = kzalloc(short_name_size + 1, GFP_KERNEL); 608 new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); 609 610 if (!short_name || !new_efivar) { 611 kfree(short_name); 612 kfree(new_efivar); 613 return 1; 614 } 615 616 memcpy(new_efivar->var.VariableName, variable_name, 617 variable_name_size); 618 memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t)); 619 620 /* Convert Unicode to normal chars (assume top bits are 0), 621 ala UTF-8 */ 622 for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) { 623 short_name[i] = variable_name[i] & 0xFF; 624 } 625 /* This is ugly, but necessary to separate one vendor's 626 private variables from another's. */ 627 628 *(short_name + strlen(short_name)) = '-'; 629 efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); 630 631 kobject_set_name(&new_efivar->kobj, "%s", short_name); 632 kobj_set_kset_s(new_efivar, vars_subsys); 633 i = kobject_register(&new_efivar->kobj); 634 if (i) { 635 kfree(short_name); 636 kfree(new_efivar); 637 return 1; 638 } 639 640 kfree(short_name); 641 short_name = NULL; 642 643 spin_lock(&efivars_lock); 644 list_add(&new_efivar->list, &efivar_list); 645 spin_unlock(&efivars_lock); 646 647 return 0; 648} 649/* 650 * For now we register the efi subsystem with the firmware subsystem 651 * and the vars subsystem with the efi subsystem. In the future, it 652 * might make sense to split off the efi subsystem into its own 653 * driver, but for now only efivars will register with it, so just 654 * include it here. 655 */ 656 657static int __init 658efivars_init(void) 659{ 660 efi_status_t status = EFI_NOT_FOUND; 661 efi_guid_t vendor_guid; 662 efi_char16_t *variable_name; 663 struct subsys_attribute *attr; 664 unsigned long variable_name_size = 1024; 665 int i, error = 0; 666 667 if (!efi_enabled) 668 return -ENODEV; 669 670 variable_name = kzalloc(variable_name_size, GFP_KERNEL); 671 if (!variable_name) { 672 printk(KERN_ERR "efivars: Memory allocation failed.\n"); 673 return -ENOMEM; 674 } 675 676 printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, 677 EFIVARS_DATE); 678 679 /* 680 * For now we'll register the efi subsys within this driver 681 */ 682 683 error = firmware_register(&efi_subsys); 684 685 if (error) { 686 printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error); 687 goto out_free; 688 } 689 690 kobj_set_kset_s(&vars_subsys, efi_subsys); 691 692 error = subsystem_register(&vars_subsys); 693 694 if (error) { 695 printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error); 696 goto out_firmware_unregister; 697 } 698 699 /* 700 * Per EFI spec, the maximum storage allocated for both 701 * the variable name and variable data is 1024 bytes. 702 */ 703 704 do { 705 variable_name_size = 1024; 706 707 status = efi.get_next_variable(&variable_name_size, 708 variable_name, 709 &vendor_guid); 710 switch (status) { 711 case EFI_SUCCESS: 712 efivar_create_sysfs_entry(variable_name_size, 713 variable_name, 714 &vendor_guid); 715 break; 716 case EFI_NOT_FOUND: 717 break; 718 default: 719 printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n", 720 status); 721 status = EFI_NOT_FOUND; 722 break; 723 } 724 } while (status != EFI_NOT_FOUND); 725 726 /* 727 * Now add attributes to allow creation of new vars 728 * and deletion of existing ones... 729 */ 730 731 for (i = 0; (attr = var_subsys_attrs[i]) && !error; i++) { 732 if (attr->show && attr->store) 733 error = subsys_create_file(&vars_subsys, attr); 734 } 735 736 /* Don't forget the systab entry */ 737 738 for (i = 0; (attr = efi_subsys_attrs[i]) && !error; i++) { 739 if (attr->show) 740 error = subsys_create_file(&efi_subsys, attr); 741 } 742 743 if (error) 744 printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); 745 else 746 goto out_free; 747 748 subsystem_unregister(&vars_subsys); 749 750out_firmware_unregister: 751 firmware_unregister(&efi_subsys); 752 753out_free: 754 kfree(variable_name); 755 756 return error; 757} 758 759static void __exit 760efivars_exit(void) 761{ 762 struct efivar_entry *entry, *n; 763 764 list_for_each_entry_safe(entry, n, &efivar_list, list) { 765 spin_lock(&efivars_lock); 766 list_del(&entry->list); 767 spin_unlock(&efivars_lock); 768 efivar_unregister(entry); 769 } 770 771 subsystem_unregister(&vars_subsys); 772 firmware_unregister(&efi_subsys); 773} 774 775module_init(efivars_init); 776module_exit(efivars_exit); 777