drivers/acpi/apei/einj-core.c

Source file repositories/reference/linux-study-clean/drivers/acpi/apei/einj-core.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/apei/einj-core.c
Extension
.c
Size
31953 bytes
Lines
1207
Domain
Driver Families
Bucket
drivers/acpi
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations error_type_fops = {
	.read		= error_type_get,
	.write		= error_type_set,
};

static int error_inject_set(void *data, u64 val)
{
	if (!error_type)
		return -EINVAL;

	if (is_v2)
		error_flags |= SETWA_FLAGS_EINJV2;
	else
		error_flags &= ~SETWA_FLAGS_EINJV2;

	return einj_error_inject(error_type, error_flags, error_param1, error_param2,
		error_param3, error_param4);
}

DEFINE_DEBUGFS_ATTRIBUTE(error_inject_fops, NULL, error_inject_set, "%llu\n");

static int einj_check_table(struct acpi_table_einj *einj_tab)
{
	if ((einj_tab->header_length !=
	     (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header)))
	    && (einj_tab->header_length != sizeof(struct acpi_table_einj)))
		return -EINVAL;
	if (einj_tab->header.length < sizeof(struct acpi_table_einj))
		return -EINVAL;
	if (einj_tab->entries !=
	    (einj_tab->header.length - sizeof(struct acpi_table_einj)) /
	    sizeof(struct acpi_einj_entry))
		return -EINVAL;

	return 0;
}

static ssize_t u128_read(struct file *f, char __user *buf, size_t count, loff_t *off)
{
	char output[2 * COMPONENT_LEN + 1];
	u8 *data = f->f_inode->i_private;
	int i;

	if (*off >= sizeof(output))
		return 0;

	for (i = 0; i < COMPONENT_LEN; i++)
		sprintf(output + 2 * i, "%.02x", data[COMPONENT_LEN - i - 1]);
	output[2 * COMPONENT_LEN] = '\n';

	return simple_read_from_buffer(buf, count, off, output, sizeof(output));
}

static ssize_t u128_write(struct file *f, const char __user *buf, size_t count, loff_t *off)
{
	char input[2 + 2 * COMPONENT_LEN + 2];
	u8 *save = f->f_inode->i_private;
	u8 tmp[COMPONENT_LEN];
	char byte[3] = {};
	char *s, *e;
	ssize_t c;
	long val;
	int i;

	/* Require that user supply whole input line in one write(2) syscall */
	if (*off)
		return -EINVAL;

	c = simple_write_to_buffer(input, sizeof(input), off, buf, count);
	if (c < 0)
		return c;

	if (c < 1 || input[c - 1] != '\n')
		return -EINVAL;

	/* Empty line means invalidate this entry */
	if (c == 1) {
		memset(save, 0xff, COMPONENT_LEN);
		return c;
	}

	if (input[0] == '0' && (input[1] == 'x' || input[1] == 'X'))
		s = input + 2;
	else
		s = input;
	e = input + c - 1;

	for (i = 0; i < COMPONENT_LEN; i++) {
		byte[1] = *--e;
		byte[0] = e > s ? *--e : '0';

Annotation

Implementation Notes