Fri Feb 11 23:19:59 2022 UTC ()
acpi(9): No need to test dv_locators.

It is always initialized by config_devalloc before config_devlink
makes it visible to device iteration.  No need to reach into private
autoconf internals.


(riastradh)
diff -r1.34 -r1.35 src/sys/dev/acpi/acpi_pci.c

cvs diff -r1.34 -r1.35 src/sys/dev/acpi/acpi_pci.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_pci.c 2022/01/22 11:49:17 1.34
+++ src/sys/dev/acpi/acpi_pci.c 2022/02/11 23:19:59 1.35
@@ -1,582 +1,579 @@ @@ -1,582 +1,579 @@
1/* $NetBSD: acpi_pci.c,v 1.34 2022/01/22 11:49:17 thorpej Exp $ */ 1/* $NetBSD: acpi_pci.c,v 1.35 2022/02/11 23:19:59 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christoph Egger and Gregoire Sutre. 8 * by Christoph Egger and Gregoire Sutre.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. The name of the author may not be used to endorse or promote products 15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission. 16 * derived from this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.34 2022/01/22 11:49:17 thorpej Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.35 2022/02/11 23:19:59 riastradh Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/kmem.h> 36#include <sys/kmem.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38 38
39#include <dev/pci/pcireg.h> 39#include <dev/pci/pcireg.h>
40#include <dev/pci/pcivar.h> 40#include <dev/pci/pcivar.h>
41#include <dev/pci/pcidevs.h> 41#include <dev/pci/pcidevs.h>
42#include <dev/pci/ppbreg.h> 42#include <dev/pci/ppbreg.h>
43 43
44#include <dev/pci/pci_calls.h> 44#include <dev/pci/pci_calls.h>
45 45
46#include <dev/acpi/acpireg.h> 46#include <dev/acpi/acpireg.h>
47#include <dev/acpi/acpivar.h> 47#include <dev/acpi/acpivar.h>
48#include <dev/acpi/acpi_pci.h> 48#include <dev/acpi/acpi_pci.h>
49 49
50#include "locators.h" 50#include "locators.h"
51 51
52#define _COMPONENT ACPI_BUS_COMPONENT 52#define _COMPONENT ACPI_BUS_COMPONENT
53ACPI_MODULE_NAME ("acpi_pci") 53ACPI_MODULE_NAME ("acpi_pci")
54 54
55#define ACPI_HILODWORD(x) ACPI_HIWORD(ACPI_LODWORD((x))) 55#define ACPI_HILODWORD(x) ACPI_HIWORD(ACPI_LODWORD((x)))
56#define ACPI_LOLODWORD(x) ACPI_LOWORD(ACPI_LODWORD((x))) 56#define ACPI_LOLODWORD(x) ACPI_LOWORD(ACPI_LODWORD((x)))
57 57
58static ACPI_STATUS acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *, 58static ACPI_STATUS acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *,
59 void *); 59 void *);
60 60
61/* 61/*
62 * UUID for _DSM control method, from PCI Firmware Specification. 62 * UUID for _DSM control method, from PCI Firmware Specification.
63 */ 63 */
64static UINT8 acpi_pci_dsm_uuid[ACPI_UUID_LENGTH] = { 64static UINT8 acpi_pci_dsm_uuid[ACPI_UUID_LENGTH] = {
65 0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d, 65 0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d,
66 0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d 66 0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d
67}; 67};
68 68
69/* 69/*
70 * Regarding PCI Segment Groups (ACPI 4.0, p. 277): 70 * Regarding PCI Segment Groups (ACPI 4.0, p. 277):
71 * 71 *
72 * "The optional _SEG object is located under a PCI host bridge and 72 * "The optional _SEG object is located under a PCI host bridge and
73 * evaluates to an integer that describes the PCI Segment Group (see PCI 73 * evaluates to an integer that describes the PCI Segment Group (see PCI
74 * Firmware Specification v3.0)." 74 * Firmware Specification v3.0)."
75 * 75 *
76 * "PCI Segment Group is purely a software concept managed by system 76 * "PCI Segment Group is purely a software concept managed by system
77 * firmware and used by OSPM. It is a logical collection of PCI buses 77 * firmware and used by OSPM. It is a logical collection of PCI buses
78 * (or bus segments). It is a way to logically group the PCI bus segments 78 * (or bus segments). It is a way to logically group the PCI bus segments
79 * and PCI Express Hierarchies. _SEG is a level higher than _BBN." 79 * and PCI Express Hierarchies. _SEG is a level higher than _BBN."
80 * 80 *
81 * "PCI Segment Group supports more than 256 buses in a system by allowing 81 * "PCI Segment Group supports more than 256 buses in a system by allowing
82 * the reuse of the PCI bus numbers. Within each PCI Segment Group, the bus 82 * the reuse of the PCI bus numbers. Within each PCI Segment Group, the bus
83 * numbers for the PCI buses must be unique. PCI buses in different PCI 83 * numbers for the PCI buses must be unique. PCI buses in different PCI
84 * Segment Group are permitted to have the same bus number." 84 * Segment Group are permitted to have the same bus number."
85 */ 85 */
86 86
87/* 87/*
88 * Regarding PCI Base Bus Numbers (ACPI 4.0, p. 277): 88 * Regarding PCI Base Bus Numbers (ACPI 4.0, p. 277):
89 * 89 *
90 * "For multi-root PCI platforms, the _BBN object evaluates to the PCI bus 90 * "For multi-root PCI platforms, the _BBN object evaluates to the PCI bus
91 * number that the BIOS assigns. This is needed to access a PCI_Config 91 * number that the BIOS assigns. This is needed to access a PCI_Config
92 * operation region for the specified bus. The _BBN object is located under 92 * operation region for the specified bus. The _BBN object is located under
93 * a PCI host bridge and must be unique for every host bridge within a 93 * a PCI host bridge and must be unique for every host bridge within a
94 * segment since it is the PCI bus number." 94 * segment since it is the PCI bus number."
95 * 95 *
96 * Moreover, the ACPI FAQ (http://www.acpi.info/acpi_faq.htm) says: 96 * Moreover, the ACPI FAQ (http://www.acpi.info/acpi_faq.htm) says:
97 * 97 *
98 * "For a multiple root bus machine, _BBN is required for each bus. _BBN 98 * "For a multiple root bus machine, _BBN is required for each bus. _BBN
99 * should provide the bus number assigned to this bus by the BIOS at boot 99 * should provide the bus number assigned to this bus by the BIOS at boot
100 * time." 100 * time."
101 */ 101 */
102 102
103/* 103/*
104 * acpi_pcidev_pciroot_bus: 104 * acpi_pcidev_pciroot_bus:
105 * 105 *
106 * Derive the PCI bus number of a PCI root bridge from its resources. 106 * Derive the PCI bus number of a PCI root bridge from its resources.
107 * If successful, return AE_OK and fill *busp. Otherwise, return an 107 * If successful, return AE_OK and fill *busp. Otherwise, return an
108 * exception code and leave *busp unchanged. 108 * exception code and leave *busp unchanged.
109 */ 109 */
110ACPI_STATUS 110ACPI_STATUS
111acpi_pcidev_pciroot_bus(ACPI_HANDLE handle, uint16_t *busp) 111acpi_pcidev_pciroot_bus(ACPI_HANDLE handle, uint16_t *busp)
112{ 112{
113 ACPI_STATUS rv; 113 ACPI_STATUS rv;
114 int32_t bus; 114 int32_t bus;
115 115
116 bus = -1; 116 bus = -1;
117 117
118 /* 118 /*
119 * XXX: Use the ACPI resource parsing functions (acpi_resource.c) 119 * XXX: Use the ACPI resource parsing functions (acpi_resource.c)
120 * once bus number ranges have been implemented there. 120 * once bus number ranges have been implemented there.
121 */ 121 */
122 rv = AcpiWalkResources(handle, "_CRS", 122 rv = AcpiWalkResources(handle, "_CRS",
123 acpi_pcidev_pciroot_bus_callback, &bus); 123 acpi_pcidev_pciroot_bus_callback, &bus);
124 124
125 if (ACPI_FAILURE(rv)) 125 if (ACPI_FAILURE(rv))
126 return rv; 126 return rv;
127 127
128 if (bus == -1) 128 if (bus == -1)
129 return AE_NOT_EXIST; 129 return AE_NOT_EXIST;
130 130
131 /* Here it holds that 0 <= bus <= 0xFFFF. */ 131 /* Here it holds that 0 <= bus <= 0xFFFF. */
132 *busp = (uint16_t)bus; 132 *busp = (uint16_t)bus;
133 133
134 return rv; 134 return rv;
135} 135}
136 136
137static ACPI_STATUS 137static ACPI_STATUS
138acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *res, void *context) 138acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *res, void *context)
139{ 139{
140 ACPI_RESOURCE_ADDRESS64 addr64; 140 ACPI_RESOURCE_ADDRESS64 addr64;
141 int32_t *bus = context; 141 int32_t *bus = context;
142 142
143 /* Always continue the walk by returning AE_OK. */ 143 /* Always continue the walk by returning AE_OK. */
144 if ((res->Type != ACPI_RESOURCE_TYPE_ADDRESS16) && 144 if ((res->Type != ACPI_RESOURCE_TYPE_ADDRESS16) &&
145 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS32) && 145 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS32) &&
146 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS64)) 146 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS64))
147 return AE_OK; 147 return AE_OK;
148 148
149 if (ACPI_FAILURE(AcpiResourceToAddress64(res, &addr64))) 149 if (ACPI_FAILURE(AcpiResourceToAddress64(res, &addr64)))
150 return AE_OK; 150 return AE_OK;
151 151
152 if (addr64.ResourceType != ACPI_BUS_NUMBER_RANGE) 152 if (addr64.ResourceType != ACPI_BUS_NUMBER_RANGE)
153 return AE_OK; 153 return AE_OK;
154 154
155 if (*bus != -1) 155 if (*bus != -1)
156 return AE_ALREADY_EXISTS; 156 return AE_ALREADY_EXISTS;
157 157
158 if (addr64.Address.Minimum > 0xFFFF) 158 if (addr64.Address.Minimum > 0xFFFF)
159 return AE_BAD_DATA; 159 return AE_BAD_DATA;
160 160
161 *bus = (int32_t)addr64.Address.Minimum; 161 *bus = (int32_t)addr64.Address.Minimum;
162 162
163 return AE_OK; 163 return AE_OK;
164} 164}
165 165
166/* 166/*
167 * acpi_pcidev_scan: 167 * acpi_pcidev_scan:
168 * 168 *
169 * Scan the ACPI device tree for PCI devices. A node is detected as a 169 * Scan the ACPI device tree for PCI devices. A node is detected as a
170 * PCI device if it has an ancestor that is a PCI root bridge and such 170 * PCI device if it has an ancestor that is a PCI root bridge and such
171 * that all intermediate nodes are PCI-to-PCI bridges. Depth-first 171 * that all intermediate nodes are PCI-to-PCI bridges. Depth-first
172 * recursive implementation. 172 * recursive implementation.
173 * 173 *
174 * PCI root bridges do not necessarily contain an _ADR, since they already 174 * PCI root bridges do not necessarily contain an _ADR, since they already
175 * contain an _HID (ACPI 4.0a, p. 197). However we require an _ADR for 175 * contain an _HID (ACPI 4.0a, p. 197). However we require an _ADR for
176 * all non-root PCI devices. 176 * all non-root PCI devices.
177 */ 177 */
178ACPI_STATUS 178ACPI_STATUS
179acpi_pcidev_scan(struct acpi_devnode *ad) 179acpi_pcidev_scan(struct acpi_devnode *ad)
180{ 180{
181 struct acpi_devnode *child; 181 struct acpi_devnode *child;
182 struct acpi_pci_info *ap; 182 struct acpi_pci_info *ap;
183 ACPI_INTEGER val; 183 ACPI_INTEGER val;
184 ACPI_STATUS rv; 184 ACPI_STATUS rv;
185 185
186 ad->ad_pciinfo = NULL; 186 ad->ad_pciinfo = NULL;
187 187
188 /* 188 /*
189 * We attach PCI information only to devices that are present, 189 * We attach PCI information only to devices that are present,
190 * enabled, and functioning properly. 190 * enabled, and functioning properly.
191 * Note: there is a possible race condition, because _STA may 191 * Note: there is a possible race condition, because _STA may
192 * have changed since ad->ad_devinfo->CurrentStatus was set. 192 * have changed since ad->ad_devinfo->CurrentStatus was set.
193 */ 193 */
194 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) 194 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
195 goto rec; 195 goto rec;
196 196
197 if (!acpi_device_present(ad->ad_handle)) 197 if (!acpi_device_present(ad->ad_handle))
198 goto rec; 198 goto rec;
199 199
200 if (ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) { 200 if (ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) {
201 201
202 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); 202 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP);
203 203
204 /* 204 /*
205 * If no _SEG exist, all PCI bus segments are assumed 205 * If no _SEG exist, all PCI bus segments are assumed
206 * to be in the PCI segment group 0 (ACPI 4.0, p. 277). 206 * to be in the PCI segment group 0 (ACPI 4.0, p. 277).
207 * The segment group number is conveyed in the lower 207 * The segment group number is conveyed in the lower
208 * 16 bits of _SEG (the other bits are all reserved). 208 * 16 bits of _SEG (the other bits are all reserved).
209 */ 209 */
210 rv = acpi_eval_integer(ad->ad_handle, "_SEG", &val); 210 rv = acpi_eval_integer(ad->ad_handle, "_SEG", &val);
211 211
212 if (ACPI_SUCCESS(rv)) 212 if (ACPI_SUCCESS(rv))
213 ap->ap_segment = ACPI_LOWORD(val); 213 ap->ap_segment = ACPI_LOWORD(val);
214 214
215 /* Try to get downstream bus number using _CRS first. */ 215 /* Try to get downstream bus number using _CRS first. */
216 rv = acpi_pcidev_pciroot_bus(ad->ad_handle, &ap->ap_downbus); 216 rv = acpi_pcidev_pciroot_bus(ad->ad_handle, &ap->ap_downbus);
217 217
218 if (ACPI_FAILURE(rv)) { 218 if (ACPI_FAILURE(rv)) {
219 rv = acpi_eval_integer(ad->ad_handle, "_BBN", &val); 219 rv = acpi_eval_integer(ad->ad_handle, "_BBN", &val);
220 220
221 if (ACPI_SUCCESS(rv)) 221 if (ACPI_SUCCESS(rv))
222 ap->ap_downbus = ACPI_LOWORD(val); 222 ap->ap_downbus = ACPI_LOWORD(val);
223 } 223 }
224 224
225 if (ap->ap_downbus > 255) { 225 if (ap->ap_downbus > 255) {
226 aprint_error_dev(ad->ad_root, 226 aprint_error_dev(ad->ad_root,
227 "invalid PCI downstream bus for %s\n", ad->ad_name); 227 "invalid PCI downstream bus for %s\n", ad->ad_name);
228 kmem_free(ap, sizeof(*ap)); 228 kmem_free(ap, sizeof(*ap));
229 goto rec; 229 goto rec;
230 } 230 }
231 231
232 ap->ap_flags |= ACPI_PCI_INFO_BRIDGE; 232 ap->ap_flags |= ACPI_PCI_INFO_BRIDGE;
233 233
234 ap->ap_pc = acpi_get_pci_chipset_tag(acpi_softc, ap->ap_segment, ap->ap_downbus); 234 ap->ap_pc = acpi_get_pci_chipset_tag(acpi_softc, ap->ap_segment, ap->ap_downbus);
235 235
236 /* 236 /*
237 * This ACPI node denotes a PCI root bridge, but it may also 237 * This ACPI node denotes a PCI root bridge, but it may also
238 * denote a PCI device on the bridge's downstream bus segment. 238 * denote a PCI device on the bridge's downstream bus segment.
239 */ 239 */
240 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR) { 240 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR) {
241 ap->ap_bus = ap->ap_downbus; 241 ap->ap_bus = ap->ap_downbus;
242 ap->ap_device = 242 ap->ap_device =
243 ACPI_HILODWORD(ad->ad_devinfo->Address); 243 ACPI_HILODWORD(ad->ad_devinfo->Address);
244 ap->ap_function = 244 ap->ap_function =
245 ACPI_LOLODWORD(ad->ad_devinfo->Address); 245 ACPI_LOLODWORD(ad->ad_devinfo->Address);
246 246
247 if (ap->ap_device > 31 || 247 if (ap->ap_device > 31 ||
248 (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) 248 (ap->ap_function > 7 && ap->ap_function != 0xFFFF))
249 aprint_error_dev(ad->ad_root, 249 aprint_error_dev(ad->ad_root,
250 "invalid PCI address for %s\n", ad->ad_name); 250 "invalid PCI address for %s\n", ad->ad_name);
251 else 251 else
252 ap->ap_flags |= ACPI_PCI_INFO_DEVICE; 252 ap->ap_flags |= ACPI_PCI_INFO_DEVICE;
253 } 253 }
254 254
255 ad->ad_pciinfo = ap; 255 ad->ad_pciinfo = ap;
256 256
257 goto rec; 257 goto rec;
258 } 258 }
259 259
260 if ((ad->ad_parent != NULL) && 260 if ((ad->ad_parent != NULL) &&
261 (ad->ad_parent->ad_pciinfo != NULL) && 261 (ad->ad_parent->ad_pciinfo != NULL) &&
262 (ad->ad_parent->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) && 262 (ad->ad_parent->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) &&
263 (ad->ad_devinfo->Valid & ACPI_VALID_ADR)) { 263 (ad->ad_devinfo->Valid & ACPI_VALID_ADR)) {
264 264
265 /* 265 /*
266 * Our parent is a PCI root bridge or a PCI-to-PCI 266 * Our parent is a PCI root bridge or a PCI-to-PCI
267 * bridge. We have the same PCI segment number, and 267 * bridge. We have the same PCI segment number, and
268 * our bus number is its downstream bus number. 268 * our bus number is its downstream bus number.
269 */ 269 */
270 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); 270 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP);
271 271
272 ap->ap_pc = ad->ad_parent->ad_pciinfo->ap_pc; 272 ap->ap_pc = ad->ad_parent->ad_pciinfo->ap_pc;
273 ap->ap_segment = ad->ad_parent->ad_pciinfo->ap_segment; 273 ap->ap_segment = ad->ad_parent->ad_pciinfo->ap_segment;
274 ap->ap_bus = ad->ad_parent->ad_pciinfo->ap_downbus; 274 ap->ap_bus = ad->ad_parent->ad_pciinfo->ap_downbus;
275 275
276 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address); 276 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address);
277 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address); 277 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address);
278 278
279 if (ap->ap_device > 31 || 279 if (ap->ap_device > 31 ||
280 (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) { 280 (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) {
281 aprint_error_dev(ad->ad_root, 281 aprint_error_dev(ad->ad_root,
282 "invalid PCI address for %s\n", ad->ad_name); 282 "invalid PCI address for %s\n", ad->ad_name);
283 kmem_free(ap, sizeof(*ap)); 283 kmem_free(ap, sizeof(*ap));
284 goto rec; 284 goto rec;
285 } 285 }
286 286
287 ap->ap_flags |= ACPI_PCI_INFO_DEVICE; 287 ap->ap_flags |= ACPI_PCI_INFO_DEVICE;
288 288
289 if (ap->ap_function == 0xFFFF) { 289 if (ap->ap_function == 0xFFFF) {
290 /* 290 /*
291 * Assume that this device is not a PCI-to-PCI bridge. 291 * Assume that this device is not a PCI-to-PCI bridge.
292 * XXX: Do we need to be smarter? 292 * XXX: Do we need to be smarter?
293 */ 293 */
294 } else { 294 } else {
295 /* 295 /*
296 * Check whether this device is a PCI-to-PCI 296 * Check whether this device is a PCI-to-PCI
297 * bridge and get its secondary bus number. 297 * bridge and get its secondary bus number.
298 */ 298 */
299 rv = acpi_pcidev_ppb_downbus( 299 rv = acpi_pcidev_ppb_downbus(
300 ad->ad_parent->ad_pciinfo->ap_pc, 300 ad->ad_parent->ad_pciinfo->ap_pc,
301 ap->ap_segment, ap->ap_bus, ap->ap_device, 301 ap->ap_segment, ap->ap_bus, ap->ap_device,
302 ap->ap_function, &ap->ap_downbus); 302 ap->ap_function, &ap->ap_downbus);
303 303
304 if (ACPI_SUCCESS(rv)) 304 if (ACPI_SUCCESS(rv))
305 ap->ap_flags |= ACPI_PCI_INFO_BRIDGE; 305 ap->ap_flags |= ACPI_PCI_INFO_BRIDGE;
306 } 306 }
307 307
308 ad->ad_pciinfo = ap; 308 ad->ad_pciinfo = ap;
309 309
310 goto rec; 310 goto rec;
311 } 311 }
312 312
313rec: 313rec:
314 SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list) { 314 SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list) {
315 rv = acpi_pcidev_scan(child); 315 rv = acpi_pcidev_scan(child);
316 316
317 if (ACPI_FAILURE(rv)) 317 if (ACPI_FAILURE(rv))
318 return rv; 318 return rv;
319 } 319 }
320 320
321 return AE_OK; 321 return AE_OK;
322} 322}
323 323
324/* 324/*
325 * acpi_pcidev_ppb_downbus: 325 * acpi_pcidev_ppb_downbus:
326 * 326 *
327 * Retrieve the secondary bus number of the PCI-to-PCI bridge having the 327 * Retrieve the secondary bus number of the PCI-to-PCI bridge having the
328 * given PCI id. If successful, return AE_OK and fill *downbus. 328 * given PCI id. If successful, return AE_OK and fill *downbus.
329 * Otherwise, return an exception code and leave *downbus unchanged. 329 * Otherwise, return an exception code and leave *downbus unchanged.
330 * 330 *
331 * XXX Need to deal with PCI segment groups (see also acpica/OsdHardware.c). 331 * XXX Need to deal with PCI segment groups (see also acpica/OsdHardware.c).
332 */ 332 */
333ACPI_STATUS 333ACPI_STATUS
334acpi_pcidev_ppb_downbus(pci_chipset_tag_t pc, uint16_t segment, uint16_t bus, 334acpi_pcidev_ppb_downbus(pci_chipset_tag_t pc, uint16_t segment, uint16_t bus,
335 uint16_t device, uint16_t function, uint16_t *downbus) 335 uint16_t device, uint16_t function, uint16_t *downbus)
336{ 336{
337 pcitag_t tag; 337 pcitag_t tag;
338 pcireg_t val; 338 pcireg_t val;
339 339
340 if (bus > 255 || device > 31 || function > 7) 340 if (bus > 255 || device > 31 || function > 7)
341 return AE_BAD_PARAMETER; 341 return AE_BAD_PARAMETER;
342 342
343 tag = pci_make_tag(pc, bus, device, function); 343 tag = pci_make_tag(pc, bus, device, function);
344 344
345 /* Check that this device exists. */ 345 /* Check that this device exists. */
346 val = pci_conf_read(pc, tag, PCI_ID_REG); 346 val = pci_conf_read(pc, tag, PCI_ID_REG);
347 347
348 if (PCI_VENDOR(val) == PCI_VENDOR_INVALID || 348 if (PCI_VENDOR(val) == PCI_VENDOR_INVALID ||
349 PCI_VENDOR(val) == 0) 349 PCI_VENDOR(val) == 0)
350 return AE_NOT_EXIST; 350 return AE_NOT_EXIST;
351 351
352 /* Check that this device is a PCI-to-PCI bridge. */ 352 /* Check that this device is a PCI-to-PCI bridge. */
353 val = pci_conf_read(pc, tag, PCI_BHLC_REG); 353 val = pci_conf_read(pc, tag, PCI_BHLC_REG);
354 354
355 if (PCI_HDRTYPE_TYPE(val) != PCI_HDRTYPE_PPB) 355 if (PCI_HDRTYPE_TYPE(val) != PCI_HDRTYPE_PPB)
356 return AE_TYPE; 356 return AE_TYPE;
357 357
358 /* This is a PCI-to-PCI bridge. Get its secondary bus#. */ 358 /* This is a PCI-to-PCI bridge. Get its secondary bus#. */
359 val = pci_conf_read(pc, tag, PCI_BRIDGE_BUS_REG); 359 val = pci_conf_read(pc, tag, PCI_BRIDGE_BUS_REG);
360 *downbus = PCI_BRIDGE_BUS_NUM_SECONDARY(val); 360 *downbus = PCI_BRIDGE_BUS_NUM_SECONDARY(val);
361 361
362 return AE_OK; 362 return AE_OK;
363} 363}
364 364
365/* 365/*
366 * acpi_pcidev_find: 366 * acpi_pcidev_find:
367 * 367 *
368 * Finds a PCI device in the ACPI name space. 368 * Finds a PCI device in the ACPI name space.
369 * 369 *
370 * Returns an ACPI device node on success and NULL on failure. 370 * Returns an ACPI device node on success and NULL on failure.
371 */ 371 */
372struct acpi_devnode * 372struct acpi_devnode *
373acpi_pcidev_find(uint16_t segment, uint16_t bus, 373acpi_pcidev_find(uint16_t segment, uint16_t bus,
374 uint16_t device, uint16_t function) 374 uint16_t device, uint16_t function)
375{ 375{
376 struct acpi_softc *sc = acpi_softc; 376 struct acpi_softc *sc = acpi_softc;
377 struct acpi_devnode *ad; 377 struct acpi_devnode *ad;
378 378
379 if (sc == NULL) 379 if (sc == NULL)
380 return NULL; 380 return NULL;
381 381
382 SIMPLEQ_FOREACH(ad, &sc->sc_head, ad_list) { 382 SIMPLEQ_FOREACH(ad, &sc->sc_head, ad_list) {
383 383
384 if (ad->ad_pciinfo != NULL && 384 if (ad->ad_pciinfo != NULL &&
385 (ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_DEVICE) && 385 (ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_DEVICE) &&
386 ad->ad_pciinfo->ap_segment == segment && 386 ad->ad_pciinfo->ap_segment == segment &&
387 ad->ad_pciinfo->ap_bus == bus && 387 ad->ad_pciinfo->ap_bus == bus &&
388 ad->ad_pciinfo->ap_device == device && 388 ad->ad_pciinfo->ap_device == device &&
389 ad->ad_pciinfo->ap_function == function) 389 ad->ad_pciinfo->ap_function == function)
390 return ad; 390 return ad;
391 } 391 }
392 392
393 return NULL; 393 return NULL;
394} 394}
395 395
396/* 396/*
397 * acpi_pcidev_get_tag: 397 * acpi_pcidev_get_tag:
398 * 398 *
399 * Returns a PCI chipset tag for a PCI device in the ACPI name space. 399 * Returns a PCI chipset tag for a PCI device in the ACPI name space.
400 */ 400 */
401pci_chipset_tag_t 401pci_chipset_tag_t
402acpi_pcidev_get_tag(uint16_t segment, uint16_t bus, 402acpi_pcidev_get_tag(uint16_t segment, uint16_t bus,
403 uint16_t device, uint16_t function) 403 uint16_t device, uint16_t function)
404{ 404{
405 struct acpi_devnode *ad; 405 struct acpi_devnode *ad;
406 406
407 ad = acpi_pcidev_find(segment, bus, device, function); 407 ad = acpi_pcidev_find(segment, bus, device, function);
408 if (ad == NULL || ad->ad_pciinfo == NULL) 408 if (ad == NULL || ad->ad_pciinfo == NULL)
409 return NULL; 409 return NULL;
410 410
411 return ad->ad_pciinfo->ap_pc; 411 return ad->ad_pciinfo->ap_pc;
412} 412}
413 413
414/* 414/*
415 * acpi_pciroot_find: 415 * acpi_pciroot_find:
416 * 416 *
417 * Finds a PCI root bridge in the ACPI name space. 417 * Finds a PCI root bridge in the ACPI name space.
418 * 418 *
419 * Returns an ACPI device node on success and NULL on failure. 419 * Returns an ACPI device node on success and NULL on failure.
420 */ 420 */
421struct acpi_devnode * 421struct acpi_devnode *
422acpi_pciroot_find(uint16_t segment, uint16_t bus) 422acpi_pciroot_find(uint16_t segment, uint16_t bus)
423{ 423{
424 struct acpi_softc *sc = acpi_softc; 424 struct acpi_softc *sc = acpi_softc;
425 struct acpi_devnode *ad; 425 struct acpi_devnode *ad;
426 426
427 if (sc == NULL) 427 if (sc == NULL)
428 return NULL; 428 return NULL;
429 429
430 SIMPLEQ_FOREACH(ad, &sc->sc_head, ad_list) { 430 SIMPLEQ_FOREACH(ad, &sc->sc_head, ad_list) {
431 431
432 if (ad->ad_pciinfo != NULL && 432 if (ad->ad_pciinfo != NULL &&
433 (ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) && 433 (ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) &&
434 ad->ad_pciinfo->ap_segment == segment && 434 ad->ad_pciinfo->ap_segment == segment &&
435 ad->ad_pciinfo->ap_bus == bus) 435 ad->ad_pciinfo->ap_bus == bus)
436 return ad; 436 return ad;
437 } 437 }
438 438
439 return NULL; 439 return NULL;
440} 440}
441 441
442/* 442/*
443 * acpi_pcidev_find_dev: 443 * acpi_pcidev_find_dev:
444 * 444 *
445 * Returns the device corresponding to the given PCI info, or NULL 445 * Returns the device corresponding to the given PCI info, or NULL
446 * if it doesn't exist. 446 * if it doesn't exist.
447 */ 447 */
448device_t 448device_t
449acpi_pcidev_find_dev(struct acpi_devnode *ad) 449acpi_pcidev_find_dev(struct acpi_devnode *ad)
450{ 450{
451 struct acpi_pci_info *ap; 451 struct acpi_pci_info *ap;
452 struct pci_softc *pci; 452 struct pci_softc *pci;
453 device_t dv, pr; 453 device_t dv, pr;
454 deviter_t di; 454 deviter_t di;
455 455
456 if (ad == NULL) 456 if (ad == NULL)
457 return NULL; 457 return NULL;
458 458
459 if (ad->ad_pciinfo == NULL) 459 if (ad->ad_pciinfo == NULL)
460 return NULL; 460 return NULL;
461 461
462 ap = ad->ad_pciinfo; 462 ap = ad->ad_pciinfo;
463 463
464 if (ap->ap_function == 0xFFFF) 464 if (ap->ap_function == 0xFFFF)
465 return NULL; 465 return NULL;
466 466
467 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); 467 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
468 dv != NULL; dv = deviter_next(&di)) { 468 dv != NULL; dv = deviter_next(&di)) {
469 469
470 pr = device_parent(dv); 470 pr = device_parent(dv);
471 471
472 if (pr == NULL || device_is_a(pr, "pci") != true) 472 if (pr == NULL || device_is_a(pr, "pci") != true)
473 continue; 473 continue;
474 474
475 if (dv->dv_locators == NULL) /* This should not happen. */ 
476 continue; 
477 
478 pci = device_private(pr); 475 pci = device_private(pr);
479 476
480 if (pci->sc_bus == ap->ap_bus && 477 if (pci->sc_bus == ap->ap_bus &&
481 device_locator(dv, PCICF_DEV) == ap->ap_device && 478 device_locator(dv, PCICF_DEV) == ap->ap_device &&
482 device_locator(dv, PCICF_FUNCTION) == ap->ap_function) 479 device_locator(dv, PCICF_FUNCTION) == ap->ap_function)
483 break; 480 break;
484 } 481 }
485 482
486 deviter_release(&di); 483 deviter_release(&di);
487 484
488 return dv; 485 return dv;
489} 486}
490 487
491/* 488/*
492 * acpi_pci_ignore_boot_config: 489 * acpi_pci_ignore_boot_config:
493 * 490 *
494 * Returns 1 if the operating system may ignore the boot configuration 491 * Returns 1 if the operating system may ignore the boot configuration
495 * of PCI resources. 492 * of PCI resources.
496 */ 493 */
497ACPI_INTEGER 494ACPI_INTEGER
498acpi_pci_ignore_boot_config(ACPI_HANDLE handle) 495acpi_pci_ignore_boot_config(ACPI_HANDLE handle)
499{ 496{
500 ACPI_OBJECT *pobj = NULL; 497 ACPI_OBJECT *pobj = NULL;
501 ACPI_INTEGER ret; 498 ACPI_INTEGER ret;
502 499
503 /* 500 /*
504 * This one is a little confusing, but the result of 501 * This one is a little confusing, but the result of
505 * evaluating _DSM #5 is: 502 * evaluating _DSM #5 is:
506 * 503 *
507 * 0: The operating system may not ignore the boot configuration 504 * 0: The operating system may not ignore the boot configuration
508 * of PCI resources. 505 * of PCI resources.
509 * 506 *
510 * 1: The operating system may ignore the boot configuration of 507 * 1: The operating system may ignore the boot configuration of
511 * PCI resources, and reconfigure or rebalance these resources 508 * PCI resources, and reconfigure or rebalance these resources
512 * in the hierarchy as required. 509 * in the hierarchy as required.
513 */ 510 */
514 511
515 if (ACPI_FAILURE(acpi_dsm(handle, acpi_pci_dsm_uuid, 512 if (ACPI_FAILURE(acpi_dsm(handle, acpi_pci_dsm_uuid,
516 1, 5, NULL, &pobj))) { 513 1, 5, NULL, &pobj))) {
517 /* 514 /*
518 * In the absence of _DSM #5, we may assume that the 515 * In the absence of _DSM #5, we may assume that the
519 * boot config can be ignored. 516 * boot config can be ignored.
520 */ 517 */
521 return 1; 518 return 1;
522 } 519 }
523 520
524 /* 521 /*
525 * ...and we default to "may ignore" in the event that the 522 * ...and we default to "may ignore" in the event that the
526 * method returns nonsense. 523 * method returns nonsense.
527 */ 524 */
528 ret = 1; 525 ret = 1;
529 526
530 if (pobj != NULL) { 527 if (pobj != NULL) {
531 switch (pobj->Type) { 528 switch (pobj->Type) {
532 case ACPI_TYPE_INTEGER: 529 case ACPI_TYPE_INTEGER:
533 ret = pobj->Integer.Value; 530 ret = pobj->Integer.Value;
534 break; 531 break;
535 532
536 case ACPI_TYPE_PACKAGE: 533 case ACPI_TYPE_PACKAGE:
537 if (pobj->Package.Count == 1 && 534 if (pobj->Package.Count == 1 &&
538 pobj->Package.Elements[0].Type == ACPI_TYPE_INTEGER) 535 pobj->Package.Elements[0].Type == ACPI_TYPE_INTEGER)
539 ret = pobj->Package.Elements[0].Integer.Value; 536 ret = pobj->Package.Elements[0].Integer.Value;
540 break; 537 break;
541 } 538 }
542 ACPI_FREE(pobj); 539 ACPI_FREE(pobj);
543 } 540 }
544 541
545 return ret; 542 return ret;
546} 543}
547 544
548/* 545/*
549 * acpi_pci_bus_get_child_devhandle: 546 * acpi_pci_bus_get_child_devhandle:
550 * 547 *
551 * Implements the "pci-bus-get-child-devhandle" device call for 548 * Implements the "pci-bus-get-child-devhandle" device call for
552 * ACPI device handles 549 * ACPI device handles
553 */ 550 */
554static int 551static int
555acpi_pci_bus_get_child_devhandle(device_t dev, devhandle_t call_handle, void *v) 552acpi_pci_bus_get_child_devhandle(device_t dev, devhandle_t call_handle, void *v)
556{ 553{
557 struct pci_bus_get_child_devhandle_args *args = v; 554 struct pci_bus_get_child_devhandle_args *args = v;
558 struct acpi_devnode *ad; 555 struct acpi_devnode *ad;
559 ACPI_HANDLE hdl; 556 ACPI_HANDLE hdl;
560 int b, d, f; 557 int b, d, f;
561 u_int segment; 558 u_int segment;
562 559
563#ifdef __HAVE_PCI_GET_SEGMENT 560#ifdef __HAVE_PCI_GET_SEGMENT
564 segment = pci_get_segment(args->pc); 561 segment = pci_get_segment(args->pc);
565#else 562#else
566 segment = 0; 563 segment = 0;
567#endif /* __HAVE_PCI_GET_SEGMENT */ 564#endif /* __HAVE_PCI_GET_SEGMENT */
568 565
569 pci_decompose_tag(args->pc, args->tag, &b, &d, &f); 566 pci_decompose_tag(args->pc, args->tag, &b, &d, &f);
570 567
571 ad = acpi_pcidev_find(segment, b, d, f); 568 ad = acpi_pcidev_find(segment, b, d, f);
572 569
573 if (ad != NULL && (hdl = ad->ad_handle) != NULL) { 570 if (ad != NULL && (hdl = ad->ad_handle) != NULL) {
574 /* Found it! */ 571 /* Found it! */
575 args->devhandle = devhandle_from_acpi(call_handle, hdl); 572 args->devhandle = devhandle_from_acpi(call_handle, hdl);
576 return 0; 573 return 0;
577 } 574 }
578 575
579 return ENODEV; 576 return ENODEV;
580} 577}
581ACPI_DEVICE_CALL_REGISTER(PCI_BUS_GET_CHILD_DEVHANDLE_STR, 578ACPI_DEVICE_CALL_REGISTER(PCI_BUS_GET_CHILD_DEVHANDLE_STR,
582 acpi_pci_bus_get_child_devhandle) 579 acpi_pci_bus_get_child_devhandle)