Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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