summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/acpica/acpi.c')
-rw-r--r--sys/dev/acpica/acpi.c93
1 files changed, 77 insertions, 16 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index aefd7e9..97b347f 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -85,10 +85,28 @@ static int acpi_off_state = ACPI_STATE_S5;
struct mtx acpi_mutex;
#endif
+struct acpi_quirks {
+ char *OemId;
+ uint32_t OemRevision;
+ char *value;
+};
+
+#define ACPI_OEM_REV_ANY 0
+
+static struct acpi_quirks acpi_quirks_table[] = {
+#ifdef notyet
+ /* Bad PCI routing table. Used on some SuperMicro boards. */
+ { "PTLTD ", 0x06040000, "pci_link" },
+#endif
+
+ { NULL, 0, NULL }
+};
+
static int acpi_modevent(struct module *mod, int event, void *junk);
static void acpi_identify(driver_t *driver, device_t parent);
static int acpi_probe(device_t dev);
static int acpi_attach(device_t dev);
+static void acpi_quirks_set(void);
static device_t acpi_add_child(device_t bus, int order, const char *name,
int unit);
static int acpi_print_child(device_t bus, device_t child);
@@ -207,7 +225,7 @@ acpi_Startup(void)
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
if (started)
- return_VALUE(error);
+ return_VALUE (error);
started = 1;
#if __FreeBSD_version >= 500000
@@ -226,7 +244,7 @@ acpi_Startup(void)
#endif
if (ACPI_FAILURE(error = AcpiInitializeSubsystem())) {
printf("ACPI: initialisation failed: %s\n", AcpiFormatException(error));
- return_VALUE(error);
+ return_VALUE (error);
}
#ifdef ACPI_DEBUGGER
debugpoint = getenv("debug.acpi.debugger");
@@ -241,7 +259,11 @@ acpi_Startup(void)
printf("ACPI: table load failed: %s\n", AcpiFormatException(error));
return_VALUE(error);
}
- return_VALUE(AE_OK);
+
+ /* Set up any quirks we have for this XSDT. */
+ acpi_quirks_set();
+
+ return_VALUE (AE_OK);
}
/*
@@ -553,6 +575,46 @@ acpi_attach(device_t dev)
return_VALUE (error);
}
+static void
+acpi_quirks_set()
+{
+ XSDT_DESCRIPTOR *xsdt;
+ struct acpi_quirks *quirk;
+ char *env, *tmp;
+ int len;
+
+ /* If the user specifies "noquirks", leave the settings alone. */
+ len = 0;
+ if ((env = getenv("debug.acpi.disabled")) != NULL) {
+ if (strstr("noquirks", env) != NULL)
+ goto out;
+ len = strlen(env);
+ }
+
+ /*
+ * Search through our quirk table and concatenate the disabled
+ * values with whatever we find.
+ */
+ xsdt = AcpiGbl_XSDT;
+ for (quirk = acpi_quirks_table; quirk->OemId; quirk++) {
+ if (!strncmp(xsdt->OemId, quirk->OemId, strlen(quirk->OemId)) &&
+ (xsdt->OemRevision == quirk->OemRevision ||
+ quirk->OemRevision == ACPI_OEM_REV_ANY)) {
+ len += strlen(quirk->value) + 2;
+ if ((tmp = malloc(len, M_TEMP, M_NOWAIT)) == NULL)
+ goto out;
+ sprintf(tmp, "%s %s", env ? env : "", quirk->value);
+ setenv("debug.acpi.disabled", tmp);
+ free(tmp, M_TEMP);
+ break;
+ }
+ }
+
+out:
+ if (env)
+ freeenv(env);
+}
+
/*
* Handle a new device being added
*/
@@ -590,7 +652,6 @@ acpi_print_child(device_t bus, device_t child)
return (retval);
}
-
/*
* Handle per-device ivars
*/
@@ -1832,24 +1893,24 @@ acpi_disabled(char *subsys)
char *cp, *env;
int len;
- if ((env = getenv("debug.acpi.disable")) == NULL)
+ if ((env = getenv("debug.acpi.disabled")) == NULL)
return (0);
- if (!strcmp(env, "all")) {
+ if (strcmp(env, "all") == 0) {
freeenv(env);
return (1);
}
- /* scan the disable list checking for a match */
+ /* Scan the disable list, checking for a match. */
cp = env;
for (;;) {
- while ((*cp != 0) && isspace(*cp))
+ while (*cp != '\0' && isspace(*cp))
cp++;
- if (*cp == 0)
+ if (*cp == '\0')
break;
len = 0;
- while ((cp[len] != 0) && !isspace(cp[len]))
+ while (cp[len] != '\0' && !isspace(cp[len]))
len++;
- if (!strncmp(cp, subsys, len)) {
+ if (strncmp(cp, subsys, len) == 0) {
freeenv(env);
return (1);
}
@@ -2211,16 +2272,16 @@ static struct debugtag dbg_layer[] = {
{"ACPI_CA_DISASSEMBLER", ACPI_CA_DISASSEMBLER},
{"ACPI_ALL_COMPONENTS", ACPI_ALL_COMPONENTS},
- {"ACPI_BUS", ACPI_BUS},
- {"ACPI_SYSTEM", ACPI_SYSTEM},
- {"ACPI_POWER", ACPI_POWER},
- {"ACPI_EC", ACPI_EC},
{"ACPI_AC_ADAPTER", ACPI_AC_ADAPTER},
{"ACPI_BATTERY", ACPI_BATTERY},
+ {"ACPI_BUS", ACPI_BUS},
{"ACPI_BUTTON", ACPI_BUTTON},
+ {"ACPI_EC", ACPI_EC},
+ {"ACPI_FAN", ACPI_FAN},
+ {"ACPI_POWERRES", ACPI_POWERRES},
{"ACPI_PROCESSOR", ACPI_PROCESSOR},
{"ACPI_THERMAL", ACPI_THERMAL},
- {"ACPI_FAN", ACPI_FAN},
+ {"ACPI_TIMER", ACPI_TIMER},
{"ACPI_ALL_DRIVERS", ACPI_ALL_DRIVERS},
{NULL, 0}
};
OpenPOWER on IntegriCloud