Module Name:    src
Committed By:   jruoho
Date:           Sun Apr 18 14:05:26 UTC 2010

Modified Files:
        src/sys/dev/acpi: acpi.c acpi_pci.c acpi_wakedev.c acpivar.h

Log Message:
>From Grégoire Sutre:

  Modify the main ACPI namespace scan by including a parent-child
  relationship for each node. The result is a bi-directional tree.

ok jmcneill@


To generate a diff of this commit:
cvs rdiff -u -r1.175 -r1.176 src/sys/dev/acpi/acpi.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/acpi/acpi_pci.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/acpi/acpi_wakedev.c
cvs rdiff -u -r1.48 -r1.49 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.175 src/sys/dev/acpi/acpi.c:1.176
--- src/sys/dev/acpi/acpi.c:1.175	Thu Apr 15 07:02:24 2010
+++ src/sys/dev/acpi/acpi.c	Sun Apr 18 14:05:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpi.c,v 1.175 2010/04/15 07:02:24 jruoho Exp $	*/
+/*	$NetBSD: acpi.c,v 1.176 2010/04/18 14:05:26 jruoho Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.175 2010/04/15 07:02:24 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.176 2010/04/18 14:05:26 jruoho Exp $");
 
 #include "opt_acpi.h"
 #include "opt_pcifixup.h"
@@ -130,6 +130,15 @@
 extern kmutex_t acpi_interrupt_list_mtx;
 
 /*
+ * This structure provides a context for the ACPI
+ * namespace walk performed in acpi_build_tree().
+ */
+struct acpi_walkcontext {
+	struct acpi_softc	*aw_sc;
+	struct acpi_devnode	*aw_parent;
+};
+
+/*
  * Ignored HIDs.
  */
 static const char * const acpi_ignored_ids[] = {
@@ -160,8 +169,15 @@
 static bool		acpi_resume(device_t, const pmf_qual_t *);
 
 static void		acpi_build_tree(struct acpi_softc *);
+
+#ifdef ACPI_DEBUG
+static void		acpi_print_tree(struct acpi_devnode *, uint32_t);
+#endif
+
 static ACPI_STATUS	acpi_make_devnode(ACPI_HANDLE, uint32_t,
 					  void *, void **);
+static ACPI_STATUS	acpi_make_devnode_post(ACPI_HANDLE, uint32_t,
+					       void *, void **);
 
 #ifdef ACPI_ACTIVATE_DEV
 static void		acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
@@ -397,8 +413,10 @@
 	acpi_unmap_rsdt(rsdt);
 
 	sc->sc_dev = self;
-	sc->sc_quirks = acpi_find_quirks();
+	sc->sc_root = NULL;
+
 	sc->sc_sleepstate = ACPI_STATE_S0;
+	sc->sc_quirks = acpi_find_quirks();
 
 	sysmon_power_settype("acpi");
 
@@ -408,7 +426,7 @@
 	sc->sc_pciflags = aa->aa_pciflags;
 	sc->sc_ic = aa->aa_ic;
 
-	SIMPLEQ_INIT(&sc->sc_devnodes);
+	SIMPLEQ_INIT(&sc->ad_head);
 
 	acpi_softc = sc;
 
@@ -562,7 +580,7 @@
 	if (sc->sc_apmbus == child)
 		sc->sc_apmbus = NULL;
 
-	SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
+	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
 
 		if (ad->ad_device == child)
 			ad->ad_device = NULL;
@@ -593,9 +611,24 @@
 static void
 acpi_build_tree(struct acpi_softc *sc)
 {
+	struct acpi_walkcontext awc;
 
-	(void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
-	    UINT32_MAX, acpi_make_devnode, NULL, sc, NULL);
+	awc.aw_sc = sc;
+	awc.aw_parent = NULL;
+
+	(void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
+
+	KASSERT(sc->sc_root == NULL);
+	KASSERT(awc.aw_parent != NULL);
+
+	sc->sc_root = awc.aw_parent;
+
+	(void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
+	    acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
+
+#ifdef ACPI_DEBUG
+	acpi_print_tree(sc->sc_root, 0);
+#endif
 
 	acpi_rescan1(sc, NULL, NULL);
 	acpi_rescan_capabilities(sc);
@@ -603,11 +636,29 @@
 	acpi_pcidev_scan(sc);
 }
 
+#ifdef ACPI_DEBUG
+static void
+acpi_print_tree(struct acpi_devnode *ad, uint32_t level)
+{
+	struct acpi_devnode *child;
+	uint32_t i;
+
+	for (i = 0; i < level; i++)
+		aprint_normal("           ");
+
+	aprint_normal("[%02u] %-5s\n", ad->ad_type, ad->ad_name);
+
+	SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list)
+	    acpi_print_tree(child, level + 1);
+}
+#endif
+
 static ACPI_STATUS
 acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
     void *context, void **status)
 {
-	struct acpi_softc *sc = context;
+	struct acpi_walkcontext *awc = context;
+	struct acpi_softc *sc = awc->aw_sc;
 	struct acpi_devnode *ad;
 	ACPI_DEVICE_INFO *devinfo;
 	ACPI_OBJECT_TYPE type;
@@ -640,12 +691,15 @@
 			return AE_NO_MEMORY;
 
 		ad->ad_device = NULL;
-		ad->ad_parent = sc->sc_dev;
+		ad->ad_notify = NULL;
 
 		ad->ad_type = type;
 		ad->ad_handle = handle;
 		ad->ad_devinfo = devinfo;
 
+		ad->ad_root = sc->sc_dev;
+		ad->ad_parent = awc->aw_parent;
+
 		anu = (ACPI_NAME_UNION *)&devinfo->Name;
 		ad->ad_name[4] = '\0';
 
@@ -662,7 +716,16 @@
 		if (ad->ad_name[0] == '\0')
 			ad->ad_name[0] = '_';
 
-		SIMPLEQ_INSERT_TAIL(&sc->sc_devnodes, ad, ad_list);
+		SIMPLEQ_INIT(&ad->ad_child_head);
+		SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list);
+
+		if (ad->ad_parent != NULL) {
+
+			SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head,
+			    ad, ad_child_list);
+		}
+
+		awc->aw_parent = ad;
 
 #ifdef ACPIVERBOSE
 
