⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 efivars.c

📁 对于那些带有区码限制的DVD光驱
💻 C
📖 第 1 页 / 共 2 页
字号:
	list_del(&var->list);	spin_unlock(&efivars_lock);	kfree(var);}static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);static struct attribute *def_attrs[] = {	&efivar_attr_guid.attr,	&efivar_attr_size.attr,	&efivar_attr_attributes.attr,	&efivar_attr_data.attr,	&efivar_attr_raw_var.attr,	NULL,};static struct kobj_type ktype_efivar = {	.release = efivar_release,	.sysfs_ops = &efivar_attr_ops,	.default_attrs = def_attrs,};static ssize_tdummy(struct subsystem *sub, char *buf){	return -ENODEV;}static inline voidefivar_unregister(struct efivar_entry *var){	kobject_unregister(&var->kobj);}static ssize_tefivar_create(struct subsystem *sub, const char *buf, size_t count){	struct efi_variable *new_var = (struct efi_variable *)buf;	struct efivar_entry *search_efivar = NULL;	unsigned long strsize1, strsize2;	struct list_head *pos, *n;	efi_status_t status = EFI_NOT_FOUND;	int found = 0;	if (!capable(CAP_SYS_ADMIN))		return -EACCES;	spin_lock(&efivars_lock);	/*	 * Does this variable already exist?	 */	list_for_each_safe(pos, n, &efivar_list) {		search_efivar = get_efivar_entry(pos);		strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);		strsize2 = utf8_strsize(new_var->VariableName, 1024);		if (strsize1 == strsize2 &&			!memcmp(&(search_efivar->var.VariableName),				new_var->VariableName, strsize1) &&			!efi_guidcmp(search_efivar->var.VendorGuid,				new_var->VendorGuid)) {			found = 1;			break;		}	}	if (found) {		spin_unlock(&efivars_lock);		return -EINVAL;	}	/* now *really* create the variable via EFI */	status = efi.set_variable(new_var->VariableName,			&new_var->VendorGuid,			new_var->Attributes,			new_var->DataSize,			new_var->Data);	if (status != EFI_SUCCESS) {		printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",			status);		spin_unlock(&efivars_lock);		return -EIO;	}	spin_unlock(&efivars_lock);	/* Create the entry in sysfs.  Locking is not required here */	status = efivar_create_sysfs_entry(utf8_strsize(new_var->VariableName,			1024), new_var->VariableName, &new_var->VendorGuid);	if (status) {		printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");	}	return count;}static ssize_tefivar_delete(struct subsystem *sub, const char *buf, size_t count){	struct efi_variable *del_var = (struct efi_variable *)buf;	struct efivar_entry *search_efivar = NULL;	unsigned long strsize1, strsize2;	struct list_head *pos, *n;	efi_status_t status = EFI_NOT_FOUND;	int found = 0;	if (!capable(CAP_SYS_ADMIN))		return -EACCES;	spin_lock(&efivars_lock);	/*	 * Does this variable already exist?	 */	list_for_each_safe(pos, n, &efivar_list) {		search_efivar = get_efivar_entry(pos);		strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);		strsize2 = utf8_strsize(del_var->VariableName, 1024);		if (strsize1 == strsize2 &&			!memcmp(&(search_efivar->var.VariableName),				del_var->VariableName, strsize1) &&			!efi_guidcmp(search_efivar->var.VendorGuid,				del_var->VendorGuid)) {			found = 1;			break;		}	}	if (!found) {		spin_unlock(&efivars_lock);		return -EINVAL;	}	/* force the Attributes/DataSize to 0 to ensure deletion */	del_var->Attributes = 0;	del_var->DataSize = 0;	status = efi.set_variable(del_var->VariableName,			&del_var->VendorGuid,			del_var->Attributes,			del_var->DataSize,			del_var->Data);	if (status != EFI_SUCCESS) {		printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",			status);		spin_unlock(&efivars_lock);		return -EIO;	}	/* We need to release this lock before unregistering. */	spin_unlock(&efivars_lock);	efivar_unregister(search_efivar);	/* It's dead Jim.... */	return count;}static VAR_SUBSYS_ATTR(new_var, 0200, dummy, efivar_create);static VAR_SUBSYS_ATTR(del_var, 0200, dummy, efivar_delete);static struct subsys_attribute *var_subsys_attrs[] = {	&var_subsys_attr_new_var,	&var_subsys_attr_del_var,	NULL,};/* * Let's not leave out systab information that snuck into * the efivars driver */static ssize_tsystab_read(struct subsystem *entry, char *buf){	char *str = buf;	if (!entry || !buf)		return -EINVAL;	if (efi.mps)		str += sprintf(str, "MPS=0x%lx\n", __pa(efi.mps));	if (efi.acpi20)		str += sprintf(str, "ACPI20=0x%lx\n", __pa(efi.acpi20));	if (efi.acpi)		str += sprintf(str, "ACPI=0x%lx\n", __pa(efi.acpi));	if (efi.smbios)		str += sprintf(str, "SMBIOS=0x%lx\n", __pa(efi.smbios));	if (efi.hcdp)		str += sprintf(str, "HCDP=0x%lx\n", __pa(efi.hcdp));	if (efi.boot_info)		str += sprintf(str, "BOOTINFO=0x%lx\n", __pa(efi.boot_info));	if (efi.uga)		str += sprintf(str, "UGA=0x%lx\n", __pa(efi.uga));	return str - buf;}static EFI_ATTR(systab, 0400, systab_read, NULL);static struct subsys_attribute *efi_subsys_attrs[] = {	&efi_attr_systab,	NULL,	/* maybe more in the future? */};static decl_subsys(vars, &ktype_efivar, NULL);static decl_subsys(efi, NULL, NULL);/* * efivar_create_sysfs_entry() * Requires: *    variable_name_size = number of bytes required to hold *                         variable_name (not counting the NULL *                         character at the end. *    efivars_lock is not held on entry or exit. * Returns 1 on failure, 0 on success */static intefivar_create_sysfs_entry(unsigned long variable_name_size,			efi_char16_t *variable_name,			efi_guid_t *vendor_guid){	int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;	char *short_name;	struct efivar_entry *new_efivar;	short_name = kzalloc(short_name_size + 1, GFP_KERNEL);	new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);	if (!short_name || !new_efivar)  {		kfree(short_name);		kfree(new_efivar);		return 1;	}	memcpy(new_efivar->var.VariableName, variable_name,		variable_name_size);	memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));	/* Convert Unicode to normal chars (assume top bits are 0),	   ala UTF-8 */	for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {		short_name[i] = variable_name[i] & 0xFF;	}	/* This is ugly, but necessary to separate one vendor's	   private variables from another's.         */	*(short_name + strlen(short_name)) = '-';	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));	kobject_set_name(&new_efivar->kobj, "%s", short_name);	kobj_set_kset_s(new_efivar, vars_subsys);	kobject_register(&new_efivar->kobj);	kfree(short_name);	short_name = NULL;	spin_lock(&efivars_lock);	list_add(&new_efivar->list, &efivar_list);	spin_unlock(&efivars_lock);	return 0;}/* * For now we register the efi subsystem with the firmware subsystem * and the vars subsystem with the efi subsystem.  In the future, it * might make sense to split off the efi subsystem into its own * driver, but for now only efivars will register with it, so just * include it here. */static int __initefivars_init(void){	efi_status_t status = EFI_NOT_FOUND;	efi_guid_t vendor_guid;	efi_char16_t *variable_name;	struct subsys_attribute *attr;	unsigned long variable_name_size = 1024;	int i, error = 0;	if (!efi_enabled)		return -ENODEV;	variable_name = kzalloc(variable_name_size, GFP_KERNEL);	if (!variable_name) {		printk(KERN_ERR "efivars: Memory allocation failed.\n");		return -ENOMEM;	}	printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,	       EFIVARS_DATE);	/*	 * For now we'll register the efi subsys within this driver	 */	error = firmware_register(&efi_subsys);	if (error) {		printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error);		goto out_free;	}	kset_set_kset_s(&vars_subsys, efi_subsys);	error = subsystem_register(&vars_subsys);	if (error) {		printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error);		goto out_firmware_unregister;	}	/*	 * Per EFI spec, the maximum storage allocated for both	 * the variable name and variable data is 1024 bytes.	 */	do {		variable_name_size = 1024;		status = efi.get_next_variable(&variable_name_size,						variable_name,						&vendor_guid);		switch (status) {		case EFI_SUCCESS:			efivar_create_sysfs_entry(variable_name_size,							variable_name,							&vendor_guid);			break;		case EFI_NOT_FOUND:			break;		default:			printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",				status);			status = EFI_NOT_FOUND;			break;		}	} while (status != EFI_NOT_FOUND);	/*	 * Now add attributes to allow creation of new vars	 * and deletion of existing ones...	 */	for (i = 0; (attr = var_subsys_attrs[i]) && !error; i++) {		if (attr->show && attr->store)			error = subsys_create_file(&vars_subsys, attr);	}	/* Don't forget the systab entry */	for (i = 0; (attr = efi_subsys_attrs[i]) && !error; i++) {		if (attr->show)			error = subsys_create_file(&efi_subsys, attr);	}	if (error)		printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error);	else		goto out_free;	subsystem_unregister(&vars_subsys);out_firmware_unregister:	firmware_unregister(&efi_subsys);out_free:	kfree(variable_name);	return error;}static void __exitefivars_exit(void){	struct list_head *pos, *n;	list_for_each_safe(pos, n, &efivar_list)		efivar_unregister(get_efivar_entry(pos));	subsystem_unregister(&vars_subsys);	firmware_unregister(&efi_subsys);}module_init(efivars_init);module_exit(efivars_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -