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.
This commit is contained in:
Nate Lawson 2004-03-03 03:02:17 +00:00
parent 2adaffb0aa
commit 3184cf5a6b
7 changed files with 102 additions and 61 deletions

View File

@ -52,16 +52,11 @@ driver is automatically loaded by the bootloader, and should not normally
be compiled into the kernel. be compiled into the kernel.
.Sh ENVIRONMENT .Sh ENVIRONMENT
This support is still experimental, and thus there are many debugging This support is still experimental, and thus there are many debugging
and tuning options which are managed via the kernel environment and tuning options which are managed via the kernel environment.
space, and set in the Tunables can be set at the
.Xr loader 8 .Xr loader 8
before booting the kernel. prompt before booting the kernel or stored in
Kernel environment variables may also be configured in the .Pa /boot/loader.conf .
.Xr loader
configuration file
.Pa /boot/loader.conf
or the device resource hints file
.Pa /boot/device.hints .
.Pp .Pp
Debugging is separated between layers and levels, where a layer is Debugging is separated between layers and levels, where a layer is
a portion of the ACPI subsystem, and a level is a particular kind a portion of the ACPI subsystem, and a level is a particular kind
@ -102,25 +97,25 @@ The supported layers are:
.It .It
.Li ACPI_ALL_COMPONENTS .Li ACPI_ALL_COMPONENTS
.It .It
.Li ACPI_BUS
.It
.Li ACPI_SYSTEM
.It
.Li ACPI_POWER
.It
.Li ACPI_EC
.It
.Li ACPI_AC_ADAPTER .Li ACPI_AC_ADAPTER
.It .It
.Li ACPI_BATTERY .Li ACPI_BATTERY
.It .It
.Li ACPI_BUS
.It
.Li ACPI_BUTTON .Li ACPI_BUTTON
.It .It
.Li ACPI_EC
.It
.Li ACPI_FAN
.It
.Li ACPI_POWER
.It
.Li ACPI_PROCESSOR .Li ACPI_PROCESSOR
.It .It
.Li ACPI_THERMAL .Li ACPI_THERMAL
.It .It
.Li ACPI_FAN .Li ACPI_TIMER
.It .It
.Li ACPI_ALL_DRIVERS .Li ACPI_ALL_DRIVERS
.El .El
@ -231,7 +226,7 @@ driver comprises a set of drivers, which may be selectively disabled
in case of problems. in case of problems.
To disable a sub-driver, list it in the kernel To disable a sub-driver, list it in the kernel
environment variable environment variable
.Va debug.acpi.disable . .Va debug.acpi.disabled .
Multiple entries can be listed, separated by a space. Multiple entries can be listed, separated by a space.
.Pp .Pp
ACPI sub-devices and features that can be disabled: 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. Enables loading of a custom ACPI DSDT.
.It Va acpi_dsdt_name .It Va acpi_dsdt_name
Name of the DSDT table to load, if loading is enabled. 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. Selectively disables portions of ACPI for debugging purposes.
.It Va hint.acpi.0.disabled .It Va hint.acpi.0.disabled
Disables all of ACPI. Disables all of ACPI.

View File

