} __attribute__((packed));
struct efivar_entry {
- struct efivars *efivars;
struct efi_variable var;
struct list_head list;
struct kobject kobj;
ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
};
-static struct efivars __efivars;
-static struct efivar_operations ops;
+/* Private pointer to registered efivars */
+static struct efivars *__efivars;
#define PSTORE_EFI_ATTRIBUTES \
(EFI_VARIABLE_NON_VOLATILE | \
if (!entry || !buf)
return -EINVAL;
- status = get_var_data(entry->efivars, var);
+ status = get_var_data(__efivars, var);
if (status != EFI_SUCCESS)
return -EIO;
if (!entry || !buf)
return -EINVAL;
- status = get_var_data(entry->efivars, var);
+ status = get_var_data(__efivars, var);
if (status != EFI_SUCCESS)
return -EIO;
if (!entry || !buf)
return -EINVAL;
- status = get_var_data(entry->efivars, var);
+ status = get_var_data(__efivars, var);
if (status != EFI_SUCCESS)
return -EIO;
efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
{
struct efi_variable *new_var, *var = &entry->var;
- struct efivars *efivars = entry->efivars;
+ struct efivars *efivars = __efivars;
efi_status_t status = EFI_NOT_FOUND;
if (count != sizeof(struct efi_variable))
if (!entry || !buf)
return 0;
- status = get_var_data(entry->efivars, var);
+ status = get_var_data(__efivars, var);
if (status != EFI_SUCCESS)
return -EIO;
const char __user *userbuf, size_t count, loff_t *ppos)
{
struct efivar_entry *var = file->private_data;
- struct efivars *efivars;
+ struct efivars *efivars = __efivars;
efi_status_t status;
void *data;
u32 attributes;
if (attributes & ~(EFI_VARIABLE_MASK))
return -EINVAL;
- efivars = var->efivars;
-
/*
* Ensure that the user can't allocate arbitrarily large
* amounts of memory. Pick a default size of 64K if
size_t count, loff_t *ppos)
{
struct efivar_entry *var = file->private_data;
- struct efivars *efivars = var->efivars;
+ struct efivars *efivars = __efivars;
efi_status_t status;
unsigned long datasize = 0;
u32 attributes;
umode_t mode, bool excl)
{
struct inode *inode;
- struct efivars *efivars = &__efivars;
+ struct efivars *efivars = __efivars;
struct efivar_entry *var;
int namelen, i = 0, err = 0;
var->var.VariableName[i] = '\0';
inode->i_private = var;
- var->efivars = efivars;
var->kobj.kset = efivars->kset;
err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s",
static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
{
struct efivar_entry *var = dentry->d_inode->i_private;
- struct efivars *efivars = var->efivars;
+ struct efivars *efivars = __efivars;
efi_status_t status;
spin_lock_irq(&efivars->lock);
struct inode *inode = NULL;
struct dentry *root;
struct efivar_entry *entry, *n;
- struct efivars *efivars = &__efivars;
+ struct efivars *efivars = __efivars;
char *name;
int err = -ENOMEM;
static int efi_pstore_open(struct pstore_info *psi)
{
- struct efivars *efivars = psi->data;
+ struct efivars *efivars = __efivars;
spin_lock_irq(&efivars->lock);
efivars->walk_entry = list_first_entry(&efivars->list,
static int efi_pstore_close(struct pstore_info *psi)
{
- struct efivars *efivars = psi->data;
+ struct efivars *efivars = __efivars;
spin_unlock_irq(&efivars->lock);
return 0;
char **buf, struct pstore_info *psi)
{
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
- struct efivars *efivars = psi->data;
+ struct efivars *efivars = __efivars;
char name[DUMP_NAME_LEN];
int i;
int cnt;
char name[DUMP_NAME_LEN];
efi_char16_t efi_name[DUMP_NAME_LEN];
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
- struct efivars *efivars = psi->data;
+ struct efivars *efivars = __efivars;
int i, ret = 0;
efi_status_t status = EFI_NOT_FOUND;
unsigned long flags;
char name_old[DUMP_NAME_LEN];
efi_char16_t efi_name_old[DUMP_NAME_LEN];
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
- struct efivars *efivars = psi->data;
+ struct efivars *efivars = __efivars;
struct efivar_entry *entry, *found = NULL;
int i;
char *buf, loff_t pos, size_t count)
{
struct efi_variable *new_var = (struct efi_variable *)buf;
- struct efivars *efivars = bin_attr->private;
+ struct efivars *efivars = __efivars;
struct efivar_entry *search_efivar, *n;
unsigned long strsize1, strsize2;
efi_status_t status = EFI_NOT_FOUND;
char *buf, loff_t pos, size_t count)
{
struct efi_variable *del_var = (struct efi_variable *)buf;
- struct efivars *efivars = bin_attr->private;
+ struct efivars *efivars = __efivars;
struct efivar_entry *search_efivar, *n;
unsigned long strsize1, strsize2;
efi_status_t status = EFI_NOT_FOUND;
static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
{
struct efivar_entry *entry, *n;
- struct efivars *efivars = &__efivars;
+ struct efivars *efivars = __efivars;
unsigned long strsize1, strsize2;
bool found = false;
static void efivar_update_sysfs_entries(struct work_struct *work)
{
- struct efivars *efivars = &__efivars;
+ struct efivars *efivars = __efivars;
efi_guid_t vendor;
efi_char16_t *variable_name;
unsigned long variable_name_size = 1024;
return 1;
}
- new_efivar->efivars = efivars;
memcpy(new_efivar->var.VariableName, variable_name,
variable_name_size);
memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
{
struct efivar_entry *entry, *n;
+ __efivars = NULL;
+
list_for_each_entry_safe(entry, n, &efivars->list, list) {
spin_lock_irq(&efivars->lock);
list_del(&entry->list);
unsigned long variable_name_size = 1024;
int error = 0;
+ __efivars = efivars;
+
variable_name = kzalloc(variable_name_size, GFP_KERNEL);
if (!variable_name) {
printk(KERN_ERR "efivars: Memory allocation failed.\n");
}
EXPORT_SYMBOL_GPL(register_efivars);
+static struct efivars generic_efivars;
+static struct efivar_operations generic_ops;
+
+static int generic_ops_register(void)
+{
+ generic_ops.get_variable = efi.get_variable;
+ generic_ops.set_variable = efi.set_variable;
+ generic_ops.get_next_variable = efi.get_next_variable;
+ generic_ops.query_variable_info = efi.query_variable_info;
+
+ return register_efivars(&generic_efivars, &generic_ops, efi_kobj);
+}
+
+static void generic_ops_unregister(void)
+{
+ unregister_efivars(&generic_efivars);
+}
+
/*
* For now we register the efi subsystem with the firmware subsystem
* and the vars subsystem with the efi subsystem. In the future, it
return -ENOMEM;
}
- ops.get_variable = efi.get_variable;
- ops.set_variable = efi.set_variable;
- ops.get_next_variable = efi.get_next_variable;
- ops.query_variable_info = efi.query_variable_info;
-
- error = register_efivars(&__efivars, &ops, efi_kobj);
+ error = generic_ops_register();
if (error)
goto err_put;
return 0;
err_unregister:
- unregister_efivars(&__efivars);
+ generic_ops_unregister();
err_put:
kobject_put(efi_kobj);
return error;
cancel_work_sync(&efivar_work);
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
- unregister_efivars(&__efivars);
+ generic_ops_unregister();
kobject_put(efi_kobj);
}
}