static int erst_exec_stall_while_true(struct apei_exec_context *ctx, struct acpi_whea_header *entry) { int rc; u64 val; u64 timeout = FIRMWARE_TIMEOUT; u64 stall_time; if (ctx->var1 > FIRMWARE_MAX_STALL) { if (!in_nmi()) pr_warn(FW_WARN "Too long stall time for stall while true instruction: 0x%llx.\n", ctx->var1); stall_time = FIRMWARE_MAX_STALL; } else stall_time = ctx->var1; for (;;) { rc = __apei_exec_read_register(entry, &val); if (rc) return rc; if (val != ctx->value) break; if (erst_timedout(&timeout, stall_time * NSEC_PER_USEC)) return -EIO; } return 0; }
static int __erst_read_from_storage(u64 record_id, u64 offset) { struct apei_exec_context ctx; u64 timeout = FIRMWARE_TIMEOUT; u64 val; int rc; erst_exec_ctx_init(&ctx); rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ); if (rc) return rc; apei_exec_ctx_set_input(&ctx, offset); rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); if (rc) return rc; apei_exec_ctx_set_input(&ctx, record_id); rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); if (rc) return rc; rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); if (rc) return rc; for (;;) { rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); if (rc) return rc; val = apei_exec_ctx_get_output(&ctx); if (!val) break; if (erst_timedout(&timeout, SPIN_UNIT)) return -EIO; }; rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); if (rc) return rc; val = apei_exec_ctx_get_output(&ctx); rc = apei_exec_run(&ctx, ACPI_ERST_END); if (rc) return rc; return erst_errno(val); }
static int erst_exec_stall_while_true(struct apei_exec_context *ctx, struct acpi_whea_header *entry) { int rc; u64 val; u64 timeout = FIRMWARE_TIMEOUT; u64 stall_time = (ctx->var1 > FIRMWARE_MAX_STALL) ? FIRMWARE_MAX_STALL : ctx->var1; for (;;) { rc = __apei_exec_read_register(entry, &val); if (rc) return rc; if (val != ctx->value) break; if (erst_timedout(&timeout, stall_time)) return -EIO; } return 0; }