@ -36,9 +36,6 @@ __FBSDID("$FreeBSD$");
#include "acpi.h" #include "acpi.h"
#include <dev/acpica/acpivar.h> #include <dev/acpica/acpivar.h>
#define _COMPONENT ACPI_TOSHIBA
ACPI_MODULE_NAME("TOSHIBA")
/* /*
* Toshiba HCI interface definitions * Toshiba HCI interface definitions
* *
@ -213,8 +210,6 @@ acpi_toshiba_attach(device_t dev)
ACPI_STATUS status; ACPI_STATUS status;
int i; int i;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = device_get_softc(dev); sc = device_get_softc(dev);
sc->dev = dev; sc->dev = dev;
sc->handle = acpi_get_handle(dev); sc->handle = acpi_get_handle(dev);
@ -253,8 +248,6 @@ acpi_toshiba_detach(device_t dev)
{ {
struct acpi_toshiba_softc *sc; struct acpi_toshiba_softc *sc;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = device_get_softc(dev); sc = device_get_softc(dev);
if (enable_fn_keys != 0) { if (enable_fn_keys != 0) {
AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,

View File

@ -85,10 +85,28 @@ static int acpi_off_state = ACPI_STATE_S5;
struct mtx acpi_mutex; struct mtx acpi_mutex;
#endif #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 int acpi_modevent(struct module *mod, int event, void *junk);
static void acpi_identify(driver_t *driver, device_t parent); static void acpi_identify(driver_t *driver, device_t parent);
static int acpi_probe(device_t dev); static int acpi_probe(device_t dev);
static int acpi_attach(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, static device_t acpi_add_child(device_t bus, int order, const char *name,
int unit); int unit);
static int acpi_print_child(device_t bus, device_t child); 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__); ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
if (started) if (started)
return_VALUE(error); return_VALUE (error);
started = 1; started = 1;
#if __FreeBSD_version >= 500000 #if __FreeBSD_version >= 500000
@ -226,7 +244,7 @@ acpi_Startup(void)
#endif #endif
if (ACPI_FAILURE(error = AcpiInitializeSubsystem())) { if (ACPI_FAILURE(error = AcpiInitializeSubsystem())) {
printf("ACPI: initialisation failed: %s\n", AcpiFormatException(error)); printf("ACPI: initialisation failed: %s\n", AcpiFormatException(error));
return_VALUE(error); return_VALUE (error);
} }
#ifdef ACPI_DEBUGGER #ifdef ACPI_DEBUGGER
debugpoint = getenv("debug.acpi.debugger"); debugpoint = getenv("debug.acpi.debugger");
@ -241,7 +259,11 @@ acpi_Startup(void)
printf("ACPI: table load failed: %s\n", AcpiFormatException(error)); printf("ACPI: table load failed: %s\n", AcpiFormatException(error));
return_VALUE(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); 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 * Handle a new device being added
*/ */
@ -590,7 +652,6 @@ acpi_print_child(device_t bus, device_t child)
return (retval); return (retval);
} }
/* /*
* Handle per-device ivars * Handle per-device ivars
*/ */
@ -1832,24 +1893,24 @@ acpi_disabled(char *subsys)
char *cp, *env; char *cp, *env;
int len; int len;
if ((env = getenv("debug.acpi.disable")) == NULL) if ((env = getenv("debug.acpi.disabled")) == NULL)
return (0); return (0);
if (!strcmp(env, "all")) { if (strcmp(env, "all") == 0) {
freeenv(env); freeenv(env);
return (1); return (1);
} }
/* scan the disable list checking for a match */ /* Scan the disable list, checking for a match. */
cp = env; cp = env;
for (;;) { for (;;) {
while ((*cp != 0) && isspace(*cp)) while (*cp != '\0' && isspace(*cp))
cp++; cp++;
if (*cp == 0) if (*cp == '\0')
break; break;
len = 0; len = 0;
while ((cp[len] != 0) && !isspace(cp[len])) while (cp[len] != '\0' && !isspace(cp[len]))
len++; len++;
if (!strncmp(cp, subsys, len)) { if (strncmp(cp, subsys, len) == 0) {
freeenv(env); freeenv(env);
return (1); return (1);
} }
@ -2211,16 +2272,16 @@ static struct debugtag dbg_layer[] = {
{"ACPI_CA_DISASSEMBLER", ACPI_CA_DISASSEMBLER}, {"ACPI_CA_DISASSEMBLER", ACPI_CA_DISASSEMBLER},
{"ACPI_ALL_COMPONENTS", ACPI_ALL_COMPONENTS}, {"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_AC_ADAPTER", ACPI_AC_ADAPTER},
{"ACPI_BATTERY", ACPI_BATTERY}, {"ACPI_BATTERY", ACPI_BATTERY},
{"ACPI_BUS", ACPI_BUS},
{"ACPI_BUTTON", ACPI_BUTTON}, {"ACPI_BUTTON", ACPI_BUTTON},
{"ACPI_EC", ACPI_EC},
{"ACPI_FAN", ACPI_FAN},
{"ACPI_POWERRES", ACPI_POWERRES},
{"ACPI_PROCESSOR", ACPI_PROCESSOR}, {"ACPI_PROCESSOR", ACPI_PROCESSOR},
{"ACPI_THERMAL", ACPI_THERMAL}, {"ACPI_THERMAL", ACPI_THERMAL},
{"ACPI_FAN", ACPI_FAN}, {"ACPI_TIMER", ACPI_TIMER},
{"ACPI_ALL_DRIVERS", ACPI_ALL_DRIVERS}, {"ACPI_ALL_DRIVERS", ACPI_ALL_DRIVERS},
{NULL, 0} {NULL, 0}
}; };

View File

@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources"); MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources");
/* Hooks for the ACPI CA debugging infrastructure */ /* Hooks for the ACPI CA debugging infrastructure */
#define _COMPONENT ACPI_POWER #define _COMPONENT ACPI_POWERRES
ACPI_MODULE_NAME("POWERRES") ACPI_MODULE_NAME("POWERRES")
/* Return values from _STA on a power resource */ /* Return values from _STA on a power resource */

