Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d502fbb0 authored by Mike Waychison's avatar Mike Waychison Committed by Greg Kroah-Hartman
Browse files

efivars: Make efivars bin_attributes dynamic



In preparation for encapsulating efivars, we need to have the
bin_attributes be dynamically allocated so that we can use their
->private fields to get back to the struct efivars structure.

Signed-off-by: default avatarMike Waychison <mikew@google.com>
Cc: Matt Domsch <Matt_Domsch@dell.com>,
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 29422693
Loading
Loading
Loading
Loading
+68 −25
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ struct efivars {
	spinlock_t lock;
	struct list_head list;
	struct kset *kset;
	struct bin_attribute *new_var, *del_var;
};
static struct efivars __efivars;
static struct efivars *efivars = &__efivars;
@@ -525,16 +526,6 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
	return count;
}

static struct bin_attribute var_subsys_attr_new_var = {
	.attr = {.name = "new_var", .mode = 0200},
	.write = efivar_create,
};

static struct bin_attribute var_subsys_attr_del_var = {
	.attr = {.name = "del_var", .mode = 0200},
	.write = efivar_delete,
};

/*
 * Let's not leave out systab information that snuck into
 * the efivars driver
@@ -640,6 +631,66 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,

	return 0;
}

static int
create_efivars_bin_attributes(struct efivars *efivars)
{
	struct bin_attribute *attr;
	int error;

	/* new_var */
	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
	if (!attr)
		return -ENOMEM;

	attr->attr.name = "new_var";
	attr->attr.mode = 0200;
	attr->write = efivar_create;
	attr->private = efivars;
	efivars->new_var = attr;

	/* del_var */
	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
	if (!attr) {
		error = -ENOMEM;
		goto out_free;
	}
	attr->attr.name = "del_var";
	attr->attr.mode = 0200;
	attr->write = efivar_delete;
	attr->private = efivars;
	efivars->del_var = attr;

	sysfs_bin_attr_init(efivars->new_var);
	sysfs_bin_attr_init(efivars->del_var);

	/* Register */
	error = sysfs_create_bin_file(&efivars->kset->kobj,
				      efivars->new_var);
	if (error) {
		printk(KERN_ERR "efivars: unable to create new_var sysfs file"
			" due to error %d\n", error);
		goto out_free;
	}
	error = sysfs_create_bin_file(&efivars->kset->kobj,
				      efivars->del_var);
	if (error) {
		printk(KERN_ERR "efivars: unable to create del_var sysfs file"
			" due to error %d\n", error);
		sysfs_remove_bin_file(&efivars->kset->kobj,
				      efivars->new_var);
		goto out_free;
	}

	return 0;
out_free:
	kfree(efivars->new_var);
	efivars->new_var = NULL;
	kfree(efivars->new_var);
	efivars->new_var = NULL;
	return error;
}

/*
 * For now we register the efi subsystem with the firmware subsystem
 * and the vars subsystem with the efi subsystem.  In the future, it
@@ -714,20 +765,7 @@ efivars_init(void)
		}
	} while (status != EFI_NOT_FOUND);

	/*
	 * Now add attributes to allow creation of new vars
	 * and deletion of existing ones...
	 */
	error = sysfs_create_bin_file(&efivars->kset->kobj,
				      &var_subsys_attr_new_var);
	if (error)
		printk(KERN_ERR "efivars: unable to create new_var sysfs file"
			" due to error %d\n", error);
	error = sysfs_create_bin_file(&efivars->kset->kobj,
				      &var_subsys_attr_del_var);
	if (error)
		printk(KERN_ERR "efivars: unable to create del_var sysfs file"
			" due to error %d\n", error);
	error = create_efivars_bin_attributes(efivars);

	/* Don't forget the systab entry */
	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
@@ -758,7 +796,12 @@ efivars_exit(void)
		spin_unlock(&efivars->lock);
		efivar_unregister(entry);
	}

	if (efivars->new_var)
		sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
	if (efivars->del_var)
		sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
	kfree(efivars->new_var);
	kfree(efivars->del_var);
	kset_unregister(efivars->kset);
	kobject_put(efi_kobj);
}