4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2010, Intel Corporation.
24 * All rights reserved.
27 #include <sys/types.h>
28 #include <sys/atomic.h>
29 #include <sys/sunddi.h>
30 #include <sys/sunndi.h>
31 #include <sys/acpi/acpi.h>
32 #include <sys/acpica.h>
33 #include <sys/acpidev.h>
34 #include <sys/acpidev_rsc.h>
35 #include <sys/acpidev_dr.h>
36 #include <sys/acpidev_impl.h>
38 static ACPI_STATUS
acpidev_pci_probe(acpidev_walk_info_t
*infop
);
41 * Default class driver for PCI/PCIEX Host Bridge devices.
43 acpidev_class_t acpidev_class_pci
= {
45 ACPIDEV_CLASS_REV1
, /* adc_version */
46 ACPIDEV_CLASS_ID_PCI
, /* adc_class_id */
47 "PCI/PCIex Host Bridge", /* adc_class_name */
48 ACPIDEV_TYPE_PCI
, /* adc_dev_type */
49 NULL
, /* adc_private */
50 NULL
, /* adc_pre_probe */
51 NULL
, /* adc_post_probe */
52 acpidev_pci_probe
, /* adc_probe */
53 NULL
, /* adc_filter */
58 static char *acpidev_pci_device_ids
[] = {
59 ACPIDEV_HID_PCIEX_HOSTBRIDGE
,
60 ACPIDEV_HID_PCI_HOSTBRIDGE
,
63 static char *acpidev_pciex_device_ids
[] = {
64 ACPIDEV_HID_PCIEX_HOSTBRIDGE
,
68 acpidev_pci_update_status(acpidev_walk_info_t
*infop
)
71 dev_info_t
*dip
= NULL
;
72 acpidev_data_handle_t dhdl
;
74 dhdl
= infop
->awi_data
;
75 ASSERT((dhdl
->aod_iflag
& ACPIDEV_ODF_DEVINFO_CREATED
) == 0);
76 ASSERT((dhdl
->aod_iflag
& ACPIDEV_ODF_DEVINFO_TAGGED
) == 0);
77 if ((dhdl
->aod_iflag
& ACPIDEV_ODF_STATUS_VALID
) == 0) {
78 status
= acpidev_query_device_status(infop
->awi_hdl
);
79 dhdl
->aod_status
= status
;
80 dhdl
->aod_iflag
|= ACPIDEV_ODF_STATUS_VALID
;
82 status
= dhdl
->aod_status
;
84 dhdl
->aod_level
= infop
->awi_level
;
85 dhdl
->aod_hdl
= infop
->awi_hdl
;
86 dhdl
->aod_class
= NULL
;
87 dhdl
->aod_class_list
= NULL
;
88 if (acpidev_match_device_id(infop
->awi_info
,
89 ACPIDEV_ARRAY_PARAM(acpidev_pciex_device_ids
))) {
90 dhdl
->aod_class_id
= ACPIDEV_CLASS_ID_PCIEX
;
92 dhdl
->aod_class_id
= ACPIDEV_CLASS_ID_PCI
;
95 if (ACPI_FAILURE(acpica_get_devinfo(infop
->awi_hdl
, &dip
))) {
100 if (acpidev_check_device_enabled(status
)) {
102 * Mark the device as DISABLE if no device node created.
103 * BIOS may hide some special PCI/PCIex buses from OS.
106 dhdl
->aod_dip
= NULL
;
107 dhdl
->aod_status
&= ~ACPI_STA_DEVICE_ENABLED
;
110 dhdl
->aod_iflag
|= ACPIDEV_ODF_DEVINFO_CREATED
;
114 dhdl
->aod_dip
= NULL
;
115 dhdl
->aod_status
&= ~ACPI_STA_DEVICE_ENABLED
;
120 acpidev_pci_probe(acpidev_walk_info_t
*infop
)
122 ACPI_STATUS rc
= AE_OK
;
124 ASSERT(infop
!= NULL
);
125 ASSERT(infop
->awi_hdl
!= NULL
);
126 ASSERT(infop
->awi_info
!= NULL
);
127 if (infop
->awi_info
->Type
!= ACPI_TYPE_DEVICE
||
128 acpidev_match_device_id(infop
->awi_info
,
129 ACPIDEV_ARRAY_PARAM(acpidev_pci_device_ids
)) == B_FALSE
) {
133 if (acpica_get_devcfg_feature(ACPI_DEVCFG_PCI
) == 0) {
137 if (infop
->awi_op_type
== ACPIDEV_OP_BOOT_PROBE
) {
139 * Check hotplug capability on the first pass.
141 acpidev_dr_check(infop
);
142 } else if (infop
->awi_op_type
== ACPIDEV_OP_BOOT_REPROBE
) {
144 * Check whether the PCI device enumerator has created device
145 * nodes for PCI/PCIEX host bridges.
147 acpidev_pci_update_status(infop
);
148 } else if (infop
->awi_op_type
== ACPIDEV_OP_HOTPLUG_PROBE
) {
150 * No support of PCI/PCIEX host bridge hotplug yet.
151 * It will come in next phase.
154 "!acpidev: no support of PCI/PCIEX host bridge hotplug.");
156 * Don't block the hot-adding process, just skip it.
160 ACPIDEV_DEBUG(CE_WARN
, "!acpidev: unknown operation type %u "
161 "in acpidev_pci_probe().", infop
->awi_op_type
);
162 rc
= AE_BAD_PARAMETER
;
164 if (ACPI_FAILURE(rc
) && rc
!= AE_NOT_EXIST
&& rc
!= AE_ALREADY_EXISTS
) {
165 cmn_err(CE_CONT
, "?acpidev: failed to process PCI/PCIEX host "
166 "bridge object %s.\n", infop
->awi_name
);