From 3184cf5a6b03f541c8bccdb1cdfc83d76f381771 Mon Sep 17 00:00:00 2001 From: Nate Lawson Date: Wed, 3 Mar 2004 03:02:17 +0000 Subject: [PATCH] Add support for quirks for acpi tables. Key off OEM vendor and revision. Sort acpi debug values. Change "disable" to "disabled" to match rest of the kernel. Remove debugging from acpi_toshiba since it was only used for probe/attach. --- share/man/man4/acpi.4 | 35 +++++------ sys/dev/acpi_support/acpi_toshiba.c | 7 --- sys/dev/acpica/acpi.c | 93 ++++++++++++++++++++++++----- sys/dev/acpica/acpi_powerres.c | 2 +- sys/dev/acpica/acpi_timer.c | 2 +- sys/dev/acpica/acpivar.h | 17 +++--- sys/i386/acpica/acpi_toshiba.c | 7 --- 7 files changed, 102 insertions(+), 61 deletions(-) diff --git a/share/man/man4/acpi.4 b/share/man/man4/acpi.4 index 9c078a93cd34..dda7368e54aa 100644 --- a/share/man/man4/acpi.4 +++ b/share/man/man4/acpi.4 @@ -52,16 +52,11 @@ driver is automatically loaded by the bootloader, and should not normally be compiled into the kernel. .Sh ENVIRONMENT This support is still experimental, and thus there are many debugging -and tuning options which are managed via the kernel environment -space, and set in the +and tuning options which are managed via the kernel environment. +Tunables can be set at the .Xr loader 8 -before booting the kernel. -Kernel environment variables may also be configured in the -.Xr loader -configuration file -.Pa /boot/loader.conf -or the device resource hints file -.Pa /boot/device.hints . +prompt before booting the kernel or stored in +.Pa /boot/loader.conf . .Pp Debugging is separated between layers and levels, where a layer is a portion of the ACPI subsystem, and a level is a particular kind @@ -102,25 +97,25 @@ The supported layers are: .It .Li ACPI_ALL_COMPONENTS .It -.Li ACPI_BUS -.It -.Li ACPI_SYSTEM -.It -.Li ACPI_POWER -.It -.Li ACPI_EC -.It .Li ACPI_AC_ADAPTER .It .Li ACPI_BATTERY .It +.Li ACPI_BUS +.It .Li ACPI_BUTTON .It +.Li ACPI_EC +.It +.Li ACPI_FAN +.It +.Li ACPI_POWER +.It .Li ACPI_PROCESSOR .It .Li ACPI_THERMAL .It -.Li ACPI_FAN +.Li ACPI_TIMER .It .Li ACPI_ALL_DRIVERS .El @@ -231,7 +226,7 @@ driver comprises a set of drivers, which may be selectively disabled in case of problems. To disable a sub-driver, list it in the kernel environment variable -.Va debug.acpi.disable . +.Va debug.acpi.disabled . Multiple entries can be listed, separated by a space. .Pp ACPI sub-devices and features that can be disabled: @@ -324,7 +319,7 @@ utilities and some ACPI knowledge. Enables loading of a custom ACPI DSDT. .It Va acpi_dsdt_name Name of the DSDT table to load, if loading is enabled. -.It Va debug.acpi.disable +.It Va debug.acpi.disabled Selectively disables portions of ACPI for debugging purposes. .It Va hint.acpi.0.disabled Disables all of ACPI. diff --git a/sys/dev/acpi_support/acpi_toshiba.c b/sys/dev/acpi_support/acpi_toshiba.c index 23d2d31a639a..e8e43e540a6b 100644 --- a/sys/dev/acpi_support/acpi_toshiba.c +++ b/sys/dev/acpi_support/acpi_toshiba.c @@ -36,9 +36,6 @@ __FBSDID("$FreeBSD$"); #include "acpi.h" #include -#define _COMPONENT ACPI_TOSHIBA -ACPI_MODULE_NAME("TOSHIBA") - /* * Toshiba HCI interface definitions * @@ -213,8 +210,6 @@ acpi_toshiba_attach(device_t dev) ACPI_STATUS status; int i; - ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - sc = device_get_softc(dev); sc->dev = dev; sc->handle = acpi_get_handle(dev); @@ -253,8 +248,6 @@ acpi_toshiba_detach(device_t dev) { struct acpi_toshiba_softc *sc; - ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - sc = device_get_softc(dev); if (enable_fn_keys != 0) { AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index aefd7e925dd8..97b347faa38c 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} }; diff --git a/sys/dev/acpica/acpi_powerres.c b/sys/dev/acpica/acpi_powerres.c index 431707809551..cfa75f576254 100644 --- a/sys/dev/acpica/acpi_powerres.c +++ b/sys/dev/acpica/acpi_powerres.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources"); /* Hooks for the ACPI CA debugging infrastructure */ -#define _COMPONENT ACPI_POWER +#define _COMPONENT ACPI_POWERRES ACPI_MODULE_NAME("POWERRES") /* Return values from _STA on a power resource */ diff --git a/sys/dev/acpica/acpi_timer.c b/sys/dev/acpica/acpi_timer.c index a737febf1173..d9867c69f229 100644 --- a/sys/dev/acpica/acpi_timer.c +++ b/sys/dev/acpica/acpi_timer.c @@ -52,7 +52,7 @@ */ /* Hooks for the ACPI CA debugging infrastructure */ -#define _COMPONENT ACPI_SYSTEM +#define _COMPONENT ACPI_TIMER ACPI_MODULE_NAME("TIMER") static device_t acpi_timer_dev; diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index a94ce7be964b..0541ff92cb57 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -115,17 +115,16 @@ struct acpi_device { * ACPI CA does not define layers for non-ACPI CA drivers. * We define some here within the range provided. */ -#define ACPI_BUS 0x00010000 -#define ACPI_SYSTEM 0x00020000 -#define ACPI_POWER 0x00040000 -#define ACPI_EC 0x00080000 -#define ACPI_AC_ADAPTER 0x00100000 -#define ACPI_BATTERY 0x00200000 -#define ACPI_BUTTON 0x00400000 +#define ACPI_AC_ADAPTER 0x00010000 +#define ACPI_BATTERY 0x00020000 +#define ACPI_BUS 0x00040000 +#define ACPI_BUTTON 0x00080000 +#define ACPI_EC 0x00100000 +#define ACPI_FAN 0x00200000 +#define ACPI_POWERRES 0x00400000 #define ACPI_PROCESSOR 0x00800000 #define ACPI_THERMAL 0x01000000 -#define ACPI_FAN 0x02000000 -#define ACPI_TOSHIBA 0x04000000 +#define ACPI_TIMER 0x02000000 /* * Constants for different interrupt models used with acpi_SetIntrModel(). diff --git a/sys/i386/acpica/acpi_toshiba.c b/sys/i386/acpica/acpi_toshiba.c index 23d2d31a639a..e8e43e540a6b 100644 --- a/sys/i386/acpica/acpi_toshiba.c +++ b/sys/i386/acpica/acpi_toshiba.c @@ -36,9 +36,6 @@ __FBSDID("$FreeBSD$"); #include "acpi.h" #include -#define _COMPONENT ACPI_TOSHIBA -ACPI_MODULE_NAME("TOSHIBA") - /* * Toshiba HCI interface definitions * @@ -213,8 +210,6 @@ acpi_toshiba_attach(device_t dev) ACPI_STATUS status; int i; - ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - sc = device_get_softc(dev); sc->dev = dev; sc->handle = acpi_get_handle(dev); @@ -253,8 +248,6 @@ acpi_toshiba_detach(device_t dev) { struct acpi_toshiba_softc *sc; - ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); - sc = device_get_softc(dev); if (enable_fn_keys != 0) { AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,