diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c --- a/sys/amd64/acpica/acpi_wakeup.c +++ b/sys/amd64/acpica/acpi_wakeup.c @@ -218,7 +218,8 @@ WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t, pcb->pcb_gdt.rd_base); /* Call ACPICA to enter the desired sleep state */ - if (state == ACPI_STATE_S4 && sc->acpi_s4bios) + if (state == ACPI_STATE_S4 && + acpi_S4_should_firmware_initiate(sc)) status = AcpiEnterSleepStateS4bios(); else status = AcpiEnterSleepState(state); diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -631,7 +631,11 @@ "sleep delay in seconds"); SYSCTL_ADD_BOOL(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "s4bios", CTLFLAG_RW, &sc->acpi_s4bios, 0, - "When hibernating, have the firmware save the machine state (S4BIOS)."); + "When hibernating, have the firmware save the machine state (S4BIOS), " + "if supported."); + SYSCTL_ADD_BOOL(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), + OID_AUTO, "s4bios_supported", CTLFLAG_RD, &sc->acpi_s4bios_supported, 0, + "Whether firmware supports saving the machine state (S4BIOS)."); SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "verbose", CTLFLAG_RW, &sc->acpi_verbose, 0, "verbose mode"); SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), @@ -673,7 +677,7 @@ /* Only enable S4BIOS by default if the FACS says it is available. */ if (AcpiGbl_FACS != NULL && AcpiGbl_FACS->Flags & ACPI_FACS_S4_BIOS_PRESENT) - sc->acpi_s4bios = true; + sc->acpi_s4bios = sc->acpi_s4bios_supported = true; /* * Probe all supported ACPI sleep states. Awake (S0) is always supported. diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -65,6 +65,7 @@ int acpi_standby_sx; bool acpi_s4bios; + bool acpi_s4bios_supported; int acpi_sleep_delay; int acpi_do_disable; @@ -527,6 +528,12 @@ return (strs[state]); } +static __inline bool +acpi_S4_should_firmware_initiate(struct acpi_softc *sc) +{ + return (sc->acpi_s4bios_supported && sc->acpi_s4bios); +} + char *acpi_name(ACPI_HANDLE handle); int acpi_avoid(ACPI_HANDLE handle); int acpi_disabled(char *subsys); diff --git a/sys/i386/acpica/acpi_wakeup.c b/sys/i386/acpica/acpi_wakeup.c --- a/sys/i386/acpica/acpi_wakeup.c +++ b/sys/i386/acpica/acpi_wakeup.c @@ -240,7 +240,8 @@ pmap_remap_lowptdi(true); /* Call ACPICA to enter the desired sleep state */ - if (state == ACPI_STATE_S4 && sc->acpi_s4bios) + if (state == ACPI_STATE_S4 && + acpi_S4_should_firmware_initiate(sc)) status = AcpiEnterSleepStateS4bios(); else status = AcpiEnterSleepState(state);