Module Name: src Committed By: jruoho Date: Sun Feb 20 06:45:32 UTC 2011
Modified Files: src/sys/dev/acpi: acpi.c acpi_quirks.c acpivar.h Log Message: Add quirk support for _OSI strings introduced in ACPICA 20110211. While here, clean up acpi_probe() and the quirk code. Remove #ifdef ACPI_DEBUGGER. To generate a diff of this commit: cvs rdiff -u -r1.237 -r1.238 src/sys/dev/acpi/acpi.c cvs rdiff -u -r1.18 -r1.19 src/sys/dev/acpi/acpi_quirks.c cvs rdiff -u -r1.68 -r1.69 src/sys/dev/acpi/acpivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/acpi/acpi.c diff -u src/sys/dev/acpi/acpi.c:1.237 src/sys/dev/acpi/acpi.c:1.238 --- src/sys/dev/acpi/acpi.c:1.237 Sat Feb 19 09:52:32 2011 +++ src/sys/dev/acpi/acpi.c Sun Feb 20 06:45:32 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi.c,v 1.237 2011/02/19 09:52:32 jruoho Exp $ */ +/* $NetBSD: acpi.c,v 1.238 2011/02/20 06:45:32 jruoho Exp $ */ /*- * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. @@ -100,7 +100,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.237 2011/02/19 09:52:32 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.238 2011/02/20 06:45:32 jruoho Exp $"); #include "opt_acpi.h" #include "opt_pcifixup.h" @@ -138,16 +138,6 @@ #include <machine/acpi_machdep.h> -#ifdef ACPI_DEBUGGER -#define ACPI_DBGR_INIT 0x01 -#define ACPI_DBGR_TABLES 0x02 -#define ACPI_DBGR_ENABLE 0x04 -#define ACPI_DBGR_PROBE 0x08 -#define ACPI_DBGR_RUNNING 0x10 - -static int acpi_dbgr = 0x00; -#endif - /* * The acpi_active variable is set when the ACPI subsystem is active. * Machine-dependent code may wish to skip other steps (such as attaching @@ -159,7 +149,7 @@ int acpi_force_load = 0; int acpi_verbose_loaded = 0; -struct acpi_softc *acpi_softc; +struct acpi_softc *acpi_softc = NULL; static uint64_t acpi_root_pointer; extern kmutex_t acpi_interrupt_list_mtx; extern struct cfdriver acpi_cd; @@ -260,42 +250,25 @@ acpi_probe(void) { ACPI_TABLE_HEADER *rsdt; - const char *func; - static int once; - bool initialized; ACPI_STATUS rv; + int quirks; - if (once != 0) + if (acpi_softc != NULL) panic("%s: already probed", __func__); - once = 1; - func = NULL; - acpi_softc = NULL; - initialized = false; - mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE); /* * Start up ACPICA. */ -#ifdef ACPI_DEBUGGER - if (acpi_dbgr & ACPI_DBGR_INIT) - acpi_osd_debugger(); -#endif - - CTASSERT(TRUE == true); - CTASSERT(FALSE == false); - AcpiGbl_AllMethodsSerialized = false; AcpiGbl_EnableInterpreterSlack = true; rv = AcpiInitializeSubsystem(); - if (ACPI_SUCCESS(rv)) - initialized = true; - else { - func = "AcpiInitializeSubsystem()"; - goto fail; + if (ACPI_FAILURE(rv)) { + aprint_error("%s: failed to initialize subsystem\n", __func__); + return 0; } /* @@ -305,49 +278,47 @@ rv = AcpiInitializeTables(NULL, 2, true); if (ACPI_FAILURE(rv)) { - func = "AcpiInitializeTables()"; + aprint_error("%s: failed to initialize tables\n", __func__); goto fail; } -#ifdef ACPI_DEBUGGER - if (acpi_dbgr & ACPI_DBGR_TABLES) - acpi_osd_debugger(); -#endif - rv = AcpiLoadTables(); if (ACPI_FAILURE(rv)) { - func = "AcpiLoadTables()"; + aprint_error("%s: failed to load tables\n", __func__); goto fail; } rsdt = acpi_map_rsdt(); if (rsdt == NULL) { - func = "acpi_map_rsdt()"; - rv = AE_ERROR; + aprint_error("%s: failed to map RSDT\n", __func__); goto fail; } - if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) { + quirks = acpi_find_quirks(); + + if (acpi_force_load == 0 && (quirks & ACPI_QUIRK_BROKEN) != 0) { + aprint_normal("ACPI: BIOS is listed as broken:\n"); aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, " - "AslId <%4.4s,%08x>\n", - rsdt->OemId, rsdt->OemTableId, - rsdt->OemRevision, - rsdt->AslCompilerId, + "AslId <%4.4s,%08x>\n", rsdt->OemId, rsdt->OemTableId, + rsdt->OemRevision, rsdt->AslCompilerId, rsdt->AslCompilerRevision); aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n"); + acpi_unmap_rsdt(rsdt); - AcpiTerminate(); - return 0; + goto fail; } - if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_OLDBIOS)) { - aprint_normal("ACPI: BIOS is too old (%s). Set acpi_force_load to use.\n", + + if (acpi_force_load == 0 && (quirks & ACPI_QUIRK_OLDBIOS) != 0) { + + aprint_normal("ACPI: BIOS is too old (%s). " + "Set acpi_force_load to use.\n", pmf_get_platform("firmware-date")); + acpi_unmap_rsdt(rsdt); - AcpiTerminate(); - return 0; + goto fail; } acpi_unmap_rsdt(rsdt); @@ -355,24 +326,14 @@ rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE)); if (ACPI_FAILURE(rv)) { - func = "AcpiEnableSubsystem()"; + aprint_error("%s: failed to enable subsystem\n", __func__); goto fail; } - /* - * Looks like we have ACPI! - */ return 1; fail: - KASSERT(rv != AE_OK); - KASSERT(func != NULL); - - aprint_error("%s: failed to probe ACPI: %s\n", - func, AcpiFormatException(rv)); - - if (initialized != false) - (void)AcpiTerminate(); + (void)AcpiTerminate(); return 0; } @@ -468,13 +429,8 @@ aprint_error_dev(self, "couldn't establish power handler\n"); /* - * Bring ACPI on-line. + * Bring ACPICA on-line. */ -#ifdef ACPI_DEBUGGER - if (acpi_dbgr & ACPI_DBGR_ENABLE) - acpi_osd_debugger(); -#endif - #define ACPI_ENABLE_PHASE1 \ (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT) #define ACPI_ENABLE_PHASE2 \ @@ -532,22 +488,12 @@ acpitimer_init(sc); -#ifdef ACPI_DEBUGGER - if (acpi_dbgr & ACPI_DBGR_PROBE) - acpi_osd_debugger(); -#endif - /* * Scan the namespace and build our device tree. */ acpi_build_tree(sc); acpi_sleep_init(sc); -#ifdef ACPI_DEBUGGER - if (acpi_dbgr & ACPI_DBGR_RUNNING) - acpi_osd_debugger(); -#endif - #ifdef ACPI_DEBUG acpi_debug_init(); #endif @@ -1659,6 +1605,9 @@ return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER)); } +/* + * XXX: Refactor to be a generic function that unmaps tables. + */ static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt) { Index: src/sys/dev/acpi/acpi_quirks.c diff -u src/sys/dev/acpi/acpi_quirks.c:1.18 src/sys/dev/acpi/acpi_quirks.c:1.19 --- src/sys/dev/acpi/acpi_quirks.c:1.18 Mon Sep 6 15:54:27 2010 +++ src/sys/dev/acpi/acpi_quirks.c Sun Feb 20 06:45:32 2011 @@ -1,4 +1,31 @@ -/* $NetBSD: acpi_quirks.c,v 1.18 2010/09/06 15:54:27 jmcneill Exp $ */ +/* $NetBSD: acpi_quirks.c,v 1.19 2011/02/20 06:45:32 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -37,27 +64,26 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.18 2010/09/06 15:54:27 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.19 2011/02/20 06:45:32 jruoho Exp $"); #include "opt_acpi.h" #include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> +#include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME ("acpi_quirks") + #define AQ_GT 0 /* > */ #define AQ_LT 1 /* < */ #define AQ_GTE 2 /* >= */ #define AQ_LTE 3 /* <= */ #define AQ_EQ 4 /* == */ -static int acpi_rev_cmp(uint32_t, uint32_t, int); +static int acpi_quirks_revcmp(uint32_t, uint32_t, int); -/* - * XXX: Add more. - */ static struct acpi_quirk acpi_quirks[] = { { ACPI_SIG_FADT, "ASUS ", 0x30303031, AQ_LTE, "CUV4X-D ", @@ -74,41 +100,34 @@ }; static int -acpi_rev_cmp(uint32_t tabval, uint32_t wanted, int op) +acpi_quirks_revcmp(uint32_t tabval, uint32_t wanted, int op) { + switch (op) { + case AQ_GT: - if (tabval > wanted) - return 0; - else - return 1; + return (tabval > wanted) ? 0 : 1; + case AQ_LT: - if (tabval < wanted) - return 0; - else - return 1; + return (tabval < wanted) ? 0 : 1; + case AQ_LTE: - if (tabval <= wanted) - return 0; - else - return 1; + return (tabval <= wanted) ? 0 : 1; + case AQ_GTE: - if (tabval >= wanted) - return 0; - else - return 1; + return (tabval >= wanted) ? 0 : 1; + case AQ_EQ: - if (tabval == wanted) - return 0; - else - return 1; + return (tabval == wanted) ? 0 : 1; + + default: + return 1; } - return 1; } #ifdef ACPI_BLACKLIST_YEAR static int -acpi_find_bios_year(void) +acpi_quirks_bios_year(void) { const char *datestr = pmf_get_platform("firmware-date"); unsigned long date; @@ -126,50 +145,127 @@ #endif /* - * Simple function to search the quirk table. Only to be used after - * AcpiLoadTables has been successfully called. + * Simple function to search the quirk table. Only to be + * used after AcpiLoadTables() has been successfully called. */ int acpi_find_quirks(void) { - int i, nquirks; - struct acpi_quirk *aqp; ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr; + struct acpi_quirk *aq; + ACPI_STATUS rv; + size_t i, len; + #ifdef ACPI_BLACKLIST_YEAR - int year = acpi_find_bios_year(); + int year = acpi_quirks_bios_year(); if (year != -1 && year <= ACPI_BLACKLIST_YEAR) return ACPI_QUIRK_OLDBIOS; #endif - nquirks = __arraycount(acpi_quirks); + rv = AcpiGetTableHeader(ACPI_SIG_FADT, 0, &fadt); + + if (ACPI_FAILURE(rv)) + (void)memset(&fadt, 0, sizeof(fadt)); + + rv = AcpiGetTableHeader(ACPI_SIG_DSDT, 0, &dsdt); + + if (ACPI_FAILURE(rv)) + (void)memset(&dsdt, 0, sizeof(dsdt)); + + rv = AcpiGetTableHeader(ACPI_SIG_XSDT, 0, &xsdt); + + if (ACPI_FAILURE(rv)) + (void)memset(&xsdt, 0, sizeof(xsdt)); + + for (i = 0; i < __arraycount(acpi_quirks); i++) { + + aq = &acpi_quirks[i]; - if (ACPI_FAILURE(AcpiGetTableHeader(ACPI_SIG_FADT, 0, &fadt))) - memset(&fadt, 0, sizeof(fadt)); - if (ACPI_FAILURE(AcpiGetTableHeader(ACPI_SIG_DSDT, 0, &dsdt))) - memset(&dsdt, 0, sizeof(dsdt)); - if (ACPI_FAILURE(AcpiGetTableHeader(ACPI_SIG_XSDT, 0, &xsdt))) - memset(&xsdt, 0, sizeof(xsdt)); - - for (i = 0; i < nquirks; i++) { - aqp = &acpi_quirks[i]; - if (!strncmp(aqp->aq_tabletype, ACPI_SIG_DSDT, 4)) + if (strncmp(aq->aq_tabletype, ACPI_SIG_DSDT, 4) == 0) hdr = &dsdt; - else if (!strncmp(aqp->aq_tabletype, ACPI_SIG_XSDT, 4)) + else if (strncmp(aq->aq_tabletype, ACPI_SIG_XSDT, 4) == 0) hdr = &xsdt; - else if (!strncmp(aqp->aq_tabletype, ACPI_SIG_FADT, 4)) + else if (strncmp(aq->aq_tabletype, ACPI_SIG_FADT, 4) == 0) hdr = &fadt; - else + else { continue; - if (strncmp(aqp->aq_oemid, hdr->OemId, strlen(aqp->aq_oemid))) + } + + len = strlen(aq->aq_oemid); + + if (strncmp(aq->aq_oemid, hdr->OemId, len) != 0) continue; - if (acpi_rev_cmp(aqp->aq_oemrev, hdr->OemRevision, - aqp->aq_cmpop)) + + if (acpi_quirks_revcmp(aq->aq_oemrev, + hdr->OemRevision, aq->aq_cmpop) != 0) continue; - if (strncmp(aqp->aq_tabid, hdr->OemTableId, - strlen(aqp->aq_tabid))) + + len = strlen(aq->aq_tabid); + + if (strncmp(aq->aq_tabid, hdr->OemTableId, len) != 0) continue; - return aqp->aq_quirks; + + return aq->aq_quirks; } + return 0; } + +/* + * Add or delete a string to the list that should return + * true when _OSI is being queried. The defaults are: + * + * "Windows 2000" # Windows 2000 + * "Windows 2001" # Windows XP + * "Windows 2001 SP1" # Windows XP SP1 + * "Windows 2001.1" # Windows Server 2003 + * "Windows 2001 SP2" # Windows XP SP2 + * "Windows 2001.1 SP1" # Windows Server 2003 SP1 + * "Windows 2006" # Windows Vista + * "Windows 2006.1" # Windows Server 2008 + * "Windows 2006 SP1" # Windows Vista SP1 + * "Windows 2006 SP2" # Windows Vista SP2 + * "Windows 2009" # Windows 7 and Server 2008 + */ +int +acpi_quirks_osi_add(const char *str) +{ + ACPI_STATUS rv; + + if (str == NULL || *str == '\0') + return EINVAL; + + rv = AcpiInstallInterface(__UNCONST(str)); + + return (rv != AE_OK) ? EIO : 0; +} + +int +acpi_quirks_osi_del(const char *str) +{ + ACPI_STATUS rv; + + if (str == NULL || *str == '\0') + return EINVAL; + + rv = AcpiRemoveInterface(__UNCONST(str)); + + return (rv != AE_OK) ? EIO : 0; +} + +#if 0 +static void +acpi_quirks_osi_linux(void) +{ + (void)acpi_quirks_osi_add("Linux"); +} + +static void +acpi_quirks_osi_vista(void) +{ + (void)acpi_quirks_osi_del("Windows 2006"); + (void)acpi_quirks_osi_del("Windows 2006 SP1"); + (void)acpi_quirks_osi_del("Windows 2006 SP2"); +} +#endif Index: src/sys/dev/acpi/acpivar.h diff -u src/sys/dev/acpi/acpivar.h:1.68 src/sys/dev/acpi/acpivar.h:1.69 --- src/sys/dev/acpi/acpivar.h:1.68 Thu Feb 17 19:36:49 2011 +++ src/sys/dev/acpi/acpivar.h Sun Feb 20 06:45:32 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpivar.h,v 1.68 2011/02/17 19:36:49 jruoho Exp $ */ +/* $NetBSD: acpivar.h,v 1.69 2011/02/20 06:45:32 jruoho Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -343,12 +343,12 @@ * Quirk handling. */ struct acpi_quirk { - const char *aq_tabletype; /* what type of table (FADT, DSDT, etc) */ - const char *aq_oemid; /* compared against the table OemId */ - int aq_oemrev; /* compared against the table OemRev */ - int aq_cmpop; /* how to compare the oemrev number */ - const char *aq_tabid; /* compared against the table TableId */ - int aq_quirks; /* the actual quirks */ + const char *aq_tabletype; /* Type of table */ + const char *aq_oemid; /* "OemId" field */ + int aq_oemrev; /* "OemRev" field */ + int aq_cmpop; /* "OemRev" comparison */ + const char *aq_tabid; /* "TableId */ + int aq_quirks; /* The actual quirk */ }; #define ACPI_QUIRK_BROKEN 0x00000001 /* totally broken */ @@ -357,10 +357,12 @@ #define ACPI_QUIRK_IRQ0 0x00000008 /* bad 0->2 irq override */ #define ACPI_QUIRK_OLDBIOS 0x00000010 /* BIOS date blacklisted */ -int acpi_find_quirks(void); +int acpi_find_quirks(void); +int acpi_quirks_osi_add(const char *); +int acpi_quirks_osi_del(const char *); #ifdef ACPI_DEBUG -void acpi_debug_init(void); +void acpi_debug_init(void); #endif /*