drivers/firmware/efi/vars.c

Source file repositories/reference/linux-study-clean/drivers/firmware/efi/vars.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/efi/vars.c
Extension
.c
Size
6246 bytes
Lines
268
Domain
Driver Families
Bucket
drivers/firmware
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0+
/*
 * Originally from efivars.c
 *
 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
 */

#define pr_fmt(fmt) "efivars: " fmt

#include <linux/types.h>
#include <linux/sizes.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/smp.h>
#include <linux/efi.h>
#include <linux/ucs2_string.h>

/* Private pointer to registered efivars */
static struct efivars *__efivars;

static DEFINE_SEMAPHORE(efivars_lock, 1);

static efi_status_t check_var_size(bool nonblocking, u32 attributes,
				   unsigned long size)
{
	const struct efivar_operations *fops;
	efi_status_t status;

	fops = __efivars->ops;

	if (!fops->query_variable_store)
		status = EFI_UNSUPPORTED;
	else
		status = fops->query_variable_store(attributes, size,
						    nonblocking);
	if (status == EFI_UNSUPPORTED)
		return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
	return status;
}

/**
 * efivar_is_available - check if efivars is available
 *
 * @return true iff evivars is currently registered
 */
bool efivar_is_available(void)
{
	return __efivars != NULL;
}
EXPORT_SYMBOL_GPL(efivar_is_available);

/**
 * efivars_register - register an efivars
 * @efivars: efivars to register
 * @ops: efivars operations
 *
 * Only a single efivars can be registered at any time.
 */
int efivars_register(struct efivars *efivars,
		     const struct efivar_operations *ops)
{
	int rv;
	int event;

	if (down_interruptible(&efivars_lock))
		return -EINTR;

	if (__efivars) {
		pr_warn("efivars already registered\n");
		rv = -EBUSY;
		goto out;
	}

	efivars->ops = ops;

	__efivars = efivars;

	if (efivar_supports_writes())
		event = EFIVAR_OPS_RDWR;
	else
		event = EFIVAR_OPS_RDONLY;

	blocking_notifier_call_chain(&efivar_ops_nh, event, NULL);

	pr_info("Registered efivars operations\n");
	rv = 0;
out:

Annotation

Implementation Notes