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