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.
- 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/init.hlinux/io.hlinux/debugfs.hlinux/seq_file.hlinux/nmi.hlinux/delay.hlinux/mm.hlinux/device/faux.hlinux/unaligned.hapei-internal.h
Detected Declarations
struct syndrome_arraystruct einjv2_extension_structstruct set_error_type_with_addressstruct vendor_error_type_extensionstruct einj_parameterfunction einj_exec_ctx_initfunction __einj_get_available_error_typefunction einj_get_available_error_typefunction einj_get_available_error_typesfunction einj_timedoutfunction get_oem_vendor_structfunction check_vendor_extensionfunction einjv2_initfunction einj_check_trigger_headerfunction is_memory_injectionfunction __einj_error_triggerfunction is_end_of_listfunction __einj_error_injectfunction is_allowed_rangefunction einj_error_injectfunction einj_cxl_rch_error_injectfunction available_error_type_showfunction error_type_getfunction einj_is_cxl_error_typefunction einj_validate_error_typefunction error_type_setfunction error_inject_setfunction einj_check_tablefunction u128_readfunction u128_writefunction setup_einjv2_component_filesfunction einj_probefunction einj_removefunction einj_initfunction einj_exitmodule init einj_init
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
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/init.h`, `linux/io.h`, `linux/debugfs.h`, `linux/seq_file.h`, `linux/nmi.h`, `linux/delay.h`.
- Detected declarations: `struct syndrome_array`, `struct einjv2_extension_struct`, `struct set_error_type_with_address`, `struct vendor_error_type_extension`, `struct einj_parameter`, `function einj_exec_ctx_init`, `function __einj_get_available_error_type`, `function einj_get_available_error_type`, `function einj_get_available_error_types`, `function einj_timedout`.
- Atlas domain: Driver Families / drivers/acpi.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.