@@ -695,6 +758,21 @@
 	return AE_OK;
 }
 
+static ACPI_STATUS
+acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level,
+    void *context, void **status)
+{
+	struct acpi_walkcontext *awc = context;
+
+	KASSERT(awc != NULL);
+	KASSERT(awc->aw_parent != NULL);
+
+	if (handle == awc->aw_parent->ad_handle)
+		awc->aw_parent = awc->aw_parent->ad_parent;
+
+	return AE_OK;
+}
+
 #ifdef ACPI_ACTIVATE_DEV
 
 #define ACPI_DEV_VALID	(ACPI_VALID_STA | ACPI_VALID_HID)
@@ -888,7 +966,7 @@
 	struct acpi_attach_args aa;
 	struct acpi_devnode *ad;
 
-	SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
+	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
 
 		if (ad->ad_device != NULL)
 			continue;
@@ -956,7 +1034,7 @@
 	ACPI_HANDLE tmp;
 	ACPI_STATUS rv;
 
-	SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
+	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
 
 		di = ad->ad_devinfo;
 
@@ -1126,7 +1204,7 @@
 	 * that have registered a handler with us.
 	 * The opaque pointer is always the device_t.
 	 */
-	SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
+	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
 
 		if (ad->ad_device == NULL)
 			continue;

Index: src/sys/dev/acpi/acpi_pci.c
diff -u src/sys/dev/acpi/acpi_pci.c:1.4 src/sys/dev/acpi/acpi_pci.c:1.5
--- src/sys/dev/acpi/acpi_pci.c:1.4	Tue Mar  9 18:15:22 2010
+++ src/sys/dev/acpi/acpi_pci.c	Sun Apr 18 14:05:26 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_pci.c,v 1.4 2010/03/09 18:15:22 jruoho Exp $ */
+/* $NetBSD: acpi_pci.c,v 1.5 2010/04/18 14:05:26 jruoho Exp $ */
 
 /*
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.4 2010/03/09 18:15:22 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.5 2010/04/18 14:05:26 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -147,7 +147,7 @@
 #define ACPI_STA_DEV_VALID      \
 	(ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|ACPI_STA_DEV_OK)
 
-	SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
+	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
 
 		di = ad->ad_devinfo;
 

Index: src/sys/dev/acpi/acpi_wakedev.c
diff -u src/sys/dev/acpi/acpi_wakedev.c:1.11 src/sys/dev/acpi/acpi_wakedev.c:1.12
--- src/sys/dev/acpi/acpi_wakedev.c:1.11	Wed Apr 14 20:08:56 2010
+++ src/sys/dev/acpi/acpi_wakedev.c	Sun Apr 18 14:05:26 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_wakedev.c,v 1.11 2010/04/14 20:08:56 jruoho Exp $ */
+/* $NetBSD: acpi_wakedev.c,v 1.12 2010/04/18 14:05:26 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2009, 2010 Jared D. McNeill <[email protected]>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_wakedev.c,v 1.11 2010/04/14 20:08:56 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_wakedev.c,v 1.12 2010/04/18 14:05:26 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -94,7 +94,7 @@
 {
 	int err;
 
-	KASSERT(ad != NULL && ad->ad_parent != NULL);
+	KASSERT(ad != NULL && ad->ad_root != NULL);
 	KASSERT((ad->ad_flags & ACPI_DEVICE_WAKEUP) != 0);
 
 	ad->ad_wake = 0;
@@ -111,7 +111,7 @@
 	    CTL_CREATE, CTL_EOL);
 
 	if (err != 0)
-		aprint_error_dev(ad->ad_parent, "sysctl_createv"
+		aprint_error_dev(ad->ad_root, "sysctl_createv"
 		    "(hw.acpi.wake.%s) failed (err %d)\n", ad->ad_name, err);
 }
 
@@ -130,7 +130,7 @@
 	 *
 	 * XXX: The first one is yet to be implemented.
 	 */
