Home | History | Annotate | Line # | Download | only in acpi
acpi_verbose.c revision 1.10.4.3
      1 /*	$NetBSD: acpi_verbose.c,v 1.10.4.3 2010/10/22 07:21:53 uebayasi Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2003, 2007, 2010 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Charles M. Hannum of By Noon Software, Inc, and Jukka Ruohonen.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Copyright 2001, 2003 Wasabi Systems, Inc.
     34  * All rights reserved.
     35  *
     36  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
     37  *
     38  * Redistribution and use in source and binary forms, with or without
     39  * modification, are permitted provided that the following conditions
     40  * are met:
     41  * 1. Redistributions of source code must retain the above copyright
     42  *    notice, this list of conditions and the following disclaimer.
     43  * 2. Redistributions in binary form must reproduce the above copyright
     44  *    notice, this list of conditions and the following disclaimer in the
     45  *    documentation and/or other materials provided with the distribution.
     46  * 3. All advertising materials mentioning features or use of this software
     47  *    must display the following acknowledgement:
     48  *	This product includes software developed for the NetBSD Project by
     49  *	Wasabi Systems, Inc.
     50  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     51  *    or promote products derived from this software without specific prior
     52  *    written permission.
     53  *
     54  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     55  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     56  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     57  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     58  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     59  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     60  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     61  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     62  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     63  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     64  * POSSIBILITY OF SUCH DAMAGE.
     65  */
     66 
     67 #include <sys/cdefs.h>
     68 __KERNEL_RCSID(0, "$NetBSD: acpi_verbose.c,v 1.10.4.3 2010/10/22 07:21:53 uebayasi Exp $");
     69 
     70 #include <sys/param.h>
     71 #include <sys/device.h>
     72 #include <sys/kernel.h>
     73 #include <sys/systm.h>
     74 #include <sys/module.h>
     75 
     76 #include <dev/acpi/acpireg.h>
     77 #include <dev/acpi/acpivar.h>
     78 #include <dev/acpi/acpidevs_data.h>
     79 
     80 #include <dev/pci/pcivar.h>
     81 
     82 #include <prop/proplib.h>
     83 
     84 #include "locators.h"
     85 
     86 static bool	   acpiverbose_modcmd_prop(prop_dictionary_t);
     87 
     88 void		   acpi_print_verbose_real(struct acpi_softc *);
     89 void		   acpi_print_dev_real(const char *);
     90 static void	   acpi_print_madt(struct acpi_softc *);
     91 static ACPI_STATUS acpi_print_madt_callback(ACPI_SUBTABLE_HEADER *, void *);
     92 static void	   acpi_print_fadt(struct acpi_softc *);
     93 static void	   acpi_print_devnodes(struct acpi_softc *);
     94 static void	   acpi_print_tree(struct acpi_devnode *, uint32_t);
     95 static device_t	   device_find_by_acpi_pci_info(const struct acpi_pci_info *);
     96 
     97 extern ACPI_TABLE_HEADER *madt_header;
     98 
     99 MODULE(MODULE_CLASS_MISC, acpiverbose, NULL);
    100 
    101 static int
    102 acpiverbose_modcmd(modcmd_t cmd, void *arg)
    103 {
    104 	static void (*saved_print_verbose)(struct acpi_softc *);
    105 	static void (*saved_print_dev)(const char *);
    106 	bool dump;
    107 
    108 	dump = false;
    109 
    110 	switch (cmd) {
    111 
    112 	case MODULE_CMD_INIT:
    113 		saved_print_verbose = acpi_print_verbose;
    114 		saved_print_dev = acpi_print_dev;
    115 		acpi_print_verbose = acpi_print_verbose_real;
    116 		acpi_print_dev = acpi_print_dev_real;
    117 		acpi_verbose_loaded = 1;
    118 
    119 		if (arg != NULL)
    120 			dump = acpiverbose_modcmd_prop(arg);
    121 
    122 		if (dump != false)
    123 			acpi_print_verbose_real(acpi_softc);
    124 
    125 		return 0;
    126 
    127 	case MODULE_CMD_FINI:
    128 		acpi_print_verbose = saved_print_verbose;
    129 		acpi_print_dev = saved_print_dev;
    130 		acpi_verbose_loaded = 0;
    131 		return 0;
    132 
    133 	default:
    134 		return ENOTTY;
    135 	}
    136 }
    137 
    138 static bool
    139 acpiverbose_modcmd_prop(prop_dictionary_t dict)
    140 {
    141 	prop_object_t obj;
    142 
    143 	obj = prop_dictionary_get(dict, "dump");
    144 
    145 	if (obj == NULL || prop_object_type(obj) != PROP_TYPE_BOOL)
    146 		return false;
    147 
    148 	return prop_bool_true(obj);
    149 }
    150 
    151 void
    152 acpi_print_verbose_real(struct acpi_softc *sc)
    153 {
    154 
    155 	acpi_print_madt(sc);
    156 	acpi_print_fadt(sc);
    157 	acpi_print_devnodes(sc);
    158 	acpi_print_tree(sc->sc_root, 0);
    159 }
    160 
    161 void
    162 acpi_print_dev_real(const char *pnpstr)
    163 {
    164 	int i;
    165 
    166 	for (i = 0; i < __arraycount(acpi_knowndevs); i++) {
    167 
    168 		if (strcmp(acpi_knowndevs[i].pnp, pnpstr) == 0)
    169 			aprint_normal("[%s] ", acpi_knowndevs[i].str);
    170 	}
    171 }
    172 
    173 static void
    174 acpi_print_madt(struct acpi_softc *sc)
    175 {
    176 	ACPI_TABLE_MADT *madt;
    177 	ACPI_STATUS rv;
    178 
    179 	rv = acpi_madt_map();
    180 
    181 	if (ACPI_FAILURE(rv) && rv != AE_ALREADY_EXISTS)
    182 		return;
    183 
    184 	if (madt_header == NULL)
    185 		return;
    186 
    187 	madt = (ACPI_TABLE_MADT *)madt_header;
    188 	acpi_madt_walk(acpi_print_madt_callback, sc);
    189 }
    190 
    191 static ACPI_STATUS
    192 acpi_print_madt_callback(ACPI_SUBTABLE_HEADER *hdr, void *aux)
    193 {
    194 	struct acpi_softc *sc = aux;
    195 	device_t self = sc->sc_dev;
    196 
    197 	/*
    198 	 * See ACPI 4.0, section 5.2.12.
    199 	 */
    200 	switch (hdr->Type) {
    201 
    202 	case ACPI_MADT_TYPE_LOCAL_APIC:
    203 
    204 		aprint_normal_dev(self, "[MADT] %-15s: "
    205 		    "CPU ID %u, LAPIC ID %u, FLAGS 0x%02X", "LAPIC",
    206 		    ((ACPI_MADT_LOCAL_APIC *)hdr)->ProcessorId,
    207 		    ((ACPI_MADT_LOCAL_APIC *)hdr)->Id,
    208 		    ((ACPI_MADT_LOCAL_APIC *)hdr)->LapicFlags);
    209 
    210 		break;
    211 
    212 	case ACPI_MADT_TYPE_IO_APIC:
    213 
    214 		aprint_normal_dev(self, "[MADT] %-15s: "
    215 		    "ID %u, GSI %u, ADDR 0x%04X", "I/O APIC",
    216 		    ((ACPI_MADT_IO_APIC *)hdr)->Id,
    217 		    ((ACPI_MADT_IO_APIC *)hdr)->GlobalIrqBase,
    218 		    ((ACPI_MADT_IO_APIC *)hdr)->Address);
    219 
    220 		break;
    221 
    222 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
    223 
    224 		aprint_normal_dev(self, "[MADT] %-15s: "
    225 		    "BUS %u, IRQ %u, GSI %u, FLAGS 0x%02X", "INTR OVERRIDE",
    226 		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->Bus,
    227 		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->SourceIrq,
    228 		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->GlobalIrq,
    229 		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->IntiFlags);
    230 
    231 		break;
    232 
    233 	case ACPI_MADT_TYPE_NMI_SOURCE:
    234 
    235 		aprint_normal_dev(self, "[MADT] %-15s: "
    236 		    "GSI %u, FLAGS 0x%02X", "NMI SOURCE",
    237 		    ((ACPI_MADT_NMI_SOURCE *)hdr)->GlobalIrq,
    238 		    ((ACPI_MADT_NMI_SOURCE *)hdr)->IntiFlags);
    239 
    240 		break;
    241 
    242 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
    243 
    244 		aprint_normal_dev(self, "[MADT] %-15s: "
    245 		    "CPU ID %u, LINT %u, FLAGS 0x%02X", "LAPIC NMI",
    246 		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->ProcessorId,
    247 		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->Lint,
    248 		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->IntiFlags);
    249 
    250 		break;
    251 
    252 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
    253 
    254 		aprint_normal_dev(self, "[MADT] %-15s: "
    255 		    "ADDR 0x%016" PRIX64"", "APIC OVERRIDE",
    256 		    ((ACPI_MADT_LOCAL_APIC_OVERRIDE *)hdr)->Address);
    257 
    258 		break;
    259 
    260 	case ACPI_MADT_TYPE_IO_SAPIC:
    261 
    262 		aprint_normal_dev(self, "[MADT] %-15s: "
    263 		    "ID %u, GSI %u, ADDR 0x%016" PRIX64"", "I/O SAPIC",
    264 		    ((ACPI_MADT_IO_SAPIC *)hdr)->Id,
    265 		    ((ACPI_MADT_IO_SAPIC *)hdr)->GlobalIrqBase,
    266 		    ((ACPI_MADT_IO_SAPIC *)hdr)->Address);
    267 
    268 		break;
    269 
    270 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
    271 
    272 		aprint_normal_dev(self, "[MADT] %-15s: "
    273 		    "CPU ID %u, ID %u, EID %u, UID %u, FLAGS 0x%02X", "LSAPIC",
    274 		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->ProcessorId,
    275 		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Id,
    276 		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Eid,
    277 		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Uid,
    278 		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->LapicFlags);
    279 
    280 		break;
    281 
    282 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
    283 
    284 		aprint_normal_dev(self, "[MADT] %-15s: ID %u, EID %u, "
    285 		    "TYPE %u, PMI %u, GSI %u, FLAGS 0x%02X", "INTR SOURCE",
    286 		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Id,
    287 		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Eid,
    288 		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Type,
    289 		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->IoSapicVector,
    290 		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->GlobalIrq,
    291 		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Flags);
    292 
    293 		break;
    294 
    295 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
    296 
    297 		aprint_normal_dev(self, "[MADT] %-15s: "
    298 		    "ID %u, UID %u, FLAGS 0x%02X", "X2APIC",
    299 		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->LocalApicId,
    300 		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->Uid,
    301 		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->LapicFlags);
    302 
    303 		break;
    304 
    305 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
    306 
    307 		aprint_normal_dev(self, "[MADT] %-15s: "
    308 		    "UID %u, LINT %u, FLAGS 0x%02X", "X2APIC NMI",
    309 		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->Uid,
    310 		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->Lint,
    311 		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->IntiFlags);
    312 
    313 		break;
    314 
    315 	default:
    316 		aprint_normal_dev(self, "[MADT] %-15s", "UNKNOWN");
    317 		break;
    318 	}
    319 
    320 	aprint_normal("\n");
    321 
    322 	return AE_OK;
    323 }
    324 
    325 static void
    326 acpi_print_fadt(struct acpi_softc *sc)
    327 {
    328 	uint32_t i;
    329 
    330 	/*
    331 	 * See ACPI 4.0, section 5.2.9.
    332 	 */
    333 	struct acpi_fadt {
    334 		uint32_t	 fadt_offset;
    335 		const char	*fadt_name;
    336 		uint64_t	 fadt_value;
    337 	};
    338 
    339 	const struct acpi_fadt acpi_fadt_table[] = {
    340 
    341 		{ 36,	"FACS",		 AcpiGbl_FADT.Facs		},
    342 		{ 40,	"DSDT",		 AcpiGbl_FADT.Dsdt		},
    343 		{ 44,	"INT_MODEL",	 AcpiGbl_FADT.Model		},
    344 		{ 45,	"PM_PROFILE",	 AcpiGbl_FADT.PreferredProfile	},
    345 		{ 46,	"SCI_INT",	 AcpiGbl_FADT.SciInterrupt	},
    346 		{ 48,	"SMI_CMD",	 AcpiGbl_FADT.SmiCommand	},
    347 		{ 52,	"ACPI_ENABLE",	 AcpiGbl_FADT.AcpiEnable	},
    348 		{ 53,	"ACPI_DISABLE",	 AcpiGbl_FADT.AcpiDisable	},
    349 		{ 54,	"S4BIOS_REQ",	 AcpiGbl_FADT.S4BiosRequest	},
    350 		{ 55,	"PSTATE_CNT",	 AcpiGbl_FADT.PstateControl	},
    351 		{ 56,	"PM1a_EVT_BLK",	 AcpiGbl_FADT.Pm1aEventBlock	},
    352 		{ 60,	"PM1b_EVT_BLK",	 AcpiGbl_FADT.Pm1bEventBlock	},
    353 		{ 64,	"PM1a_CNT_BLK",	 AcpiGbl_FADT.Pm1aControlBlock	},
    354 		{ 68,	"PM1b_CNT_BLK",	 AcpiGbl_FADT.Pm1bControlBlock	},
    355 		{ 72,	"PM2_CNT_BLK",	 AcpiGbl_FADT.Pm2ControlBlock	},
    356 		{ 76,	"PM_TMR_BLK",	 AcpiGbl_FADT.PmTimerBlock	},
    357 		{ 80,	"GPE0_BLK",	 AcpiGbl_FADT.Gpe0Block		},
    358 		{ 84,	"GPE1_BLK",	 AcpiGbl_FADT.Gpe1Block		},
    359 		{ 88,	"PM1_EVT_LEN",	 AcpiGbl_FADT.Pm1EventLength	},
    360 		{ 89,	"PM1_CNT_LEN",	 AcpiGbl_FADT.Pm1ControlLength	},
    361 		{ 90,	"PM2_CNT_LEN",	 AcpiGbl_FADT.Pm2ControlLength	},
    362 		{ 91,	"PM_TMR_LEN",	 AcpiGbl_FADT.PmTimerLength	},
    363 		{ 92,	"GPE0_BLK_LEN",	 AcpiGbl_FADT.Gpe0BlockLength	},
    364 		{ 93,	"GPE1_BLK_LEN",	 AcpiGbl_FADT.Gpe1BlockLength	},
    365 		{ 94,	"GPE1_BASE",	 AcpiGbl_FADT.Gpe1Base		},
    366 		{ 95,	"CST_CNT",	 AcpiGbl_FADT.CstControl	},
    367 		{ 96,	"P_LVL2_LAT",	 AcpiGbl_FADT.C2Latency		},
    368 		{ 98,	"P_LVL3_LAT",	 AcpiGbl_FADT.C3Latency		},
    369 		{ 100,	"FLUSH_SIZE",	 AcpiGbl_FADT.FlushSize		},
    370 		{ 102,	"FLUSH_STRIDE",	 AcpiGbl_FADT.FlushStride	},
    371 		{ 104,	"DUTY_OFFSET",	 AcpiGbl_FADT.DutyOffset	},
    372 		{ 105,	"DUTY_WIDTH",	 AcpiGbl_FADT.DutyWidth		},
    373 		{ 106,	"DAY_ALRM",	 AcpiGbl_FADT.DayAlarm		},
    374 		{ 107,	"MON_ALRM",	 AcpiGbl_FADT.MonthAlarm	},
    375 		{ 108,	"CENTURY",	 AcpiGbl_FADT.Century		},
    376 		{ 109,	"IAPC_BOOT_ARCH",AcpiGbl_FADT.BootFlags		},
    377 		{ 128,	"RESET_VALUE",	 AcpiGbl_FADT.ResetValue	},
    378 	};
    379 
    380 	const struct acpi_fadt acpi_fadt_flags[] = {
    381 
    382 		{ 0,	"WBINVD",	ACPI_FADT_WBINVD		},
    383 		{ 1,	"WBINVD_FLUSH",	ACPI_FADT_WBINVD_FLUSH		},
    384 		{ 2,	"PROC_C1",	ACPI_FADT_C1_SUPPORTED		},
    385 		{ 3,	"P_LVL2_UP",	ACPI_FADT_C2_MP_SUPPORTED	},
    386 		{ 4,	"PWR_BUTTON",	ACPI_FADT_POWER_BUTTON		},
    387 		{ 5,	"SLP_BUTTON",	ACPI_FADT_SLEEP_BUTTON		},
    388 		{ 6,	"FIX_RTC",	ACPI_FADT_FIXED_RTC		},
    389 		{ 7,	"RTC_S4",	ACPI_FADT_S4_RTC_WAKE		},
    390 		{ 8,	"TMR_VAL_EXT",	ACPI_FADT_32BIT_TIMER		},
    391 		{ 9,	"DCK_CAP",	ACPI_FADT_DOCKING_SUPPORTED	},
    392 		{ 10,	"RESET_REG_SUP",ACPI_FADT_RESET_REGISTER	},
    393 		{ 11,	"SEALED_CASE",	ACPI_FADT_SEALED_CASE		},
    394 		{ 12,	"HEADLESS",	ACPI_FADT_HEADLESS		},
    395 		{ 13,	"CPU_SW_SLP",	ACPI_FADT_SLEEP_TYPE		},
    396 		{ 14,	"PCI_EXP_WAK",	ACPI_FADT_PCI_EXPRESS_WAKE	},
    397 		{ 15,	"PLATFORM_CLK", ACPI_FADT_PLATFORM_CLOCK	},
    398 		{ 16,	"S4_RTC_STS",	ACPI_FADT_S4_RTC_VALID		},
    399 		{ 17,	"REMOTE_POWER", ACPI_FADT_REMOTE_POWER_ON	},
    400 		{ 18,	"APIC_CLUSTER",	ACPI_FADT_APIC_CLUSTER		},
    401 		{ 19,	"APIC_PHYSICAL",ACPI_FADT_APIC_PHYSICAL		},
    402 	};
    403 
    404 	for (i = 0; i < __arraycount(acpi_fadt_table); i++) {
    405 
    406 		aprint_normal_dev(sc->sc_dev,
    407 		    "[FADT] %-15s: 0x%016" PRIX64"\n",
    408 		    acpi_fadt_table[i].fadt_name,
    409 		    acpi_fadt_table[i].fadt_value);
    410 	}
    411 
    412 	for (i = 0; i < __arraycount(acpi_fadt_flags); i++) {
    413 
    414 		aprint_normal_dev(sc->sc_dev,
    415 		    "[FADT] %-15s: 0x%016" PRIX64"\n",
    416 		    acpi_fadt_flags[i].fadt_name, AcpiGbl_FADT.Flags &
    417 		    acpi_fadt_flags[i].fadt_value);
    418 
    419 		KASSERT(i ==  acpi_fadt_flags[i].fadt_offset);
    420 		KASSERT(__BIT(acpi_fadt_flags[i].fadt_offset) ==
    421 		              acpi_fadt_flags[i].fadt_value);
    422 	}
    423 }
    424 
    425 static void
    426 acpi_print_devnodes(struct acpi_softc *sc)
    427 {
    428 	struct acpi_devnode *ad;
    429 	ACPI_DEVICE_INFO *di;
    430 
    431 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
    432 
    433 		di = ad->ad_devinfo;
    434 		aprint_normal_dev(sc->sc_dev, "[%-4s] ", ad->ad_name);
    435 
    436 		aprint_normal("HID %-10s ",
    437 		    ((di->Valid & ACPI_VALID_HID) != 0) ?
    438 		    di->HardwareId.String: "-");
    439 
    440 		aprint_normal("UID %-4s ",
    441 		    ((di->Valid & ACPI_VALID_UID) != 0) ?
    442 		    di->UniqueId.String : "-");
    443 
    444 		if ((di->Valid & ACPI_VALID_STA) != 0)
    445 			aprint_normal("STA 0x%08X ", di->CurrentStatus);
    446 		else
    447 			aprint_normal("STA %10s ", "-");
    448 
    449 		if ((di->Valid & ACPI_VALID_ADR) != 0)
    450 			aprint_normal("ADR 0x%016" PRIX64"", di->Address);
    451 		else
    452 			aprint_normal("ADR -");
    453 
    454 		aprint_normal("\n");
    455 	}
    456 	aprint_normal("\n");
    457 }
    458 
    459 static void
    460 acpi_print_tree(struct acpi_devnode *ad, uint32_t level)
    461 {
    462 	struct acpi_devnode *child;
    463 	device_t pcidev;
    464 	uint32_t i;
    465 
    466 	for (i = 0; i < level; i++)
    467 		aprint_normal("    ");
    468 
    469 	aprint_normal("%-5s [%02u] [%c%c] ", ad->ad_name, ad->ad_type,
    470 	    ((ad->ad_flags & ACPI_DEVICE_POWER)  != 0) ? 'P' : ' ',
    471 	    ((ad->ad_flags & ACPI_DEVICE_WAKEUP) != 0) ? 'W' : ' ');
    472 
    473 	if (ad->ad_device != NULL)
    474 		aprint_normal("<%s> ", device_xname(ad->ad_device));
    475 
    476 	if (ad->ad_pciinfo != NULL) {
    477 
    478 		aprint_normal("(PCI) @ 0x%02X:0x%02X:0x%02X:0x%02X ",
    479 		    ad->ad_pciinfo->ap_segment, ad->ad_pciinfo->ap_bus,
    480 		    ad->ad_pciinfo->ap_device, ad->ad_pciinfo->ap_function);
    481 
    482 		if ((ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0)
    483 			aprint_normal("[R] ");
    484 
    485 		if (ad->ad_pciinfo->ap_bridge != false)
    486 			aprint_normal("[B] -> 0x%02X ",
    487 			    ad->ad_pciinfo->ap_downbus);
    488 
    489 		pcidev = device_find_by_acpi_pci_info(ad->ad_pciinfo);
    490 		if (pcidev != NULL)
    491 			aprint_normal("<%s>", device_xname(pcidev));
    492 	}
    493 
    494 	aprint_normal("\n");
    495 
    496 	SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list)
    497 	    acpi_print_tree(child, level + 1);
    498 }
    499 
    500 /*
    501  * device_find_by_acpi_pci_info:
    502  *
    503  *	Returns the device corresponding to the given PCI info, or NULL
    504  *	if it doesn't exist.
    505  */
    506 static device_t
    507 device_find_by_acpi_pci_info(const struct acpi_pci_info *ap)
    508 {
    509 	device_t dv, pr;
    510 	struct pci_softc *pci;
    511 	deviter_t di;
    512 
    513 	if (ap->ap_function == 0xFFFF)
    514 		return NULL;
    515 
    516 	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
    517 	     dv = deviter_next(&di)) {
    518 		pr = device_parent(dv);
    519 		if ((pr == NULL) || !device_is_a(pr, "pci"))
    520 			continue;
    521 		if (dv->dv_locators == NULL)	/* This should not happen. */
    522 			continue;
    523 		pci = device_private(pr);
    524 		if (pci->sc_bus == ap->ap_bus &&
    525 		    device_locator(dv, PCICF_DEV) == ap->ap_device &&
    526 		    device_locator(dv, PCICF_FUNCTION) == ap->ap_function)
    527 			break;
    528 	}
    529 	deviter_release(&di);
    530 
    531 	return dv;
    532 }
    533