Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F166359614
D56756.id177001.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D56756.id177001.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D56756: acpi_spmc(4): Human-readably print supported DSMs and their functions
Attached
Detach File
Event Timeline
Log In to Comment