-	SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
+	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
 
 		if ((ad->ad_flags & ACPI_DEVICE_WAKEUP) == 0)
 			continue;
@@ -189,7 +189,7 @@
 	return;
 
 fail:
-	aprint_error_dev(ad->ad_parent, "failed to evaluate wake "
+	aprint_error_dev(ad->ad_root, "failed to evaluate wake "
 	    "control method: %s\n", AcpiFormatException(rv));
 }
 

Index: src/sys/dev/acpi/acpivar.h
diff -u src/sys/dev/acpi/acpivar.h:1.48 src/sys/dev/acpi/acpivar.h:1.49
--- src/sys/dev/acpi/acpivar.h:1.48	Thu Apr 15 07:02:24 2010
+++ src/sys/dev/acpi/acpivar.h	Sun Apr 18 14:05:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpivar.h,v 1.48 2010/04/15 07:02:24 jruoho Exp $	*/
+/*	$NetBSD: acpivar.h,v 1.49 2010/04/18 14:05:26 jruoho Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -72,13 +72,11 @@
 
 /*
  * An ACPI device node.
- *
- * Note that this is available for all nodes, meaning that e.g.
- * the device_t (ad_device) may be NULL for unattached devices.
  */
 struct acpi_devnode {
 	device_t		 ad_device;	/* Device */
-	device_t		 ad_parent;	/* Backpointer to the parent */
+	device_t		 ad_root;	/* Backpointer to acpi_softc */
+	struct acpi_devnode	*ad_parent;	/* Backpointer to parent */
 	ACPI_NOTIFY_HANDLER	 ad_notify;	/* Device notify */
 	ACPI_DEVICE_INFO	*ad_devinfo;	/* Device info */
 	ACPI_HANDLE		 ad_handle;	/* Device handle */
@@ -87,37 +85,38 @@
 	uint32_t		 ad_type;	/* Device type */
 	int			 ad_wake;	/* Device wakeup */
 
-	SIMPLEQ_ENTRY(acpi_devnode) ad_list;
+
+	SIMPLEQ_ENTRY(acpi_devnode)	ad_list;
+	SIMPLEQ_ENTRY(acpi_devnode)	ad_child_list;
+	SIMPLEQ_HEAD(, acpi_devnode)	ad_child_head;
 };
 
 /*
  * Software state of the ACPI subsystem.
  */
 struct acpi_softc {
-	device_t sc_dev;		/* base device info */
-	bus_space_tag_t sc_iot;		/* PCI I/O space tag */
-	bus_space_tag_t sc_memt;	/* PCI MEM space tag */
-	pci_chipset_tag_t sc_pc;	/* PCI chipset tag */
-	int sc_pciflags;		/* PCI bus flags */
-	int sc_pci_bus;			/* internal PCI fixup */
-	isa_chipset_tag_t sc_ic;	/* ISA chipset tag */
-
-	void *sc_sdhook;		/* shutdown hook */
-
-	/*
-	 * Power switch handlers for fixed-feature buttons.
-	 */
-	struct sysmon_pswitch sc_smpsw_power;
-	struct sysmon_pswitch sc_smpsw_sleep;
+	device_t		 sc_dev;	/* base device info */
+	device_t		 sc_apmbus;	/* APM pseudo-bus */
+
+	struct acpi_devnode	*sc_root;	/* root of the device tree */
+
+	bus_space_tag_t		 sc_iot;	/* PCI I/O space tag */
+	bus_space_tag_t		 sc_memt;	/* PCI MEM space tag */
+	pci_chipset_tag_t	 sc_pc;		/* PCI chipset tag */
+	int			 sc_pciflags;	/* PCI bus flags */
+	int			 sc_pci_bus;	/* internal PCI fixup */
+	isa_chipset_tag_t	 sc_ic;		/* ISA chipset tag */
 
-	int sc_sleepstate;		/* current sleep state */
-	int sc_sleepstates;		/* supported sleep states */
+	void			*sc_sdhook;	/* shutdown hook */
 
-	int sc_quirks;
+	int			 sc_quirks;
+	int			 sc_sleepstate;
+	int			 sc_sleepstates;
 
-	device_t	sc_apmbus;
+	struct sysmon_pswitch	 sc_smpsw_power;
+	struct sysmon_pswitch	 sc_smpsw_sleep;
 
-	SIMPLEQ_HEAD(, acpi_devnode) sc_devnodes; /* devices */
+	SIMPLEQ_HEAD(, acpi_devnode)	ad_head;
 };
 
 /*

Reply via email to