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
 
 /*

Reply via email to