Page MenuHomeFreeBSD

D56756.id177001.diff
No OneTemporary

D56756.id177001.diff

diff --git a/sys/dev/acpica/acpi_spmc.c b/sys/dev/acpica/acpi_spmc.c
--- a/sys/dev/acpica/acpi_spmc.c
+++ b/sys/dev/acpica/acpi_spmc.c
@@ -22,60 +22,81 @@
#include <dev/acpica/acpivar.h>
+
/* Hooks for the ACPI CA debugging infrastructure */
#define _COMPONENT ACPI_SPMC
ACPI_MODULE_NAME("SPMC")
-static SYSCTL_NODE(_debug_acpi, OID_AUTO, spmc, CTLFLAG_RD | CTLFLAG_MPSAFE,
- NULL, "SPMC debugging");
-
static char *spmc_ids[] = {
"PNP0D80",
NULL
};
-enum intel_dsm_index {
- DSM_ENUM_FUNCTIONS = 0,
- DSM_GET_DEVICE_CONSTRAINTS = 1,
- DSM_GET_CRASH_DUMP_DEVICE = 2,
- DSM_DISPLAY_OFF_NOTIF = 3,
- DSM_DISPLAY_ON_NOTIF = 4,
- DSM_ENTRY_NOTIF = 5,
- DSM_EXIT_NOTIF = 6,
- /* Only for Microsoft DSM set. */
- DSM_MODERN_ENTRY_NOTIF = 7,
- DSM_MODERN_EXIT_NOTIF = 8,
- DSM_MODERN_TURN_ON_DISPLAY = 9,
-};
+/* Conversion of an index to a mask. */
+#define IDX_TO_BIT(function) (1ull << (function))
-enum amd_dsm_index {
- AMD_DSM_ENUM_FUNCTIONS = 0,
- AMD_DSM_GET_DEVICE_CONSTRAINTS = 1,
- AMD_DSM_ENTRY_NOTIF = 2,
- AMD_DSM_EXIT_NOTIF = 3,
- AMD_DSM_DISPLAY_OFF_NOTIF = 4,
- AMD_DSM_DISPLAY_ON_NOTIF = 5,
-};
+/* List of DSM UUIDs. */
+#define DSM_INTEL 0
+#define DSM_MS 1
+#define DSM_AMD 2
-enum dsm_set_flags {
- DSM_SET_INTEL = 1 << 0,
- DSM_SET_MS = 1 << 1,
- DSM_SET_AMD = 1 << 2,
-};
+/* List of DSM function indices. */
+#define DSM_ENUM_FUNCTIONS 0 /* Common to all DSMs */
+#define DSM_GET_DEVICE_CONSTRAINTS 1 /* AMD and Intel, MS N/A */
-struct dsm_set {
- enum dsm_set_flags flag;
+#define DSM_GET_CRASH_DUMP_DEVICE 2 /* Intel, MS N/A */
+#define DSM_INTEL_MS_DISPLAY_OFF_NOTIF 3
+#define DSM_INTEL_MS_DISPLAY_ON_NOTIF 4
+#define DSM_INTEL_MS_LPI_ENTRY_NOTIF 5
+#define DSM_INTEL_MS_LPI_EXIT_NOTIF 6
+
+#define DSM_MS_SLEEP_ENTRY_NOTIF 7
+#define DSM_MS_SLEEP_EXIT_NOTIF 8
+#define DSM_MS_TURN_ON_DISPLAY 9
+
+#define DSM_AMD_LPI_ENTRY_NOTIF 2
+#define DSM_AMD_LPI_EXIT_NOTIF 3
+#define DSM_AMD_DISPLAY_OFF_NOTIF 4
+#define DSM_AMD_DISPLAY_ON_NOTIF 5
+
+
+/* Descriptors for the DSMs we support. */
+
+struct dsm_desc {
const char *name;
- int revision;
- struct uuid uuid;
- uint64_t dsms_supported;
- uint64_t dsms_expected;
- uint64_t extra_dsms;
+ u_int index;
+ /*
+ * Revisions are zero or a positive number. Strictly speaking, next
+ * field should be a 'uint64_t' as per the ACPI spec, but our ACPI DSM
+ * interface takes an 'int' and anyway actual revision numbers never
+ * even exceed the limits of a 'uint8_t'.
+ */
+ int revision;
+ struct uuid uuid;
+ uint64_t required_functions;
+ uint64_t extra_functions;
+ uint64_t supported_functions;
+ /* Human-friendly names of supported functions. */
+ const char *const *function_names;
+ u_int function_names_nb;
};
-static struct dsm_set intel_dsm_set = {
- .flag = DSM_SET_INTEL,
+static const char *const dsm_intel_function_names[] = {
+ [DSM_GET_DEVICE_CONSTRAINTS] = "DEVICE_CONSTRAINTS",
+ [DSM_GET_CRASH_DUMP_DEVICE] = "CRASH_DUMP_DEVICE",
+ [DSM_INTEL_MS_DISPLAY_OFF_NOTIF] = "DISPLAY_OFF",
+ [DSM_INTEL_MS_DISPLAY_ON_NOTIF] = "DISPLAY_ON",
+ [DSM_INTEL_MS_LPI_ENTRY_NOTIF] = "LPI_ENTRY",
+ [DSM_INTEL_MS_LPI_EXIT_NOTIF] = "LPI_EXIT",
+};
+
+static struct dsm_desc dsm_intel = {
+ .index = DSM_INTEL,
.name = "Intel",
+ .uuid = { /* c4eb40a0-6cd2-11e2-bcfd-0800200c9a66 */
+ 0xc4eb40a0, 0x6cd2, 0x11e2, 0xbc, 0xfd,
+ {0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66}
+ },
/*
* XXX Linux uses 1 for the revision on Intel DSMs, but doesn't explain
* why. The commit that introduces this links to a document mentioning
@@ -85,37 +106,64 @@
* this just in case.
*/
.revision = 0,
- .uuid = { /* c4eb40a0-6cd2-11e2-bcfd-0800200c9a66 */
- 0xc4eb40a0, 0x6cd2, 0x11e2, 0xbc, 0xfd,
- {0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66},
- },
- .dsms_expected = (1 << DSM_GET_DEVICE_CONSTRAINTS) |
- (1 << DSM_DISPLAY_OFF_NOTIF) | (1 << DSM_DISPLAY_ON_NOTIF) |
- (1 << DSM_ENTRY_NOTIF) | (1 << DSM_EXIT_NOTIF),
+ .required_functions =
+ IDX_TO_BIT(DSM_GET_DEVICE_CONSTRAINTS) |
+ IDX_TO_BIT(DSM_INTEL_MS_DISPLAY_OFF_NOTIF) |
+ IDX_TO_BIT(DSM_INTEL_MS_DISPLAY_ON_NOTIF) |
+ IDX_TO_BIT(DSM_INTEL_MS_LPI_ENTRY_NOTIF) |
+ IDX_TO_BIT(DSM_INTEL_MS_LPI_EXIT_NOTIF),
+ .extra_functions =
+ IDX_TO_BIT(DSM_GET_CRASH_DUMP_DEVICE), /* Not used. */
+ .function_names = dsm_intel_function_names,
+ .function_names_nb = nitems(dsm_intel_function_names),
};
-SYSCTL_INT(_debug_acpi_spmc, OID_AUTO, intel_dsm_revision, CTLFLAG_RW,
- &intel_dsm_set.revision, 0,
- "Revision to use when evaluating Intel SPMC DSMs");
+static const char *const dsm_ms_function_names[] = {
+ [DSM_INTEL_MS_DISPLAY_OFF_NOTIF] = "DISPLAY_OFF",
+ [DSM_INTEL_MS_DISPLAY_ON_NOTIF] = "DISPLAY_ON",
+ [DSM_INTEL_MS_LPI_ENTRY_NOTIF] = "LPI_ENTRY",
+ [DSM_INTEL_MS_LPI_EXIT_NOTIF] = "LPI_EXIT",
+ [DSM_MS_SLEEP_ENTRY_NOTIF] = "SLEEP_ENTRY",
+ [DSM_MS_SLEEP_EXIT_NOTIF] = "SLEEP_EXIT",
+ [DSM_MS_TURN_ON_DISPLAY] = "TURN_ON",
+};
-static struct dsm_set ms_dsm_set = {
- .flag = DSM_SET_MS,
+static struct dsm_desc dsm_ms = {
+ .index = DSM_MS,
.name = "Microsoft",
- .revision = 0,
.uuid = { /* 11e00d56-ce64-47ce-837b-1f898f9aa461 */
0x11e00d56, 0xce64, 0x47ce, 0x83, 0x7b,
- {0x1f, 0x89, 0x8f, 0x9a, 0xa4, 0x61},
+ {0x1f, 0x89, 0x8f, 0x9a, 0xa4, 0x61}
},
- .dsms_expected = (1 << DSM_DISPLAY_OFF_NOTIF) |
- (1 << DSM_DISPLAY_ON_NOTIF) | (1 << DSM_ENTRY_NOTIF) |
- (1 << DSM_EXIT_NOTIF) | (1 << DSM_MODERN_ENTRY_NOTIF) |
- (1 << DSM_MODERN_EXIT_NOTIF),
- .extra_dsms = (1 << DSM_MODERN_TURN_ON_DISPLAY),
+ .revision = 0,
+ .required_functions =
+ IDX_TO_BIT(DSM_INTEL_MS_DISPLAY_OFF_NOTIF) |
+ IDX_TO_BIT(DSM_INTEL_MS_DISPLAY_ON_NOTIF) |
+ IDX_TO_BIT(DSM_INTEL_MS_LPI_ENTRY_NOTIF) |
+ IDX_TO_BIT(DSM_INTEL_MS_LPI_EXIT_NOTIF) |
+ IDX_TO_BIT(DSM_MS_SLEEP_ENTRY_NOTIF) |
+ IDX_TO_BIT(DSM_MS_SLEEP_EXIT_NOTIF),
+ .extra_functions =
+ IDX_TO_BIT(DSM_MS_TURN_ON_DISPLAY),
+ .function_names = dsm_ms_function_names,
+ .function_names_nb = nitems(dsm_ms_function_names),
};
-static struct dsm_set amd_dsm_set = {
- .flag = DSM_SET_AMD,
+static const char *const dsm_amd_function_names[] = {
+ [DSM_GET_DEVICE_CONSTRAINTS] = "DEVICE_CONSTRAINTS",
+ [DSM_AMD_DISPLAY_OFF_NOTIF] = "DISPLAY_OFF",
+ [DSM_AMD_DISPLAY_ON_NOTIF] = "DISPLAY_ON",
+ [DSM_AMD_LPI_ENTRY_NOTIF] = "LPI_ENTRY",
+ [DSM_AMD_LPI_EXIT_NOTIF] = "LPI_EXIT",
+};
+
+static struct dsm_desc dsm_amd = {
+ .index = DSM_AMD,
.name = "AMD",
+ .uuid = { /* e3f32452-febc-43ce-9039-932122d37721 */
+ 0xe3f32452, 0xfebc, 0x43ce, 0x90, 0x39,
+ {0x93, 0x21, 0x22, 0xd3, 0x77, 0x21}
+ },
/*
* XXX Linux uses 0 for the revision on AMD DSMs, but at least on the
* Framework 13 AMD 7040 series, the enum functions DSM only returns a
@@ -126,23 +174,32 @@
* this just in case.
*/
.revision = 2,
- .uuid = { /* e3f32452-febc-43ce-9039-932122d37721 */
- 0xe3f32452, 0xfebc, 0x43ce, 0x90, 0x39,
- {0x93, 0x21, 0x22, 0xd3, 0x77, 0x21},
- },
- .dsms_expected = (1 << AMD_DSM_GET_DEVICE_CONSTRAINTS) |
- (1 << AMD_DSM_ENTRY_NOTIF) | (1 << AMD_DSM_EXIT_NOTIF) |
- (1 << AMD_DSM_DISPLAY_OFF_NOTIF) | (1 << AMD_DSM_DISPLAY_ON_NOTIF),
+ .required_functions =
+ IDX_TO_BIT(DSM_GET_DEVICE_CONSTRAINTS) |
+ IDX_TO_BIT(DSM_AMD_DISPLAY_OFF_NOTIF) |
+ IDX_TO_BIT(DSM_AMD_DISPLAY_ON_NOTIF) |
+ IDX_TO_BIT(DSM_AMD_LPI_ENTRY_NOTIF) |
+ IDX_TO_BIT(DSM_AMD_LPI_EXIT_NOTIF),
+ .function_names = dsm_amd_function_names,
+ .function_names_nb = nitems(dsm_amd_function_names),
};
+static const struct dsm_desc *const dsms[] = {
+ [DSM_INTEL] = &dsm_intel,
+ [DSM_MS] = &dsm_ms,
+ [DSM_AMD] = &dsm_amd,
+};
+
+static SYSCTL_NODE(_debug_acpi, OID_AUTO, spmc, CTLFLAG_RD | CTLFLAG_MPSAFE,
+ NULL, "SPMC debugging");
+
+SYSCTL_INT(_debug_acpi_spmc, OID_AUTO, intel_dsm_revision, CTLFLAG_RW,
+ &dsm_intel.revision, 0,
+ "Revision to use when evaluating Intel SPMC DSMs");
+
SYSCTL_INT(_debug_acpi_spmc, OID_AUTO, amd_dsm_revision, CTLFLAG_RW,
- &amd_dsm_set.revision, 0, "Revision to use when evaluating AMD SPMC DSMs");
+ &dsm_amd.revision, 0, "Revision to use when evaluating AMD SPMC DSMs");
-union dsm_index {
- int i;
- enum intel_dsm_index regular;
- enum amd_dsm_index amd;
-};
struct acpi_spmc_constraint {
bool enabled;
@@ -150,7 +207,7 @@
int min_d_state;
ACPI_HANDLE handle;
- /* Unused, spec only. */
+ /* Unused, Intel only. */
uint64_t lpi_uid;
uint64_t min_dev_specific_state;
@@ -159,10 +216,9 @@
};
struct acpi_spmc_softc {
- device_t dev;
- ACPI_HANDLE handle;
- ACPI_OBJECT *obj;
- enum dsm_set_flags dsm_sets;
+ device_t dev;
+ ACPI_HANDLE handle;
+ int supported_dsms;
struct eventhandler_entry *eh_suspend;
struct eventhandler_entry *eh_resume;
@@ -172,10 +228,104 @@
struct acpi_spmc_constraint *constraints;
};
-static void acpi_spmc_check_dsm_set(struct acpi_spmc_softc *sc,
- ACPI_HANDLE handle, struct dsm_set *dsm_set);
+
+typedef const char *pbf_get_name_t(const int, const void *const);
+
+static const char *
+pbf_dsm_name(const int dsm_index, const void *const opaque __unused)
+{
+ MPASS(0 <= dsm_index && dsm_index < nitems(dsms));
+ return (dsms[dsm_index]->name);
+}
+
+static const char *
+dsm_function_name(const struct dsm_desc *const dsm, const int function_index)
+{
+ if (function_index >= dsm->function_names_nb)
+ return (NULL);
+ /* May be NULL. */
+ return (dsm->function_names[function_index]);
+}
+
+static const char *
+pbf_function_name(const int function_index, const void *const opaque)
+{
+ return (dsm_function_name(opaque, function_index));
+}
+
+static int
+print_bit_field(char *const buf, const size_t buf_size,
+ const uint64_t bit_field, const char *const fallback_prefix,
+ pbf_get_name_t get_name, const void *const opaque)
+{
+ uint64_t bf = bit_field;
+ char *const buf_end = buf + buf_size;
+ char *p = buf;
+ int ret = 0;
+ bool one_set = false;
+
+#define PBF_PRINT(...) \
+ do { \
+ const __ptrdiff_t rem = MAX(buf_end - p, 0); \
+ const int lret = snprintf(p, rem, __VA_ARGS__); \
+ \
+ MPASS(lret >= 0); \
+ p += MIN(lret, rem); \
+ ret += lret; \
+ } while (0)
+
+ if (bf == 0) {
+ PBF_PRINT("");
+ return (ret);
+ }
+
+ do {
+ const int b_idx = ffsll(bf) - 1;
+ const char *const name = get_name(b_idx, opaque);
+
+ PBF_PRINT(one_set ? "," : "<");
+ one_set = true;
+ if (name != NULL)
+ PBF_PRINT("%s", name);
+ else
+ PBF_PRINT("%s_%d", fallback_prefix, b_idx);
+
+ bf &= ~IDX_TO_BIT(b_idx);
+ } while (bf != 0);
+ PBF_PRINT(">");
+
+ return (ret);
+}
+
+static bool
+is_dsm_present(const struct acpi_spmc_softc *const sc, const int dsm_index)
+{
+ return (sc->supported_dsms & IDX_TO_BIT(dsm_index));
+}
+
+static void
+failed_to_call_dsm(device_t dev, const char *func_name,
+ const struct dsm_desc *dsm, int function_index)
+{
+ (void)device_printf(dev,
+ "%s failed to call DSM %s (rev %d) function %s\n",
+ func_name, dsm->name, dsm->revision,
+ dsm_function_name(dsm, function_index));
+}
+
+static bool
+dsm_supports_function(const struct dsm_desc *const dsm, int function_index)
+{
+ return ((dsm->supported_functions & IDX_TO_BIT(function_index)) != 0);
+}
+
+static void acpi_spmc_probe_dsm(struct acpi_spmc_softc *sc,
+ ACPI_HANDLE handle, struct dsm_desc *const dsm);
+static void acpi_spmc_dsm_check_functions(
+ const struct acpi_spmc_softc *const sc,
+ const struct dsm_desc *const dsm);
static int acpi_spmc_get_constraints(device_t dev);
-static void acpi_spmc_free_constraints(struct acpi_spmc_softc *sc);
+static void acpi_spmc_free_constraints(struct acpi_spmc_softc *const sc);
static void acpi_spmc_suspend(device_t dev, enum power_stype stype);
static void acpi_spmc_resume(device_t dev, enum power_stype stype);
@@ -184,8 +334,9 @@
acpi_spmc_probe(device_t dev)
{
char *name;
- ACPI_HANDLE handle;
+ ACPI_HANDLE handle;
struct acpi_spmc_softc *sc;
+ char buf[32];
/* Check that this is an enabled device. */
if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("spmc"))
@@ -207,17 +358,19 @@
sc->dev = dev;
/* Check which sets of DSMs are supported. */
- sc->dsm_sets = 0;
+ sc->supported_dsms = 0;
- acpi_spmc_check_dsm_set(sc, handle, &intel_dsm_set);
- acpi_spmc_check_dsm_set(sc, handle, &ms_dsm_set);
- acpi_spmc_check_dsm_set(sc, handle, &amd_dsm_set);
+ acpi_spmc_probe_dsm(sc, handle, &dsm_intel);
+ acpi_spmc_probe_dsm(sc, handle, &dsm_ms);
+ acpi_spmc_probe_dsm(sc, handle, &dsm_amd);
- if (sc->dsm_sets == 0)
+ if (sc->supported_dsms == 0)
return (ENXIO);
+ print_bit_field(buf, nitems(buf), sc->supported_dsms, "DSM",
+ pbf_dsm_name, NULL);
device_set_descf(dev, "System Power Management Controller "
- "(DSM sets 0x%x)", sc->dsm_sets);
+ "(DSM sets %#0x%s)", sc->supported_dsms, buf);
return (0);
}
@@ -231,6 +384,9 @@
if (sc->handle == NULL)
return (ENXIO);
+ for (int i = 0; i < nitems(dsms); ++i)
+ acpi_spmc_dsm_check_functions(sc, dsms[i]);
+
sc->constraints_populated = false;
sc->constraint_count = 0;
sc->constraints = NULL;
@@ -259,38 +415,55 @@
}
static void
-acpi_spmc_check_dsm_set(struct acpi_spmc_softc *sc, ACPI_HANDLE handle,
- struct dsm_set *dsm_set)
+acpi_spmc_probe_dsm(struct acpi_spmc_softc *sc, ACPI_HANDLE handle,
+ struct dsm_desc *const dsm)
{
- uint64_t dsms_supported = acpi_DSMQuery(handle,
- (uint8_t *)&dsm_set->uuid, dsm_set->revision);
- const uint64_t min_dsms = dsm_set->dsms_expected;
- const uint64_t max_dsms = min_dsms | dsm_set->extra_dsms;
+ const uint64_t supported_functions = acpi_DSMQuery(handle,
+ (uint8_t *)&dsm->uuid, dsm->revision);
/*
- * Check if DSM set supported at all. We do this by checking the
- * existence of "enum functions".
+ * DSM is supported if bit 0 is set.
*/
- if ((dsms_supported & 1) == 0)
+ if ((supported_functions & 1) == 0)
return;
- dsms_supported &= ~1;
- dsm_set->dsms_supported = dsms_supported;
- sc->dsm_sets |= dsm_set->flag;
-
- if ((dsms_supported & min_dsms) != min_dsms)
- device_printf(sc->dev, "DSM set %s does not support expected "
- "DSMs (%#" PRIx64 " vs %#" PRIx64 "). "
- "Some methods may fail.\n",
- dsm_set->name, dsms_supported, min_dsms);
-
- if ((dsms_supported & ~max_dsms) != 0)
- device_printf(sc->dev, "DSM set %s supports more DSMs than "
- "expected (%#" PRIx64 " vs %#" PRIx64 ").\n", dsm_set->name,
- dsms_supported, max_dsms);
+ dsm->supported_functions = supported_functions & ~1;
+ sc->supported_dsms |= IDX_TO_BIT(dsm->index);
}
static void
-acpi_spmc_free_constraints(struct acpi_spmc_softc *sc)
+acpi_spmc_dsm_check_functions(const struct acpi_spmc_softc *const sc,
+ const struct dsm_desc *const dsm)
+{
+ const uint64_t missing = dsm->required_functions &
+ ~dsm->supported_functions;
+ const uint64_t unknown = dsm->supported_functions &
+ ~(dsm->required_functions | dsm->extra_functions);
+ char buf[128];
+
+ print_bit_field(buf, nitems(buf), dsm->supported_functions,
+ "FUNC", pbf_function_name, dsm);
+ device_printf(sc->dev, "DSM %s: Supported functions: %#" PRIx64 "%s\n",
+ dsm->name, dsm->supported_functions, buf);
+
+ if (missing != 0) {
+ print_bit_field(buf, nitems(buf), missing, "FUNC",
+ pbf_function_name, dsm);
+ device_printf(sc->dev, "DSM %s: Does not enumerate expected "
+ "functions %#" PRIx64 "%s. Calls to them may fail.\n",
+ dsm->name, missing, buf);
+ }
+
+ if (bootverbose && unknown != 0) {
+ print_bit_field(buf, nitems(buf), unknown, "FUNC",
+ pbf_function_name, dsm);
+ device_printf(sc->dev, "DSM %s: Supports more functions than "
+ "used (%#" PRIx64 "%s), driver might need an upgrade.\n",
+ dsm->name, unknown, buf);
+ }
+}
+
+static void
+acpi_spmc_free_constraints(struct acpi_spmc_softc *const sc)
{
for (size_t i = 0; i < sc->constraint_count; i++)
free(sc->constraints[i].name, M_TEMP);
@@ -301,7 +474,7 @@
}
static int
-acpi_spmc_get_constraints_spec(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
+acpi_spmc_get_constraints_intel(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
{
struct acpi_spmc_constraint *constraint;
int revision;
@@ -428,8 +601,7 @@
acpi_spmc_get_constraints(device_t dev)
{
struct acpi_spmc_softc *sc;
- union dsm_index dsm_index;
- struct dsm_set *dsm_set;
+ struct dsm_desc *dsm;
ACPI_STATUS status;
ACPI_BUFFER result;
ACPI_OBJECT *object;
@@ -442,22 +614,15 @@
return (0);
/* The Microsoft DSM set doesn't have this DSM. */
- is_amd = (sc->dsm_sets & DSM_SET_AMD) != 0;
- if (is_amd) {
- dsm_set = &amd_dsm_set;
- dsm_index.amd = AMD_DSM_GET_DEVICE_CONSTRAINTS;
- } else {
- dsm_set = &intel_dsm_set;
- dsm_index.regular = DSM_GET_DEVICE_CONSTRAINTS;
- }
+ is_amd = is_dsm_present(sc, DSM_AMD) != 0;
+ dsm = is_amd ? &dsm_amd : &dsm_intel;
- /* XXX It seems like this DSM fails if called more than once. */
- status = acpi_EvaluateDSMTyped(sc->handle, (uint8_t *)&dsm_set->uuid,
- dsm_set->revision, dsm_index.i, NULL, &result,
+ /* XXX This DSM function seems to fail if called more than once. */
+ status = acpi_EvaluateDSMTyped(sc->handle, (uint8_t *)&dsm->uuid,
+ dsm->revision, DSM_GET_DEVICE_CONSTRAINTS, NULL, &result,
ACPI_TYPE_PACKAGE);
if (ACPI_FAILURE(status)) {
- device_printf(dev, "%s failed to call %s DSM %d (rev %d)\n",
- __func__, dsm_set->name, dsm_index.i, dsm_set->revision);
+ failed_to_call_dsm(dev, __func__, dsm, DSM_GET_DEVICE_CONSTRAINTS);
return (ENXIO);
}
@@ -465,7 +630,7 @@
if (is_amd)
rv = acpi_spmc_get_constraints_amd(sc, object);
else
- rv = acpi_spmc_get_constraints_spec(sc, object);
+ rv = acpi_spmc_get_constraints_intel(sc, object);
AcpiOsFree(object);
if (rv != 0)
return (rv);
@@ -530,7 +695,7 @@
}
static void
-acpi_spmc_run_dsm(device_t dev, struct dsm_set *dsm_set, int index)
+acpi_spmc_run_dsm(device_t dev, struct dsm_desc *dsm, int index)
{
struct acpi_spmc_softc *sc;
ACPI_STATUS status;
@@ -538,16 +703,13 @@
sc = device_get_softc(dev);
- status = acpi_EvaluateDSMTyped(sc->handle, (uint8_t *)&dsm_set->uuid,
- dsm_set->revision, index, NULL, &result, ACPI_TYPE_ANY);
+ status = acpi_EvaluateDSMTyped(sc->handle, (uint8_t *)&dsm->uuid,
+ dsm->revision, index, NULL, &result, ACPI_TYPE_ANY);
- if (ACPI_FAILURE(status)) {
- device_printf(dev, "%s failed to call %s DSM %d (rev %d)\n",
- __func__, dsm_set->name, index, dsm_set->revision);
- return;
- }
-
- AcpiOsFree(result.Pointer);
+ if (ACPI_FAILURE(status))
+ failed_to_call_dsm(dev, __func__, dsm, index);
+ else
+ AcpiOsFree(result.Pointer);
}
/*
@@ -562,12 +724,14 @@
{
struct acpi_spmc_softc *sc = device_get_softc(dev);
- if ((sc->dsm_sets & DSM_SET_INTEL) != 0)
- acpi_spmc_run_dsm(dev, &intel_dsm_set, DSM_DISPLAY_OFF_NOTIF);
- if ((sc->dsm_sets & DSM_SET_MS) != 0)
- acpi_spmc_run_dsm(dev, &ms_dsm_set, DSM_DISPLAY_OFF_NOTIF);
- if ((sc->dsm_sets & DSM_SET_AMD) != 0)
- acpi_spmc_run_dsm(dev, &amd_dsm_set, AMD_DSM_DISPLAY_OFF_NOTIF);
+ if (is_dsm_present(sc, DSM_INTEL))
+ acpi_spmc_run_dsm(dev, &dsm_intel,
+ DSM_INTEL_MS_DISPLAY_OFF_NOTIF);
+ if (is_dsm_present(sc, DSM_MS))
+ acpi_spmc_run_dsm(dev, &dsm_ms,
+ DSM_INTEL_MS_DISPLAY_OFF_NOTIF);
+ if (is_dsm_present(sc, DSM_AMD))
+ acpi_spmc_run_dsm(dev, &dsm_amd, DSM_AMD_DISPLAY_OFF_NOTIF);
}
static void
@@ -575,12 +739,14 @@
{
struct acpi_spmc_softc *sc = device_get_softc(dev);
- if ((sc->dsm_sets & DSM_SET_INTEL) != 0)
- acpi_spmc_run_dsm(dev, &intel_dsm_set, DSM_DISPLAY_ON_NOTIF);
- if ((sc->dsm_sets & DSM_SET_MS) != 0)
- acpi_spmc_run_dsm(dev, &ms_dsm_set, DSM_DISPLAY_ON_NOTIF);
- if ((sc->dsm_sets & DSM_SET_AMD) != 0)
- acpi_spmc_run_dsm(dev, &amd_dsm_set, AMD_DSM_DISPLAY_ON_NOTIF);
+ if (is_dsm_present(sc, DSM_INTEL))
+ acpi_spmc_run_dsm(dev, &dsm_intel,
+ DSM_INTEL_MS_DISPLAY_ON_NOTIF);
+ if (is_dsm_present(sc, DSM_MS))
+ acpi_spmc_run_dsm(dev, &dsm_ms,
+ DSM_INTEL_MS_DISPLAY_ON_NOTIF);
+ if (is_dsm_present(sc, DSM_AMD))
+ acpi_spmc_run_dsm(dev, &dsm_amd, DSM_AMD_DISPLAY_ON_NOTIF);
}
static void
@@ -590,14 +756,15 @@
acpi_spmc_check_constraints(sc);
- if ((sc->dsm_sets & DSM_SET_AMD) != 0)
- acpi_spmc_run_dsm(dev, &amd_dsm_set, AMD_DSM_ENTRY_NOTIF);
- if ((sc->dsm_sets & DSM_SET_MS) != 0) {
- acpi_spmc_run_dsm(dev, &ms_dsm_set, DSM_MODERN_ENTRY_NOTIF);
- acpi_spmc_run_dsm(dev, &ms_dsm_set, DSM_ENTRY_NOTIF);
+ if (is_dsm_present(sc, DSM_AMD))
+ acpi_spmc_run_dsm(dev, &dsm_amd, DSM_AMD_LPI_ENTRY_NOTIF);
+ if (is_dsm_present(sc, DSM_MS)) {
+ acpi_spmc_run_dsm(dev, &dsm_ms, DSM_MS_SLEEP_ENTRY_NOTIF);
+ acpi_spmc_run_dsm(dev, &dsm_ms, DSM_INTEL_MS_LPI_ENTRY_NOTIF);
}
- if ((sc->dsm_sets & DSM_SET_INTEL) != 0)
- acpi_spmc_run_dsm(dev, &intel_dsm_set, DSM_ENTRY_NOTIF);
+ if (is_dsm_present(sc, DSM_INTEL))
+ acpi_spmc_run_dsm(dev, &dsm_intel,
+ DSM_INTEL_MS_LPI_ENTRY_NOTIF);
}
static void
@@ -605,17 +772,16 @@
{
struct acpi_spmc_softc *sc = device_get_softc(dev);
- if ((sc->dsm_sets & DSM_SET_INTEL) != 0)
- acpi_spmc_run_dsm(dev, &intel_dsm_set, DSM_EXIT_NOTIF);
- if ((sc->dsm_sets & DSM_SET_AMD) != 0)
- acpi_spmc_run_dsm(dev, &amd_dsm_set, AMD_DSM_EXIT_NOTIF);
- if ((sc->dsm_sets & DSM_SET_MS) != 0) {
- acpi_spmc_run_dsm(dev, &ms_dsm_set, DSM_EXIT_NOTIF);
- if (ms_dsm_set.dsms_supported &
- (1 << DSM_MODERN_TURN_ON_DISPLAY))
- acpi_spmc_run_dsm(dev, &ms_dsm_set,
- DSM_MODERN_TURN_ON_DISPLAY);
- acpi_spmc_run_dsm(dev, &ms_dsm_set, DSM_MODERN_EXIT_NOTIF);
+ if (is_dsm_present(sc, DSM_INTEL))
+ acpi_spmc_run_dsm(dev, &dsm_intel, DSM_INTEL_MS_LPI_EXIT_NOTIF);
+ if (is_dsm_present(sc, DSM_AMD))
+ acpi_spmc_run_dsm(dev, &dsm_amd, DSM_AMD_LPI_EXIT_NOTIF);
+ if (is_dsm_present(sc, DSM_MS)) {
+ acpi_spmc_run_dsm(dev, &dsm_ms, DSM_INTEL_MS_LPI_EXIT_NOTIF);
+ if (dsm_supports_function(&dsm_ms, DSM_MS_TURN_ON_DISPLAY))
+ acpi_spmc_run_dsm(dev, &dsm_ms,
+ DSM_MS_TURN_ON_DISPLAY);
+ acpi_spmc_run_dsm(dev, &dsm_ms, DSM_MS_SLEEP_EXIT_NOTIF);
}
}

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 14, 3:10 AM (12 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36698645
Default Alt Text
D56756.id177001.diff (21 KB)

Event Timeline