drivers/acpi/apei/bert.c

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

File Facts

System
Linux kernel
Corpus path
drivers/acpi/apei/bert.c
Extension
.c
Size
4592 bytes
Lines
175
Domain
Driver Families
Bucket
drivers/acpi
Inferred role
Driver Families: implementation source
Status
source 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

if (remain < estatus_len) {
			pr_err(FW_BUG "Truncated status block (length: %u).\n",
			       estatus_len);
			break;
		}

		/* No more error records. */
		if (!estatus->block_status)
			break;

		if (cper_estatus_check(estatus)) {
			pr_err(FW_BUG "Invalid error record.\n");
			break;
		}

		if (estatus_len < ACPI_BERT_PRINT_MAX_LEN &&
		    printed < ACPI_BERT_PRINT_MAX_RECORDS) {
			pr_info_once("Error records from previous boot:\n");
			cper_estatus_print(KERN_INFO HW_ERR, estatus);
			printed++;
		} else {
			skipped++;
		}

		/*
		 * Because the boot error source is "one-time polled" type,
		 * clear Block Status of current Generic Error Status Block,
		 * once it's printed.
		 */
		estatus->block_status = 0;

		estatus = (void *)estatus + estatus_len;
		remain -= estatus_len;
	}

	if (skipped)
		pr_info(HW_ERR "Skipped %d error records\n", skipped);

	if (printed + skipped)
		pr_info("Total records found: %d\n", printed + skipped);
}

static int __init setup_bert_disable(char *str)
{
	bert_disable = 1;

	return 1;
}
__setup("bert_disable", setup_bert_disable);

static int __init bert_check_table(struct acpi_table_bert *bert_tab)
{
	if (bert_tab->header.length < sizeof(struct acpi_table_bert) ||
	    bert_tab->region_length < sizeof(struct acpi_bert_region))
		return -EINVAL;

	return 0;
}

static int __init bert_init(void)
{
	struct apei_resources bert_resources;
	struct acpi_bert_region *boot_error_region;
	struct acpi_table_bert *bert_tab;
	unsigned int region_len;
	acpi_status status;
	int rc = 0;

	if (acpi_disabled)
		return 0;

	if (bert_disable) {
		pr_info("Boot Error Record Table support is disabled.\n");
		return 0;
	}

	status = acpi_get_table(ACPI_SIG_BERT, 0, (struct acpi_table_header **)&bert_tab);
	if (status == AE_NOT_FOUND)
		return 0;

	if (ACPI_FAILURE(status)) {
		pr_err("get table failed, %s.\n", acpi_format_exception(status));
		return -EINVAL;
	}

	rc = bert_check_table(bert_tab);
	if (rc) {
		pr_err(FW_BUG "table invalid.\n");
		goto out_put_bert_tab;
	}

Annotation

Implementation Notes