static int __init erst_init()

in apei/erst.c [1093:1204]


static int __init erst_init(void)
{
	int rc = 0;
	acpi_status status;
	struct apei_exec_context ctx;
	struct apei_resources erst_resources;
	struct resource *r;
	char *buf;

	if (acpi_disabled)
		goto err;

	if (erst_disable) {
		pr_info(
	"Error Record Serialization Table (ERST) support is disabled.\n");
		goto err;
	}

	status = acpi_get_table(ACPI_SIG_ERST, 0,
				(struct acpi_table_header **)&erst_tab);
	if (status == AE_NOT_FOUND)
		goto err;
	else if (ACPI_FAILURE(status)) {
		const char *msg = acpi_format_exception(status);
		pr_err("Failed to get table, %s\n", msg);
		rc = -EINVAL;
		goto err;
	}

	rc = erst_check_table(erst_tab);
	if (rc) {
		pr_err(FW_BUG "ERST table is invalid.\n");
		goto err_put_erst_tab;
	}

	apei_resources_init(&erst_resources);
	erst_exec_ctx_init(&ctx);
	rc = apei_exec_collect_resources(&ctx, &erst_resources);
	if (rc)
		goto err_fini;
	rc = apei_resources_request(&erst_resources, "APEI ERST");
	if (rc)
		goto err_fini;
	rc = apei_exec_pre_map_gars(&ctx);
	if (rc)
		goto err_release;
	rc = erst_get_erange(&erst_erange);
	if (rc) {
		if (rc == -ENODEV)
			pr_info(
	"The corresponding hardware device or firmware implementation "
	"is not available.\n");
		else
			pr_err("Failed to get Error Log Address Range.\n");
		goto err_unmap_reg;
	}

	r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST");
	if (!r) {
		pr_err("Can not request [mem %#010llx-%#010llx] for ERST.\n",
		       (unsigned long long)erst_erange.base,
		       (unsigned long long)erst_erange.base + erst_erange.size - 1);
		rc = -EIO;
		goto err_unmap_reg;
	}
	rc = -ENOMEM;
	erst_erange.vaddr = ioremap_cache(erst_erange.base,
					  erst_erange.size);
	if (!erst_erange.vaddr)
		goto err_release_erange;

	pr_info(
	"Error Record Serialization Table (ERST) support is initialized.\n");

	buf = kmalloc(erst_erange.size, GFP_KERNEL);
	if (buf) {
		erst_info.buf = buf + sizeof(struct cper_pstore_record);
		erst_info.bufsize = erst_erange.size -
				    sizeof(struct cper_pstore_record);
		rc = pstore_register(&erst_info);
		if (rc) {
			if (rc != -EPERM)
				pr_info(
				"Could not register with persistent store.\n");
			erst_info.buf = NULL;
			erst_info.bufsize = 0;
			kfree(buf);
		}
	} else
		pr_err(
		"Failed to allocate %lld bytes for persistent store error log.\n",
		erst_erange.size);

	/* Cleanup ERST Resources */
	apei_resources_fini(&erst_resources);

	return 0;

err_release_erange:
	release_mem_region(erst_erange.base, erst_erange.size);
err_unmap_reg:
	apei_exec_post_unmap_gars(&ctx);
err_release:
	apei_resources_release(&erst_resources);
err_fini:
	apei_resources_fini(&erst_resources);
err_put_erst_tab:
	acpi_put_table((struct acpi_table_header *)erst_tab);
err:
	erst_disable = 1;
	return rc;
}