1
0
Fork 0

ACPI / einj: Make error paths more talkative

It is absolutely unfriendly when one sees this:

  # modprobe einj
  modprobe: ERROR: could not insert 'einj': No such device

without anything in dmesg to tell one why the load failed.

Beef up the error handling of the init function to be more user-friendly
when the load fails.

Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
steinar/wifi_calib_4_9_kernel
Borislav Petkov 2016-05-23 10:28:04 +02:00 committed by Rafael J. Wysocki
parent b2f740baa4
commit dba648300e
1 changed files with 27 additions and 9 deletions

View File

@ -692,34 +692,42 @@ static int __init einj_init(void)
struct dentry *fentry; struct dentry *fentry;
struct apei_exec_context ctx; struct apei_exec_context ctx;
if (acpi_disabled) if (acpi_disabled) {
pr_warn("ACPI disabled.\n");
return -ENODEV; return -ENODEV;
}
status = acpi_get_table(ACPI_SIG_EINJ, 0, status = acpi_get_table(ACPI_SIG_EINJ, 0,
(struct acpi_table_header **)&einj_tab); (struct acpi_table_header **)&einj_tab);
if (status == AE_NOT_FOUND) if (status == AE_NOT_FOUND) {
pr_warn("EINJ table not found.\n");
return -ENODEV; return -ENODEV;
}
else if (ACPI_FAILURE(status)) { else if (ACPI_FAILURE(status)) {
const char *msg = acpi_format_exception(status); pr_err("Failed to get EINJ table: %s\n",
pr_err("Failed to get table, %s\n", msg); acpi_format_exception(status));
return -EINVAL; return -EINVAL;
} }
rc = einj_check_table(einj_tab); rc = einj_check_table(einj_tab);
if (rc) { if (rc) {
pr_warning(FW_BUG "EINJ table is invalid\n"); pr_warn(FW_BUG "Invalid EINJ table.n");
return -EINVAL; return -EINVAL;
} }
rc = -ENOMEM; rc = -ENOMEM;
einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir()); einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());
if (!einj_debug_dir) if (!einj_debug_dir) {
pr_err("Error creating debugfs node.\n");
goto err_cleanup; goto err_cleanup;
}
fentry = debugfs_create_file("available_error_type", S_IRUSR, fentry = debugfs_create_file("available_error_type", S_IRUSR,
einj_debug_dir, NULL, einj_debug_dir, NULL,
&available_error_type_fops); &available_error_type_fops);
if (!fentry) if (!fentry)
goto err_cleanup; goto err_cleanup;
fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR, fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR,
einj_debug_dir, NULL, &error_type_fops); einj_debug_dir, NULL, &error_type_fops);
if (!fentry) if (!fentry)
@ -732,14 +740,22 @@ static int __init einj_init(void)
apei_resources_init(&einj_resources); apei_resources_init(&einj_resources);
einj_exec_ctx_init(&ctx); einj_exec_ctx_init(&ctx);
rc = apei_exec_collect_resources(&ctx, &einj_resources); rc = apei_exec_collect_resources(&ctx, &einj_resources);
if (rc) if (rc) {
pr_err("Error collecting EINJ resources.\n");
goto err_fini; goto err_fini;
}
rc = apei_resources_request(&einj_resources, "APEI EINJ"); rc = apei_resources_request(&einj_resources, "APEI EINJ");
if (rc) if (rc) {
pr_err("Error requesting memory/port resources.\n");
goto err_fini; goto err_fini;
}
rc = apei_exec_pre_map_gars(&ctx); rc = apei_exec_pre_map_gars(&ctx);
if (rc) if (rc) {
pr_err("Error pre-mapping GARs.\n");
goto err_release; goto err_release;
}
rc = -ENOMEM; rc = -ENOMEM;
einj_param = einj_get_parameter_address(); einj_param = einj_get_parameter_address();
@ -795,6 +811,7 @@ err_unmap:
sizeof(struct einj_parameter); sizeof(struct einj_parameter);
acpi_os_unmap_iomem(einj_param, size); acpi_os_unmap_iomem(einj_param, size);
pr_err("Error creating param extension debugfs nodes.\n");
} }
apei_exec_post_unmap_gars(&ctx); apei_exec_post_unmap_gars(&ctx);
err_release: err_release:
@ -802,6 +819,7 @@ err_release:
err_fini: err_fini:
apei_resources_fini(&einj_resources); apei_resources_fini(&einj_resources);
err_cleanup: err_cleanup:
pr_err("Error creating primary debugfs nodes.\n");
debugfs_remove_recursive(einj_debug_dir); debugfs_remove_recursive(einj_debug_dir);
return rc; return rc;