View File

@ -52,7 +52,7 @@
*/ */
/* Hooks for the ACPI CA debugging infrastructure */ /* Hooks for the ACPI CA debugging infrastructure */
#define _COMPONENT ACPI_SYSTEM #define _COMPONENT ACPI_TIMER
ACPI_MODULE_NAME("TIMER") ACPI_MODULE_NAME("TIMER")
static device_t acpi_timer_dev; static device_t acpi_timer_dev;

View File

@ -115,17 +115,16 @@ struct acpi_device {
* ACPI CA does not define layers for non-ACPI CA drivers. * ACPI CA does not define layers for non-ACPI CA drivers.
* We define some here within the range provided. * We define some here within the range provided.
*/ */
#define ACPI_BUS 0x00010000 #define ACPI_AC_ADAPTER 0x00010000
#define ACPI_SYSTEM 0x00020000 #define ACPI_BATTERY 0x00020000
#define ACPI_POWER 0x00040000 #define ACPI_BUS 0x00040000
#define ACPI_EC 0x00080000 #define ACPI_BUTTON 0x00080000
#define ACPI_AC_ADAPTER 0x00100000 #define ACPI_EC 0x00100000
#define ACPI_BATTERY 0x00200000 #define ACPI_FAN 0x00200000
#define ACPI_BUTTON 0x00400000 #define ACPI_POWERRES 0x00400000
#define ACPI_PROCESSOR 0x00800000 #define ACPI_PROCESSOR 0x00800000
#define ACPI_THERMAL 0x01000000 #define ACPI_THERMAL 0x01000000
#define ACPI_FAN 0x02000000 #define ACPI_TIMER 0x02000000
#define ACPI_TOSHIBA 0x04000000
/* /*
* Constants for different interrupt models used with acpi_SetIntrModel(). * Constants for different interrupt models used with acpi_SetIntrModel().

View File

@ -36,9 +36,6 @@ __FBSDID("$FreeBSD$");
#include "acpi.h" #include "acpi.h"
#include <dev/acpica/acpivar.h> #include <dev/acpica/acpivar.h>
#define _COMPONENT ACPI_TOSHIBA
ACPI_MODULE_NAME("TOSHIBA")
/* /*
* Toshiba HCI interface definitions * Toshiba HCI interface definitions
* *
@ -213,8 +210,6 @@ acpi_toshiba_attach(device_t dev)
ACPI_STATUS status; ACPI_STATUS status;
int i; int i;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = device_get_softc(dev); sc = device_get_softc(dev);
sc->dev = dev; sc->dev = dev;
sc->handle = acpi_get_handle(dev); sc->handle = acpi_get_handle(dev);
@ -253,8 +248,6 @@ acpi_toshiba_detach(device_t dev)
{ {
struct acpi_toshiba_softc *sc; struct acpi_toshiba_softc *sc;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = device_get_softc(dev); sc = device_get_softc(dev);
if (enable_fn_keys != 0) { if (enable_fn_keys != 0) {
AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,