Exemplo n.º 1
0
Arquivo: erst.c Projeto: bpopovych/xen
int __init erst_init(void)
{
	int rc = 0;
	acpi_status status;
	struct apei_exec_context ctx;

	if (acpi_disabled)
		return -ENODEV;

	status = acpi_get_table(ACPI_SIG_ERST, 0,
				(struct acpi_table_header **)&erst_tab);
	if (status == AE_NOT_FOUND) {
		printk(KERN_INFO "ERST table was not found\n");
		return -ENODEV;
	} else if (ACPI_FAILURE(status)) {
		const char *msg = acpi_format_exception(status);
		printk(KERN_WARNING "Failed to get ERST table: %s\n", msg);
		return -EINVAL;
	}

	rc = erst_check_table(erst_tab);
	if (rc) {
		printk(KERN_ERR "ERST table is invalid\n");
		return rc;
	}

	erst_exec_ctx_init(&ctx);
	rc = apei_exec_pre_map_gars(&ctx);
	if (rc)
		return rc;

	rc = erst_get_erange(&erst_erange);
	if (rc) {
		if (rc == -ENODEV)
			printk(KERN_INFO
			"The corresponding hardware device or firmware "
			"implementation is not available.\n");
		else
			printk(KERN_ERR
			       "Failed to get Error Log Address Range.\n");
		goto err_unmap_reg;
	}

	erst_erange.vaddr = apei_pre_map(erst_erange.base, erst_erange.size);
	if (!erst_erange.vaddr) {
		rc = -ENOMEM;
		goto err_unmap_reg;
	}

	printk(KERN_INFO "Xen ERST support is initialized.\n");
	erst_enabled = 1;

	return 0;

err_unmap_reg:
	apei_exec_post_unmap_gars(&ctx);
	return rc;
}
Exemplo n.º 2
0
/*
 * Pre-map all GARs in action table to make it possible to access them
 * in NMI handler.
 */
int apei_exec_pre_map_gars(struct apei_exec_context *ctx)
{
	int rc, end;

	rc = apei_exec_for_each_entry(ctx, pre_map_gar_callback,
				      NULL, &end);
	if (rc) {
		struct apei_exec_context ctx_unmap;
		memcpy(&ctx_unmap, ctx, sizeof(*ctx));
		ctx_unmap.entries = end;
		apei_exec_post_unmap_gars(&ctx_unmap);
	}

	return rc;
}
Exemplo n.º 3
0
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;

    if (acpi_disabled)
        goto err;

    if (erst_disable) {
        pr_info(ERST_PFX
                "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) {
        pr_info(ERST_PFX "Table is not found!\n");
        goto err;
    } else if (ACPI_FAILURE(status)) {
        const char *msg = acpi_format_exception(status);
        pr_err(ERST_PFX "Failed to get table, %s\n", msg);
        rc = -EINVAL;
        goto err;
    }

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

    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(ERST_PFX
                    "The corresponding hardware device or firmware implementation "
                    "is not available.\n");
        else
            pr_err(ERST_PFX
                   "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(ERST_PFX
               "Can not request iomem region <0x%16llx-0x%16llx> for ERST.\n",
               (unsigned long long)erst_erange.base,
               (unsigned long long)erst_erange.base + erst_erange.size);
        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(ERST_PFX
            "Error Record Serialization Table (ERST) support is initialized.\n");

    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:
    erst_disable = 1;
    return rc;
}