xref: /illumos-gate/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2019 Joyent, Inc.
24  * Copyright 2023 Oxide Computer Company
25  */
26 
27 /*
28  *     PCI configurator (pcicfg)
29  */
30 
31 #include <sys/sysmacros.h>
32 #include <sys/conf.h>
33 #include <sys/kmem.h>
34 #include <sys/debug.h>
35 #include <sys/modctl.h>
36 #include <sys/autoconf.h>
37 #include <sys/hwconf.h>
38 #include <sys/pcie.h>
39 #include <sys/pcie_impl.h>
40 #include <sys/pci_cap.h>
41 #include <sys/ddi.h>
42 #include <sys/sunndi.h>
43 #include <sys/hotplug/pci/pcicfg.h>
44 #include <sys/ndi_impldefs.h>
45 #include <sys/pci_cfgacc.h>
46 
47 /*
48  * ************************************************************************
49  * *** Implementation specific local data structures/definitions.	***
50  * ************************************************************************
51  */
52 
53 static	int	pcicfg_start_devno = 0;	/* for Debug only */
54 
55 #define	PCICFG_MAX_ARI_FUNCTION 256
56 
57 #define	PCICFG_NODEVICE 42
58 #define	PCICFG_NOMEMORY 43
59 #define	PCICFG_NOMULTI	44
60 #define	PCICFG_NORESRC	45
61 
62 #define	PCICFG_HIADDR(n) ((uint32_t)(((uint64_t)(n) & \
63 	0xFFFFFFFF00000000ULL)>> 32))
64 #define	PCICFG_LOADDR(n) ((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
65 #define	PCICFG_LADDR(lo, hi)	(((uint64_t)(hi) << 32) | (uint32_t)(lo))
66 
67 #define	PCICFG_HIWORD(n) ((uint16_t)(((uint32_t)(n) & 0xFFFF0000)>> 16))
68 #define	PCICFG_LOWORD(n) ((uint16_t)((uint32_t)(n) & 0x0000FFFF))
69 #define	PCICFG_HIBYTE(n) ((uint8_t)(((uint16_t)(n) & 0xFF00)>> 8))
70 #define	PCICFG_LOBYTE(n) ((uint8_t)((uint16_t)(n) & 0x00FF))
71 
72 #define	PCICFG_ROUND_UP(addr, gran) ((uintptr_t)((gran+addr-1)&(~(gran-1))))
73 #define	PCICFG_ROUND_DOWN(addr, gran) ((uintptr_t)((addr) & ~(gran-1)))
74 
75 #define	PCICFG_MEMGRAN 0x100000
76 #define	PCICFG_IOGRAN 0x1000
77 #define	PCICFG_4GIG_LIMIT 0xFFFFFFFFUL
78 
79 #define	PCICFG_MEM_MULT 4
80 #define	PCICFG_IO_MULT 4
81 #define	PCICFG_RANGE_LEN 3 /* Number of range entries */
82 
83 static int pcicfg_slot_busnums = 8;
84 static int pcicfg_slot_memsize = 32 * PCICFG_MEMGRAN; /* 32MB per slot */
85 static int pcicfg_slot_pf_memsize = 32 * PCICFG_MEMGRAN; /* 32MB per slot */
86 static int pcicfg_slot_iosize = 64 * PCICFG_IOGRAN; /* 64K per slot */
87 static int pcicfg_sec_reset_delay = 3000000;
88 static int pcicfg_do_legacy_props = 1;	/* create legacy compatible prop */
89 
90 typedef struct hole hole_t;
91 
92 struct hole {
93 	uint64_t	start;
94 	uint64_t	len;
95 	hole_t		*next;
96 };
97 
98 typedef struct pcicfg_phdl pcicfg_phdl_t;
99 
100 struct pcicfg_phdl {
101 
102 	dev_info_t	*dip;		/* Associated with the bridge */
103 	dev_info_t	*top_dip;	/* top node of the attach point */
104 	pcicfg_phdl_t	*next;
105 
106 	/* non-prefetchable memory space */
107 	uint64_t	memory_base;	/* Memory base for this attach point */
108 	uint64_t	memory_last;
109 	uint64_t	memory_len;
110 
111 	/* prefetchable memory space */
112 	uint64_t	pf_memory_base;	/* PF Memory base for this Connection */
113 	uint64_t	pf_memory_last;
114 	uint64_t	pf_memory_len;
115 
116 	/* io space */
117 	uint32_t	io_base;	/* I/O base for this attach point */
118 	uint32_t	io_last;
119 	uint32_t	io_len;
120 
121 	int		error;
122 	uint_t		highest_bus;	/* Highest bus seen on the probe */
123 
124 	hole_t		mem_hole;	/* Memory hole linked list. */
125 	hole_t		pf_mem_hole;	/* PF Memory hole linked list. */
126 	hole_t		io_hole;	/* IO hole linked list */
127 
128 	ndi_ra_request_t mem_req;	/* allocator request for memory */
129 	ndi_ra_request_t pf_mem_req;	/* allocator request for PF memory */
130 	ndi_ra_request_t io_req;	/* allocator request for I/O */
131 };
132 
133 struct pcicfg_standard_prop_entry {
134     uchar_t *name;
135     uint_t  config_offset;
136     uint_t  size;
137 };
138 
139 
140 struct pcicfg_name_entry {
141     uint32_t class_code;
142     char  *name;
143 };
144 
145 struct pcicfg_find_ctrl {
146 	uint_t		device;
147 	uint_t		function;
148 	dev_info_t	*dip;
149 };
150 
151 /*
152  * List of Indirect Config Map Devices. At least the intent of the
153  * design is to look for a device in this list during the configure
154  * operation, and if the device is listed here, then it is a nontransparent
155  * bridge, hence load the driver and avail the config map services from
156  * the driver. Class and Subclass should be as defined in the PCI specs
157  * ie. class is 0x6, and subclass is 0x9.
158  */
159 static struct {
160 	uint8_t		mem_range_bar_offset;
161 	uint8_t		io_range_bar_offset;
162 	uint8_t		prefetch_mem_range_bar_offset;
163 } pcicfg_indirect_map_devs[] = {
164 	PCI_CONF_BASE3, PCI_CONF_BASE2, PCI_CONF_BASE3,
165 	0,	0,	0,
166 };
167 
168 #define	PCICFG_MAKE_REG_HIGH(busnum, devnum, funcnum, register)\
169 	(\
170 	((ulong_t)(busnum & 0xff) << 16)    |\
171 	((ulong_t)(devnum & 0x1f) << 11)    |\
172 	((ulong_t)(funcnum & 0x7) <<  8)    |\
173 	((ulong_t)(register & 0x3f)))
174 
175 /*
176  * debug macros:
177  */
178 #if	defined(DEBUG)
179 extern void prom_printf(const char *, ...);
180 
181 /*
182  * Following values are defined for this debug flag.
183  *
184  * 1 = dump configuration header only.
185  * 2 = dump generic debug data only (no config header dumped)
186  * 3 = dump everything (both 1 and 2)
187  */
188 int pcicfg_debug = 0;
189 
190 static void debug(char *, uintptr_t, uintptr_t,
191 	uintptr_t, uintptr_t, uintptr_t);
192 
193 #define	DEBUG0(fmt)\
194 	debug(fmt, 0, 0, 0, 0, 0);
195 #define	DEBUG1(fmt, a1)\
196 	debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
197 #define	DEBUG2(fmt, a1, a2)\
198 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
199 #define	DEBUG3(fmt, a1, a2, a3)\
200 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
201 		(uintptr_t)(a3), 0, 0);
202 #define	DEBUG4(fmt, a1, a2, a3, a4)\
203 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
204 		(uintptr_t)(a3), (uintptr_t)(a4), 0);
205 #define	DEBUG5(fmt, a1, a2, a3, a4, a5)\
206 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
207 		(uintptr_t)(a3), (uintptr_t)(a4), (uintptr_t)(a5));
208 #else
209 #define	DEBUG0(fmt)
210 #define	DEBUG1(fmt, a1)
211 #define	DEBUG2(fmt, a1, a2)
212 #define	DEBUG3(fmt, a1, a2, a3)
213 #define	DEBUG4(fmt, a1, a2, a3, a4)
214 #define	DEBUG5(fmt, a1, a2, a3, a4, a5)
215 #endif
216 
217 /*
218  * forward declarations for routines defined in this module (called here)
219  */
220 
221 static int pcicfg_add_config_reg(dev_info_t *,
222     uint_t, uint_t, uint_t);
223 static int pcicfg_probe_children(dev_info_t *, uint_t, uint_t, uint_t,
224     uint_t *, pcicfg_flags_t, boolean_t);
225 static int pcicfg_match_dev(dev_info_t *, void *);
226 static dev_info_t *pcicfg_devi_find(dev_info_t *, uint_t, uint_t);
227 static pcicfg_phdl_t *pcicfg_find_phdl(dev_info_t *);
228 static pcicfg_phdl_t *pcicfg_create_phdl(dev_info_t *);
229 static int pcicfg_destroy_phdl(dev_info_t *);
230 static int pcicfg_sum_resources(dev_info_t *, void *);
231 static int pcicfg_device_assign(dev_info_t *);
232 static int pcicfg_bridge_assign(dev_info_t *, void *);
233 static int pcicfg_device_assign_readonly(dev_info_t *);
234 static int pcicfg_free_resources(dev_info_t *, pcicfg_flags_t);
235 static void pcicfg_setup_bridge(pcicfg_phdl_t *, ddi_acc_handle_t);
236 static void pcicfg_update_bridge(pcicfg_phdl_t *, ddi_acc_handle_t);
237 static int pcicfg_update_assigned_prop(dev_info_t *, pci_regspec_t *);
238 static void pcicfg_device_on(ddi_acc_handle_t);
239 static void pcicfg_device_off(ddi_acc_handle_t);
240 static int pcicfg_set_busnode_props(dev_info_t *, uint8_t);
241 static int pcicfg_free_bridge_resources(dev_info_t *);
242 static int pcicfg_free_device_resources(dev_info_t *);
243 static int pcicfg_teardown_device(dev_info_t *, pcicfg_flags_t, boolean_t);
244 static void pcicfg_reparent_node(dev_info_t *, dev_info_t *);
245 static int pcicfg_config_setup(dev_info_t *, ddi_acc_handle_t *);
246 static void pcicfg_config_teardown(ddi_acc_handle_t *);
247 static void pcicfg_get_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
248 static void pcicfg_get_pf_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
249 static void pcicfg_get_io(pcicfg_phdl_t *, uint32_t, uint32_t *);
250 static int pcicfg_update_ranges_prop(dev_info_t *, ppb_ranges_t *);
251 static int pcicfg_configure_ntbridge(dev_info_t *, uint_t, uint_t);
252 static uint_t pcicfg_ntbridge_child(dev_info_t *);
253 static uint_t pcicfg_get_ntbridge_child_range(dev_info_t *, uint64_t *,
254     uint64_t *, uint_t);
255 static int pcicfg_is_ntbridge(dev_info_t *);
256 static int pcicfg_ntbridge_allocate_resources(dev_info_t *);
257 static int pcicfg_ntbridge_configure_done(dev_info_t *);
258 static int pcicfg_ntbridge_program_child(dev_info_t *);
259 static uint_t pcicfg_ntbridge_unconfigure(dev_info_t *);
260 static int pcicfg_ntbridge_unconfigure_child(dev_info_t *, uint_t);
261 static void pcicfg_free_hole(hole_t *);
262 static uint64_t pcicfg_alloc_hole(hole_t *, uint64_t *, uint32_t);
263 static int pcicfg_device_type(dev_info_t *, ddi_acc_handle_t *);
264 static void pcicfg_update_phdl(dev_info_t *, uint8_t, uint8_t);
265 static int pcicfg_get_cap(ddi_acc_handle_t, uint8_t);
266 static uint8_t pcicfg_get_nslots(dev_info_t *, ddi_acc_handle_t);
267 static int pcicfg_pcie_dev(dev_info_t *, ddi_acc_handle_t);
268 static int pcicfg_pcie_device_type(dev_info_t *, ddi_acc_handle_t);
269 static int pcicfg_pcie_port_type(dev_info_t *, ddi_acc_handle_t);
270 static int pcicfg_probe_bridge(dev_info_t *, ddi_acc_handle_t, uint_t,
271 	uint_t *, boolean_t);
272 static int pcicfg_find_resource_end(dev_info_t *, void *);
273 static boolean_t is_pcie_fabric(dev_info_t *);
274 
275 static int pcicfg_populate_reg_props(dev_info_t *, ddi_acc_handle_t);
276 static int pcicfg_populate_props_from_bar(dev_info_t *, ddi_acc_handle_t);
277 static int pcicfg_update_assigned_prop_value(dev_info_t *, uint32_t,
278     uint32_t, uint32_t, uint_t);
279 static int pcicfg_ari_configure(dev_info_t *);
280 
281 #ifdef DEBUG
282 static void pcicfg_dump_common_config(ddi_acc_handle_t config_handle);
283 static void pcicfg_dump_device_config(ddi_acc_handle_t);
284 static void pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle);
285 static uint64_t pcicfg_unused_space(hole_t *, uint32_t *);
286 
287 #define	PCICFG_DUMP_COMMON_CONFIG(hdl) (void)pcicfg_dump_common_config(hdl)
288 #define	PCICFG_DUMP_DEVICE_CONFIG(hdl) (void)pcicfg_dump_device_config(hdl)
289 #define	PCICFG_DUMP_BRIDGE_CONFIG(hdl) (void)pcicfg_dump_bridge_config(hdl)
290 #else
291 #define	PCICFG_DUMP_COMMON_CONFIG(handle)
292 #define	PCICFG_DUMP_DEVICE_CONFIG(handle)
293 #define	PCICFG_DUMP_BRIDGE_CONFIG(handle)
294 #endif
295 
296 static kmutex_t pcicfg_list_mutex; /* Protects the probe handle list */
297 static pcicfg_phdl_t *pcicfg_phdl_list = NULL;
298 
299 #ifndef _DONT_USE_1275_GENERIC_NAMES
300 /*
301  * Class code table
302  */
303 static struct pcicfg_name_entry pcicfg_class_lookup [] = {
304 
305 	{ 0x001, "display" },
306 	{ 0x100, "scsi" },
307 	{ 0x101, "ide" },
308 	{ 0x102, "fdc" },
309 	{ 0x103, "ipi" },
310 	{ 0x104, "raid" },
311 	{ 0x105, "ata" },
312 	{ 0x106, "sata" },
313 	{ 0x200, "ethernet" },
314 	{ 0x201, "token-ring" },
315 	{ 0x202, "fddi" },
316 	{ 0x203, "atm" },
317 	{ 0x204, "isdn" },
318 	{ 0x206, "mcd" },
319 	{ 0x300, "display" },
320 	{ 0x400, "video" },
321 	{ 0x401, "sound" },
322 	{ 0x500, "memory" },
323 	{ 0x501, "flash" },
324 	{ 0x600, "host" },
325 	{ 0x601, "isa" },
326 	{ 0x602, "eisa" },
327 	{ 0x603, "mca" },
328 	{ 0x604, "pci" },
329 	{ 0x605, "pcmcia" },
330 	{ 0x606, "nubus" },
331 	{ 0x607, "cardbus" },
332 	{ 0x609, "pci" },
333 	{ 0x60a, "ib-pci" },
334 	{ 0x700, "serial" },
335 	{ 0x701, "parallel" },
336 	{ 0x800, "interrupt-controller" },
337 	{ 0x801, "dma-controller" },
338 	{ 0x802, "timer" },
339 	{ 0x803, "rtc" },
340 	{ 0x900, "keyboard" },
341 	{ 0x901, "pen" },
342 	{ 0x902, "mouse" },
343 	{ 0xa00, "dock" },
344 	{ 0xb00, "cpu" },
345 	{ 0xb01, "cpu" },
346 	{ 0xb02, "cpu" },
347 	{ 0xb10, "cpu" },
348 	{ 0xb20, "cpu" },
349 	{ 0xb30, "cpu" },
350 	{ 0xb40, "coproc" },
351 	{ 0xc00, "firewire" },
352 	{ 0xc01, "access-bus" },
353 	{ 0xc02, "ssa" },
354 	{ 0xc03, "usb" },
355 	{ 0xc04, "fibre-channel" },
356 	{ 0xc05, "smbus" },
357 	{ 0xc06, "ib" },
358 	{ 0xd00, "irda" },
359 	{ 0xd01, "ir" },
360 	{ 0xd10, "rf" },
361 	{ 0xd11, "btooth" },
362 	{ 0xd12, "brdband" },
363 	{ 0xd20, "802.11a" },
364 	{ 0xd21, "802.11b" },
365 	{ 0xe00, "i2o" },
366 	{ 0xf01, "tv" },
367 	{ 0xf02, "audio" },
368 	{ 0xf03, "voice" },
369 	{ 0xf04, "data" },
370 	{ 0, 0 }
371 };
372 #endif /* _DONT_USE_1275_GENERIC_NAMES */
373 
374 /*
375  * Module control operations
376  */
377 
378 extern struct mod_ops mod_miscops;
379 
380 static struct modlmisc modlmisc = {
381 	&mod_miscops, /* Type of module */
382 	"PCI configurator"
383 };
384 
385 static struct modlinkage modlinkage = {
386 	MODREV_1, (void *)&modlmisc, NULL
387 };
388 
389 
390 #ifdef DEBUG
391 
392 static void
393 pcicfg_dump_common_config(ddi_acc_handle_t config_handle)
394 {
395 	if ((pcicfg_debug & 1) == 0)
396 		return;
397 	prom_printf(" Vendor ID   = [0x%x]\n",
398 	    pci_config_get16(config_handle, PCI_CONF_VENID));
399 	prom_printf(" Device ID   = [0x%x]\n",
400 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
401 	prom_printf(" Command REG = [0x%x]\n",
402 	    pci_config_get16(config_handle, PCI_CONF_COMM));
403 	prom_printf(" Status  REG = [0x%x]\n",
404 	    pci_config_get16(config_handle, PCI_CONF_STAT));
405 	prom_printf(" Revision ID = [0x%x]\n",
406 	    pci_config_get8(config_handle, PCI_CONF_REVID));
407 	prom_printf(" Prog Class  = [0x%x]\n",
408 	    pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
409 	prom_printf(" Dev Class   = [0x%x]\n",
410 	    pci_config_get8(config_handle, PCI_CONF_SUBCLASS));
411 	prom_printf(" Base Class  = [0x%x]\n",
412 	    pci_config_get8(config_handle, PCI_CONF_BASCLASS));
413 	prom_printf(" Device ID   = [0x%x]\n",
414 	    pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ));
415 	prom_printf(" Header Type = [0x%x]\n",
416 	    pci_config_get8(config_handle, PCI_CONF_HEADER));
417 	prom_printf(" BIST        = [0x%x]\n",
418 	    pci_config_get8(config_handle, PCI_CONF_BIST));
419 	prom_printf(" BASE 0      = [0x%x]\n",
420 	    pci_config_get32(config_handle, PCI_CONF_BASE0));
421 	prom_printf(" BASE 1      = [0x%x]\n",
422 	    pci_config_get32(config_handle, PCI_CONF_BASE1));
423 
424 }
425 
426 static void
427 pcicfg_dump_device_config(ddi_acc_handle_t config_handle)
428 {
429 	if ((pcicfg_debug & 1) == 0)
430 		return;
431 	pcicfg_dump_common_config(config_handle);
432 
433 	prom_printf(" BASE 2      = [0x%x]\n",
434 	    pci_config_get32(config_handle, PCI_CONF_BASE2));
435 	prom_printf(" BASE 3      = [0x%x]\n",
436 	    pci_config_get32(config_handle, PCI_CONF_BASE3));
437 	prom_printf(" BASE 4      = [0x%x]\n",
438 	    pci_config_get32(config_handle, PCI_CONF_BASE4));
439 	prom_printf(" BASE 5      = [0x%x]\n",
440 	    pci_config_get32(config_handle, PCI_CONF_BASE5));
441 	prom_printf(" Cardbus CIS = [0x%x]\n",
442 	    pci_config_get32(config_handle, PCI_CONF_CIS));
443 	prom_printf(" Sub VID     = [0x%x]\n",
444 	    pci_config_get16(config_handle, PCI_CONF_SUBVENID));
445 	prom_printf(" Sub SID     = [0x%x]\n",
446 	    pci_config_get16(config_handle, PCI_CONF_SUBSYSID));
447 	prom_printf(" ROM         = [0x%x]\n",
448 	    pci_config_get32(config_handle, PCI_CONF_ROM));
449 	prom_printf(" I Line      = [0x%x]\n",
450 	    pci_config_get8(config_handle, PCI_CONF_ILINE));
451 	prom_printf(" I Pin       = [0x%x]\n",
452 	    pci_config_get8(config_handle, PCI_CONF_IPIN));
453 	prom_printf(" Max Grant   = [0x%x]\n",
454 	    pci_config_get8(config_handle, PCI_CONF_MIN_G));
455 	prom_printf(" Max Latent  = [0x%x]\n",
456 	    pci_config_get8(config_handle, PCI_CONF_MAX_L));
457 }
458 
459 static void
460 pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle)
461 {
462 	if ((pcicfg_debug & 1) == 0)
463 		return;
464 	pcicfg_dump_common_config(config_handle);
465 
466 	prom_printf("........................................\n");
467 
468 	prom_printf(" Pri Bus     = [0x%x]\n",
469 	    pci_config_get8(config_handle, PCI_BCNF_PRIBUS));
470 	prom_printf(" Sec Bus     = [0x%x]\n",
471 	    pci_config_get8(config_handle, PCI_BCNF_SECBUS));
472 	prom_printf(" Sub Bus     = [0x%x]\n",
473 	    pci_config_get8(config_handle, PCI_BCNF_SUBBUS));
474 	prom_printf(" Latency     = [0x%x]\n",
475 	    pci_config_get8(config_handle, PCI_BCNF_LATENCY_TIMER));
476 	prom_printf(" I/O Base LO = [0x%x]\n",
477 	    pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW));
478 	prom_printf(" I/O Lim LO  = [0x%x]\n",
479 	    pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW));
480 	prom_printf(" Sec. Status = [0x%x]\n",
481 	    pci_config_get16(config_handle, PCI_BCNF_SEC_STATUS));
482 	prom_printf(" Mem Base    = [0x%x]\n",
483 	    pci_config_get16(config_handle, PCI_BCNF_MEM_BASE));
484 	prom_printf(" Mem Limit   = [0x%x]\n",
485 	    pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT));
486 	prom_printf(" PF Mem Base = [0x%x]\n",
487 	    pci_config_get16(config_handle, PCI_BCNF_PF_BASE_LOW));
488 	prom_printf(" PF Mem Lim  = [0x%x]\n",
489 	    pci_config_get16(config_handle, PCI_BCNF_PF_LIMIT_LOW));
490 	prom_printf(" PF Base HI  = [0x%x]\n",
491 	    pci_config_get32(config_handle, PCI_BCNF_PF_BASE_HIGH));
492 	prom_printf(" PF Lim  HI  = [0x%x]\n",
493 	    pci_config_get32(config_handle, PCI_BCNF_PF_LIMIT_HIGH));
494 	prom_printf(" I/O Base HI = [0x%x]\n",
495 	    pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI));
496 	prom_printf(" I/O Lim HI  = [0x%x]\n",
497 	    pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI));
498 	prom_printf(" ROM addr    = [0x%x]\n",
499 	    pci_config_get32(config_handle, PCI_BCNF_ROM));
500 	prom_printf(" Intr Line   = [0x%x]\n",
501 	    pci_config_get8(config_handle, PCI_BCNF_ILINE));
502 	prom_printf(" Intr Pin    = [0x%x]\n",
503 	    pci_config_get8(config_handle, PCI_BCNF_IPIN));
504 	prom_printf(" Bridge Ctrl = [0x%x]\n",
505 	    pci_config_get16(config_handle, PCI_BCNF_BCNTRL));
506 }
507 #endif
508 
509 int
510 _init()
511 {
512 	DEBUG0(" PCI configurator installed\n");
513 	mutex_init(&pcicfg_list_mutex, NULL, MUTEX_DRIVER, NULL);
514 	return (mod_install(&modlinkage));
515 }
516 
517 int
518 _fini(void)
519 {
520 	int error;
521 
522 	error = mod_remove(&modlinkage);
523 	if (error != 0) {
524 		return (error);
525 	}
526 	mutex_destroy(&pcicfg_list_mutex);
527 	return (0);
528 }
529 
530 int
531 _info(struct modinfo *modinfop)
532 {
533 	return (mod_info(&modlinkage, modinfop));
534 }
535 
536 /*
537  * In the following functions ndi_devi_enter() without holding the
538  * parent dip is sufficient. This is because  pci dr is driven through
539  * opens on the nexus which is in the device tree path above the node
540  * being operated on, and implicitly held due to the open.
541  */
542 
543 /*
544  * This entry point is called to configure a device (and
545  * all its children) on the given bus. It is called when
546  * a new device is added to the PCI domain.  This routine
547  * will create the device tree and program the devices
548  * registers.
549  */
550 int
551 pcicfg_configure(dev_info_t *devi, uint_t device, uint_t function,
552     pcicfg_flags_t flags)
553 {
554 	uint_t bus;
555 	int len;
556 	int func;
557 	dev_info_t *attach_point;
558 	pci_bus_range_t pci_bus_range;
559 	int rv;
560 	int circ, pcirc;
561 	uint_t highest_bus, visited = 0;
562 	int ari_mode = B_FALSE;
563 	int max_function = PCI_MAX_FUNCTIONS;
564 	int trans_device;
565 	dev_info_t *new_device;
566 	boolean_t is_pcie;
567 
568 	if (flags == PCICFG_FLAG_ENABLE_ARI)
569 		return (pcicfg_ari_configure(devi));
570 
571 	/*
572 	 * Start probing at the device specified in "device" on the
573 	 * "bus" specified.
574 	 */
575 	len = sizeof (pci_bus_range_t);
576 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devi, 0, "bus-range",
577 	    (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
578 		DEBUG0("no bus-range property\n");
579 		return (PCICFG_FAILURE);
580 	}
581 
582 	bus = pci_bus_range.lo; /* primary bus number of this bus node */
583 
584 	attach_point = devi;
585 
586 	is_pcie = is_pcie_fabric(devi);
587 
588 	/*
589 	 * This code may be racing against other code walking the device info
590 	 * tree, such as `di_copytree` et al.  To avoid deadlock, we must ensure
591 	 * a strict hierarchical ordering of `ndi_devi_enter` calls that mirrors
592 	 * the structure of the tree, working from the root towards leaves.
593 	 * `pcie_fabric_setup`, if called, will call `ddi_walk_devs` which
594 	 * requires that the parent is locked; therefore, to obey the lock
595 	 * ordering, we must lock the parent here.
596 	 */
597 	ndi_devi_enter(ddi_get_parent(devi), &pcirc);
598 	ndi_devi_enter(devi, &circ);
599 	for (func = 0; func < max_function; ) {
600 
601 		if ((function != PCICFG_ALL_FUNC) && (function != func))
602 			goto next;
603 
604 		if (ari_mode)
605 			trans_device = func >> 3;
606 		else
607 			trans_device = device;
608 
609 		switch (rv = pcicfg_probe_children(attach_point,
610 		    bus, trans_device, func & 7, &highest_bus,
611 		    flags, is_pcie)) {
612 			case PCICFG_NORESRC:
613 			case PCICFG_FAILURE:
614 				DEBUG2("configure failed: bus [0x%x] device "
615 				    "[0x%x]\n", bus, trans_device);
616 				goto cleanup;
617 			case PCICFG_NODEVICE:
618 				DEBUG3("no device : bus "
619 				    "[0x%x] slot [0x%x] func [0x%x]\n",
620 				    bus, trans_device, func &7);
621 
622 				/*
623 				 * When walking the list of ARI functions
624 				 * we don't expect to see a non-present
625 				 * function, so we will stop walking
626 				 * the function list.
627 				 */
628 				if (ari_mode == B_TRUE)
629 					break;
630 
631 				if (func)
632 					goto next;
633 				break;
634 			default:
635 				DEBUG3("configure: bus => [%d] "
636 				    "slot => [%d] func => [%d]\n",
637 				    bus, trans_device, func & 7);
638 			break;
639 		}
640 
641 		if (rv != PCICFG_SUCCESS)
642 			break;
643 
644 		if ((new_device = pcicfg_devi_find(attach_point,
645 		    trans_device, func & 7)) == NULL) {
646 			DEBUG0("Did'nt find device node just created\n");
647 			goto cleanup;
648 		}
649 
650 		/*
651 		 * Up until now, we have detected a non transparent bridge
652 		 * (ntbridge) as a part of the generic probe code and
653 		 * configured only one configuration
654 		 * header which is the side facing the host bus.
655 		 * Now, configure the other side and create children.
656 		 *
657 		 * In order to make the process simpler, lets load the device
658 		 * driver for the non transparent bridge as this is a
659 		 * Solaris bundled driver, and use its configuration map
660 		 * services rather than programming it here.
661 		 * If the driver is not bundled into Solaris, it must be
662 		 * first loaded and configured before performing any
663 		 * hotplug operations.
664 		 *
665 		 * This not only makes the code here simpler but also more
666 		 * generic.
667 		 *
668 		 * So here we go.
669 		 */
670 
671 		/*
672 		 * check if this is a bridge in nontransparent mode
673 		 */
674 		if (pcicfg_is_ntbridge(new_device) != DDI_FAILURE) {
675 			DEBUG0("pcicfg: Found nontransparent bridge.\n");
676 
677 			rv = pcicfg_configure_ntbridge(new_device, bus,
678 			    trans_device);
679 			if (rv != PCICFG_SUCCESS)
680 				goto cleanup;
681 		}
682 
683 		/*
684 		 * Note that we've successfully gone through and visited at
685 		 * least one node.
686 		 */
687 		visited++;
688 next:
689 		/*
690 		 * Determine if ARI Forwarding should be enabled.
691 		 */
692 		if (func == 0) {
693 			if ((pcie_ari_supported(devi)
694 			    == PCIE_ARI_FORW_SUPPORTED) &&
695 			    (pcie_ari_device(new_device) == PCIE_ARI_DEVICE)) {
696 				if (pcie_ari_enable(devi) == DDI_SUCCESS) {
697 					(void) ddi_prop_create(DDI_DEV_T_NONE,
698 					    devi,  DDI_PROP_CANSLEEP,
699 					    "ari-enabled", NULL, 0);
700 
701 					ari_mode = B_TRUE;
702 					max_function = PCICFG_MAX_ARI_FUNCTION;
703 				}
704 			}
705 		}
706 		if (ari_mode == B_TRUE) {
707 			int next_function;
708 
709 			DEBUG0("Next Function - ARI Device\n");
710 			if (pcie_ari_get_next_function(new_device,
711 			    &next_function) != DDI_SUCCESS)
712 				goto cleanup;
713 
714 			/*
715 			 * Check if there are more functions to probe.
716 			 */
717 			if (next_function == 0) {
718 				DEBUG0("Next Function - "
719 				    "No more ARI Functions\n");
720 				break;
721 			}
722 			func = next_function;
723 		} else {
724 			func++;
725 		}
726 		DEBUG1("Next Function - %x\n", func);
727 	}
728 
729 	/*
730 	 * At this point we have set up the various dev_info nodes that we
731 	 * expect to see in the tree and we must re-evaluate the general fabric
732 	 * settings such as the overall max payload size or the tagging that is
733 	 * enabled. However, as part the big theory statement in pcie.c, this
734 	 * can only be performed on a root port; however, that determination
735 	 * will be made by the fabric scanning logic.
736 	 */
737 	if (visited > 0 && is_pcie) {
738 		pcie_fabric_setup(devi);
739 	}
740 
741 	ndi_devi_exit(devi, circ);
742 	ndi_devi_exit(ddi_get_parent(devi), pcirc);
743 
744 	if (visited == 0)
745 		return (PCICFG_FAILURE);	/* probe failed */
746 	else
747 		return (PCICFG_SUCCESS);
748 
749 cleanup:
750 	/*
751 	 * Clean up a partially created "probe state" tree.
752 	 * There are no resources allocated to the in the
753 	 * probe state.
754 	 */
755 
756 	for (func = 0; func < PCI_MAX_FUNCTIONS; func++) {
757 		if ((function != PCICFG_ALL_FUNC) && (function != func))
758 			continue;
759 
760 		if ((new_device = pcicfg_devi_find(devi, device, func))
761 		    == NULL) {
762 			continue;
763 		}
764 
765 		DEBUG2("Cleaning up device [0x%x] function [0x%x]\n",
766 		    device, func);
767 		/*
768 		 * If this was a bridge device it will have a
769 		 * probe handle - if not, no harm in calling this.
770 		 */
771 		(void) pcicfg_destroy_phdl(new_device);
772 		if (is_pcie) {
773 			/*
774 			 * free pcie_bus_t for the sub-tree
775 			 */
776 			if (ddi_get_child(new_device) != NULL)
777 				pcie_fab_fini_bus(new_device, PCIE_BUS_ALL);
778 
779 			pcie_fini_bus(new_device, PCIE_BUS_ALL);
780 		}
781 		/*
782 		 * This will free up the node
783 		 */
784 		(void) ndi_devi_offline(new_device, NDI_DEVI_REMOVE);
785 	}
786 	ndi_devi_exit(devi, circ);
787 	ndi_devi_exit(ddi_get_parent(devi), pcirc);
788 
789 	/*
790 	 * Use private return codes to help identify issues without debugging
791 	 * enabled.  Resource limitations and mis-configurations are
792 	 * probably the most likely caue of configuration failures on x86.
793 	 * Convert return code back to values expected by the external
794 	 * consumer before returning so we will warn only once on the first
795 	 * encountered failure.
796 	 */
797 	if (rv == PCICFG_NORESRC) {
798 		char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
799 
800 		(void) ddi_pathname(devi, path);
801 		cmn_err(CE_CONT, "?Not enough PCI resources to "
802 		    "configure: %s\n", path);
803 
804 		kmem_free(path, MAXPATHLEN);
805 		rv = PCICFG_FAILURE;
806 	}
807 
808 	return (rv);
809 }
810 
811 /*
812  * configure the child nodes of ntbridge. new_device points to ntbridge itself
813  */
814 /*ARGSUSED*/
815 static int
816 pcicfg_configure_ntbridge(dev_info_t *new_device, uint_t bus, uint_t device)
817 {
818 	int bus_range[2], rc = PCICFG_FAILURE, rc1, max_devs = 0;
819 	int			devno;
820 	dev_info_t		*new_ntbridgechild;
821 	ddi_acc_handle_t	config_handle;
822 	uint16_t		vid;
823 	uint64_t		next_bus;
824 	uint64_t		blen;
825 	ndi_ra_request_t	req;
826 	uint8_t			pcie_device_type = 0;
827 
828 	/*
829 	 * If we need to do indirect config, lets create a property here
830 	 * to let the child conf map routine know that it has to
831 	 * go through the DDI calls, and not assume the devices are
832 	 * mapped directly under the host.
833 	 */
834 	if ((rc = ndi_prop_update_int(DDI_DEV_T_NONE, new_device,
835 	    PCI_DEV_CONF_MAP_PROP, (int)DDI_SUCCESS)) != DDI_SUCCESS) {
836 		DEBUG0("Cannot create indirect conf map property.\n");
837 		return ((int)PCICFG_FAILURE);
838 	}
839 
840 	if (pci_config_setup(new_device, &config_handle) != DDI_SUCCESS)
841 		return (PCICFG_FAILURE);
842 	/* check if we are PCIe device */
843 	if (pcicfg_pcie_device_type(new_device, config_handle) == DDI_SUCCESS) {
844 		DEBUG0("PCIe device detected\n");
845 		pcie_device_type = 1;
846 	}
847 	pci_config_teardown(&config_handle);
848 	/* create Bus node properties for ntbridge. */
849 	if (pcicfg_set_busnode_props(new_device, pcie_device_type)
850 	    != PCICFG_SUCCESS) {
851 		DEBUG0("Failed to set busnode props\n");
852 		return (rc);
853 	}
854 
855 	/* For now: Lets only support one layer of child */
856 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
857 	req.ra_len = 1;
858 	if (ndi_ra_alloc(ddi_get_parent(new_device), &req, &next_bus, &blen,
859 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
860 		DEBUG0("ntbridge: Failed to get a bus number\n");
861 		return (PCICFG_NORESRC);
862 	}
863 
864 	DEBUG1("ntbridge bus range start  ->[%d]\n", next_bus);
865 
866 	/*
867 	 * Following will change, as we detect more bridges
868 	 * on the way.
869 	 */
870 	bus_range[0] = (int)next_bus;
871 	bus_range[1] = (int)next_bus;
872 
873 	if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_device, "bus-range",
874 	    bus_range, 2) != DDI_SUCCESS) {
875 		DEBUG0("Cannot set ntbridge bus-range property");
876 		return (rc);
877 	}
878 
879 	/*
880 	 * The other interface (away from the host) will be
881 	 * initialized by the nexus driver when it loads.
882 	 * We just have to set the registers and the nexus driver
883 	 * figures out the rest.
884 	 */
885 
886 	/*
887 	 * finally, lets load and attach the driver
888 	 * before configuring children of ntbridge.
889 	 */
890 	rc = ndi_devi_online(new_device, NDI_ONLINE_ATTACH|NDI_CONFIG);
891 	if (rc != NDI_SUCCESS) {
892 		cmn_err(CE_WARN,
893 		"pcicfg: Fail:cant load nontransparent bridgd driver..\n");
894 		rc = PCICFG_FAILURE;
895 		return (rc);
896 	}
897 	DEBUG0("pcicfg: Success loading nontransparent bridge nexus driver..");
898 
899 	/* Now set aside pci resource allocation requests for our children */
900 	if (pcicfg_ntbridge_allocate_resources(new_device) != PCICFG_SUCCESS) {
901 		max_devs = 0;
902 		rc = PCICFG_FAILURE;
903 	} else
904 		max_devs = PCI_MAX_DEVICES;
905 
906 	/* Probe devices on 2nd bus */
907 	rc = PCICFG_SUCCESS;
908 	for (devno = pcicfg_start_devno; devno < max_devs; devno++) {
909 
910 		ndi_devi_alloc_sleep(new_device, DEVI_PSEUDO_NEXNAME,
911 		    (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild);
912 
913 		if (pcicfg_add_config_reg(new_ntbridgechild, next_bus, devno, 0)
914 		    != DDI_PROP_SUCCESS) {
915 			cmn_err(CE_WARN,
916 			    "Failed to add conf reg for ntbridge child.\n");
917 			(void) ndi_devi_free(new_ntbridgechild);
918 			rc = PCICFG_FAILURE;
919 			break;
920 		}
921 
922 		if (pci_config_setup(new_ntbridgechild, &config_handle)
923 		    != DDI_SUCCESS) {
924 			cmn_err(CE_WARN,
925 			    "Cannot map ntbridge child %x\n", devno);
926 			(void) ndi_devi_free(new_ntbridgechild);
927 			rc = PCICFG_FAILURE;
928 			break;
929 		}
930 
931 		/*
932 		 * See if there is any PCI HW at this location
933 		 * by reading the Vendor ID.  If it returns with 0xffff
934 		 * then there is no hardware at this location.
935 		 */
936 		vid = pci_config_get16(config_handle, PCI_CONF_VENID);
937 
938 		pci_config_teardown(&config_handle);
939 		(void) ndi_devi_free(new_ntbridgechild);
940 		if (vid	== 0xffff)
941 			continue;
942 
943 		/* Lets fake attachments points for each child, */
944 		rc = pcicfg_configure(new_device, devno, PCICFG_ALL_FUNC, 0);
945 		if (rc != PCICFG_SUCCESS) {
946 			int old_dev = pcicfg_start_devno;
947 
948 			cmn_err(CE_WARN,
949 			    "Error configuring ntbridge child dev=%d\n", devno);
950 
951 			while (old_dev != devno) {
952 				if (pcicfg_ntbridge_unconfigure_child(
953 				    new_device, old_dev) == PCICFG_FAILURE)
954 					cmn_err(CE_WARN, "Unconfig Error "
955 					    "ntbridge child dev=%d\n", old_dev);
956 				old_dev++;
957 			}
958 			break;
959 		}
960 	} /* devno loop */
961 	DEBUG1("ntbridge: finish probing 2nd bus, rc=%d\n", rc);
962 
963 	if (rc == PCICFG_SUCCESS)
964 		rc = pcicfg_ntbridge_configure_done(new_device);
965 	else {
966 		pcicfg_phdl_t *entry = pcicfg_find_phdl(new_device);
967 		uint_t			*bus;
968 		int			k;
969 
970 		if (ddi_getlongprop(DDI_DEV_T_ANY, new_device,
971 		    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus, &k)
972 		    != DDI_PROP_SUCCESS) {
973 			DEBUG0("Failed to read bus-range property\n");
974 			rc = PCICFG_FAILURE;
975 			return (rc);
976 		}
977 
978 		DEBUG2("Need to free bus [%d] range [%d]\n",
979 		    bus[0], bus[1] - bus[0] + 1);
980 
981 		if (ndi_ra_free(ddi_get_parent(new_device), (uint64_t)bus[0],
982 		    (uint64_t)(bus[1] - bus[0] + 1), NDI_RA_TYPE_PCI_BUSNUM,
983 		    NDI_RA_PASS) != NDI_SUCCESS) {
984 			DEBUG0("Failed to free a bus number\n");
985 			rc = PCICFG_FAILURE;
986 			kmem_free(bus, k);
987 			return (rc);
988 		}
989 
990 		/*
991 		 * Since no memory allocations are done for non transparent
992 		 * bridges (but instead we just set the handle with the
993 		 * already allocated memory, we just need to reset the
994 		 * following values before calling the destroy_phdl()
995 		 * function next, otherwise the it will try to free
996 		 * memory allocated as in case of a transparent bridge.
997 		 */
998 		entry->memory_len = 0;
999 		entry->pf_memory_len = 0;
1000 		entry->io_len = 0;
1001 		kmem_free(bus, k);
1002 		/* the following will free hole data. */
1003 		(void) pcicfg_destroy_phdl(new_device);
1004 	}
1005 
1006 	/*
1007 	 * Unload driver just in case child configure failed!
1008 	 */
1009 	rc1 = ndi_devi_offline(new_device, 0);
1010 	DEBUG1("pcicfg: now unloading the ntbridge driver. rc1=%d\n", rc1);
1011 	if (rc1 != NDI_SUCCESS) {
1012 		cmn_err(CE_WARN,
1013 		"pcicfg: cant unload ntbridge driver..children.\n");
1014 		rc = PCICFG_FAILURE;
1015 	}
1016 
1017 	return (rc);
1018 }
1019 
1020 static int
1021 pcicfg_ntbridge_allocate_resources(dev_info_t *dip)
1022 {
1023 	pcicfg_phdl_t		*phdl;
1024 	ndi_ra_request_t	*mem_request;
1025 	ndi_ra_request_t	*pf_mem_request;
1026 	ndi_ra_request_t	*io_request;
1027 	uint64_t		boundbase, boundlen;
1028 
1029 	phdl = pcicfg_find_phdl(dip);
1030 	ASSERT(phdl);
1031 
1032 	mem_request = &phdl->mem_req;
1033 	pf_mem_request = &phdl->pf_mem_req;
1034 	io_request  = &phdl->io_req;
1035 
1036 	phdl->error = PCICFG_SUCCESS;
1037 
1038 	/* Set Memory space handle for ntbridge */
1039 	if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1040 	    PCI_BASE_SPACE_MEM) != DDI_SUCCESS) {
1041 		cmn_err(CE_WARN,
1042 		    "ntbridge: Mem resource information failure\n");
1043 		phdl->memory_len  = 0;
1044 		return (PCICFG_FAILURE);
1045 	}
1046 	mem_request->ra_boundbase = boundbase;
1047 	mem_request->ra_boundlen = boundbase + boundlen;
1048 	mem_request->ra_len = boundlen;
1049 	mem_request->ra_align_mask =
1050 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
1051 	mem_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1052 
1053 	/*
1054 	 * mem_request->ra_len =
1055 	 * PCICFG_ROUND_UP(mem_request->ra_len, PCICFG_MEMGRAN);
1056 	 */
1057 
1058 	phdl->memory_base = phdl->memory_last = boundbase;
1059 	phdl->memory_len  = boundlen;
1060 	phdl->mem_hole.start = phdl->memory_base;
1061 	phdl->mem_hole.len = mem_request->ra_len;
1062 	phdl->mem_hole.next = (hole_t *)NULL;
1063 
1064 	DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of memory\n",
1065 	    boundlen, mem_request->ra_len);
1066 
1067 	/* Set IO space handle for ntbridge */
1068 	if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1069 	    PCI_BASE_SPACE_IO) != DDI_SUCCESS) {
1070 		cmn_err(CE_WARN, "ntbridge: IO resource information failure\n");
1071 		phdl->io_len  = 0;
1072 		return (PCICFG_FAILURE);
1073 	}
1074 	io_request->ra_len = boundlen;
1075 	io_request->ra_align_mask =
1076 	    PCICFG_IOGRAN - 1;   /* 4K alignment on I/O space */
1077 	io_request->ra_boundbase = boundbase;
1078 	io_request->ra_boundlen = boundbase + boundlen;
1079 	io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1080 
1081 	/*
1082 	 * io_request->ra_len =
1083 	 * PCICFG_ROUND_UP(io_request->ra_len, PCICFG_IOGRAN);
1084 	 */
1085 
1086 	phdl->io_base = phdl->io_last = (uint32_t)boundbase;
1087 	phdl->io_len  = (uint32_t)boundlen;
1088 	phdl->io_hole.start = phdl->io_base;
1089 	phdl->io_hole.len = io_request->ra_len;
1090 	phdl->io_hole.next = (hole_t *)NULL;
1091 
1092 	DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of IO\n",
1093 	    boundlen, io_request->ra_len);
1094 
1095 	/* Set Prefetchable Memory space handle for ntbridge */
1096 	if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1097 	    PCI_BASE_SPACE_MEM | PCI_BASE_PREF_M) != DDI_SUCCESS) {
1098 		cmn_err(CE_WARN,
1099 		    "ntbridge: PF Mem resource information failure\n");
1100 		phdl->pf_memory_len  = 0;
1101 		return (PCICFG_FAILURE);
1102 	}
1103 	pf_mem_request->ra_boundbase = boundbase;
1104 	pf_mem_request->ra_boundlen = boundbase + boundlen;
1105 	pf_mem_request->ra_len = boundlen;
1106 	pf_mem_request->ra_align_mask =
1107 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
1108 	pf_mem_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1109 
1110 	/*
1111 	 * pf_mem_request->ra_len =
1112 	 * PCICFG_ROUND_UP(pf_mem_request->ra_len, PCICFG_MEMGRAN);
1113 	 */
1114 
1115 	phdl->pf_memory_base = phdl->pf_memory_last = boundbase;
1116 	phdl->pf_memory_len  = boundlen;
1117 	phdl->pf_mem_hole.start = phdl->pf_memory_base;
1118 	phdl->pf_mem_hole.len = pf_mem_request->ra_len;
1119 	phdl->pf_mem_hole.next = (hole_t *)NULL;
1120 
1121 	DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of PF "
1122 	    "memory\n", boundlen, pf_mem_request->ra_len);
1123 
1124 	DEBUG2("MEMORY BASE = [0x%lx] length [0x%lx]\n",
1125 	    phdl->memory_base, phdl->memory_len);
1126 	DEBUG2("IO     BASE = [0x%x] length [0x%x]\n",
1127 	    phdl->io_base, phdl->io_len);
1128 	DEBUG2("PF MEMORY BASE = [0x%lx] length [0x%lx]\n",
1129 	    phdl->pf_memory_base, phdl->pf_memory_len);
1130 
1131 	return (PCICFG_SUCCESS);
1132 }
1133 
1134 static int
1135 pcicfg_ntbridge_configure_done(dev_info_t *dip)
1136 {
1137 	ppb_ranges_t range[PCICFG_RANGE_LEN];
1138 	pcicfg_phdl_t		*entry;
1139 	uint_t			len;
1140 	pci_bus_range_t		bus_range;
1141 	int			new_bus_range[2];
1142 
1143 	DEBUG1("Configuring children for %p\n", dip);
1144 
1145 	entry = pcicfg_find_phdl(dip);
1146 	ASSERT(entry);
1147 
1148 	bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
1149 	range[1].child_high = range[1].parent_high |=
1150 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
1151 	range[1].child_low = range[1].parent_low = (uint32_t)entry->memory_base;
1152 
1153 	range[0].child_high = range[0].parent_high |=
1154 	    (PCI_REG_REL_M | PCI_ADDR_IO);
1155 	range[0].child_low = range[0].parent_low = (uint32_t)entry->io_base;
1156 
1157 	range[2].child_high = range[2].parent_high |=
1158 	    (PCI_REG_REL_M | PCI_ADDR_MEM32 | PCI_REG_PF_M);
1159 	range[2].child_low = range[2].parent_low =
1160 	    (uint32_t)entry->pf_memory_base;
1161 
1162 	len = sizeof (pci_bus_range_t);
1163 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1164 	    "bus-range", (caddr_t)&bus_range, (int *)&len) != DDI_SUCCESS) {
1165 		DEBUG0("no bus-range property\n");
1166 		return (PCICFG_FAILURE);
1167 	}
1168 
1169 	new_bus_range[0] = bus_range.lo;	/* primary bus number */
1170 	if (entry->highest_bus) {	/* secondary bus number */
1171 		if (entry->highest_bus < bus_range.lo) {
1172 			cmn_err(CE_WARN,
1173 			    "ntbridge bus range invalid !(%d,%d)\n",
1174 			    bus_range.lo, entry->highest_bus);
1175 			new_bus_range[1] = bus_range.lo + entry->highest_bus;
1176 		}
1177 		else
1178 			new_bus_range[1] = entry->highest_bus;
1179 	}
1180 	else
1181 		new_bus_range[1] = bus_range.hi;
1182 
1183 	DEBUG2("ntbridge: bus range lo=%x, hi=%x\n", new_bus_range[0],
1184 	    new_bus_range[1]);
1185 
1186 	if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "bus-range",
1187 	    new_bus_range, 2) != DDI_SUCCESS) {
1188 		DEBUG0("Failed to set bus-range property");
1189 		entry->error = PCICFG_FAILURE;
1190 		return (PCICFG_FAILURE);
1191 	}
1192 
1193 #ifdef DEBUG
1194 	{
1195 		uint64_t	unused;
1196 		unused = pcicfg_unused_space(&entry->io_hole, &len);
1197 		DEBUG2("ntbridge: Unused IO space %llx bytes over %d holes\n",
1198 		    unused, len);
1199 	}
1200 #endif
1201 
1202 	range[0].size_low = entry->io_len;
1203 	if (pcicfg_update_ranges_prop(dip, &range[0])) {
1204 		DEBUG0("Failed to update ranges (i/o)\n");
1205 		entry->error = PCICFG_FAILURE;
1206 		return (PCICFG_FAILURE);
1207 	}
1208 
1209 #ifdef DEBUG
1210 	{
1211 		uint64_t	unused;
1212 		unused = pcicfg_unused_space(&entry->mem_hole, &len);
1213 		DEBUG2("ntbridge: Unused Mem space %llx bytes over %d holes\n",
1214 		    unused, len);
1215 	}
1216 #endif
1217 
1218 	range[1].size_low = entry->memory_len;
1219 	if (pcicfg_update_ranges_prop(dip, &range[1])) {
1220 		DEBUG0("Failed to update ranges (memory)\n");
1221 		entry->error = PCICFG_FAILURE;
1222 		return (PCICFG_FAILURE);
1223 	}
1224 
1225 #ifdef DEBUG
1226 	{
1227 		uint64_t	unused;
1228 		unused = pcicfg_unused_space(&entry->pf_mem_hole, &len);
1229 		DEBUG2("ntbridge: Unused PF Mem space %llx bytes over"
1230 		    " %d holes\n", unused, len);
1231 	}
1232 #endif
1233 
1234 	range[2].size_low = entry->pf_memory_len;
1235 	if (pcicfg_update_ranges_prop(dip, &range[2])) {
1236 		DEBUG0("Failed to update ranges (PF memory)\n");
1237 		entry->error = PCICFG_FAILURE;
1238 		return (PCICFG_FAILURE);
1239 	}
1240 
1241 	return (PCICFG_SUCCESS);
1242 }
1243 
1244 static int
1245 pcicfg_ntbridge_program_child(dev_info_t *dip)
1246 {
1247 	pcicfg_phdl_t	*entry;
1248 	int		rc = PCICFG_SUCCESS;
1249 	dev_info_t	*anode = dip;
1250 
1251 	/* Find the Hotplug Connection (CN) node */
1252 	while ((anode != NULL) &&
1253 	    (strcmp(ddi_binding_name(anode), "hp_attachment") != 0)) {
1254 		anode = ddi_get_parent(anode);
1255 	}
1256 
1257 	if (anode == NULL) {
1258 		DEBUG0("ntbridge child tree not in PROBE state\n");
1259 		return (PCICFG_FAILURE);
1260 	}
1261 	entry = pcicfg_find_phdl(ddi_get_parent(anode));
1262 	ASSERT(entry);
1263 
1264 	if (pcicfg_bridge_assign(dip, entry) == DDI_WALK_TERMINATE) {
1265 		cmn_err(CE_WARN,
1266 		    "ntbridge: Error assigning range for child %s\n",
1267 		    ddi_get_name(dip));
1268 		rc = PCICFG_FAILURE;
1269 	}
1270 	return (rc);
1271 }
1272 
1273 static int
1274 pcicfg_ntbridge_unconfigure_child(dev_info_t *new_device, uint_t devno)
1275 {
1276 
1277 	dev_info_t	*new_ntbridgechild;
1278 	int		len, bus;
1279 	uint16_t	vid;
1280 	ddi_acc_handle_t	config_handle;
1281 	pci_bus_range_t pci_bus_range;
1282 
1283 	len = sizeof (pci_bus_range_t);
1284 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, new_device, DDI_PROP_DONTPASS,
1285 	    "bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
1286 		DEBUG0("no bus-range property\n");
1287 		return (PCICFG_FAILURE);
1288 	}
1289 
1290 	bus = pci_bus_range.lo; /* primary bus number of this bus node */
1291 
1292 	ndi_devi_alloc_sleep(new_device, DEVI_PSEUDO_NEXNAME,
1293 	    (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild);
1294 
1295 	if (pcicfg_add_config_reg(new_ntbridgechild, bus, devno, 0)
1296 	    != DDI_PROP_SUCCESS) {
1297 		cmn_err(CE_WARN, "Unconfigure: Failed to add conf reg prop for "
1298 		    "ntbridge child.\n");
1299 		(void) ndi_devi_free(new_ntbridgechild);
1300 		return (PCICFG_FAILURE);
1301 	}
1302 
1303 	if (pci_config_setup(new_ntbridgechild, &config_handle)
1304 	    != DDI_SUCCESS) {
1305 		cmn_err(CE_WARN, "pcicfg: Cannot map ntbridge child %x\n",
1306 		    devno);
1307 		(void) ndi_devi_free(new_ntbridgechild);
1308 		return (PCICFG_FAILURE);
1309 	}
1310 
1311 	/*
1312 	 * See if there is any PCI HW at this location
1313 	 * by reading the Vendor ID.  If it returns with 0xffff
1314 	 * then there is no hardware at this location.
1315 	 */
1316 	vid = pci_config_get16(config_handle, PCI_CONF_VENID);
1317 
1318 	pci_config_teardown(&config_handle);
1319 	(void) ndi_devi_free(new_ntbridgechild);
1320 	if (vid	== 0xffff)
1321 		return (PCICFG_NODEVICE);
1322 
1323 	return (pcicfg_unconfigure(new_device, devno, PCICFG_ALL_FUNC, 0));
1324 }
1325 
1326 static uint_t
1327 pcicfg_ntbridge_unconfigure(dev_info_t *dip)
1328 {
1329 	pcicfg_phdl_t *entry = pcicfg_find_phdl(dip);
1330 	uint_t			*bus;
1331 	int			k, rc = DDI_FAILURE;
1332 
1333 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "bus-range",
1334 	    (caddr_t)&bus, &k) != DDI_PROP_SUCCESS) {
1335 		DEBUG0("ntbridge: Failed to read bus-range property\n");
1336 		return (rc);
1337 	}
1338 
1339 	DEBUG2("ntbridge: Need to free bus [%d] range [%d]\n",
1340 	    bus[0], bus[1] - bus[0] + 1);
1341 
1342 	if (ndi_ra_free(ddi_get_parent(dip), (uint64_t)bus[0],
1343 	    (uint64_t)(bus[1] - bus[0] + 1),
1344 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1345 		DEBUG0("ntbridge: Failed to free a bus number\n");
1346 		kmem_free(bus, k);
1347 		return (rc);
1348 	}
1349 
1350 	/*
1351 	 * Since our resources will be freed at the parent level,
1352 	 * just reset these values.
1353 	 */
1354 	entry->memory_len = 0;
1355 	entry->io_len = 0;
1356 	entry->pf_memory_len = 0;
1357 
1358 	kmem_free(bus, k);
1359 
1360 	/* the following will also free hole data. */
1361 	return (pcicfg_destroy_phdl(dip));
1362 
1363 }
1364 
1365 static int
1366 pcicfg_is_ntbridge(dev_info_t *dip)
1367 {
1368 	ddi_acc_handle_t	config_handle;
1369 	uint8_t		class, subclass;
1370 	int		rc = DDI_SUCCESS;
1371 
1372 	if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
1373 		cmn_err(CE_WARN,
1374 		    "pcicfg: cannot map config space, to get map type\n");
1375 		return (DDI_FAILURE);
1376 	}
1377 	class = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
1378 	subclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
1379 
1380 	/* check for class=6, subclass=9, for non transparent bridges.  */
1381 	if ((class != PCI_CLASS_BRIDGE) || (subclass != PCI_BRIDGE_STBRIDGE))
1382 		rc = DDI_FAILURE;
1383 
1384 	DEBUG3("pcicfg: checking device %x,%x for indirect map. rc=%d\n",
1385 	    pci_config_get16(config_handle, PCI_CONF_VENID),
1386 	    pci_config_get16(config_handle, PCI_CONF_DEVID),
1387 	    rc);
1388 	pci_config_teardown(&config_handle);
1389 	return (rc);
1390 }
1391 
1392 static uint_t
1393 pcicfg_ntbridge_child(dev_info_t *dip)
1394 {
1395 	int		len, val, rc = DDI_FAILURE;
1396 	dev_info_t	*anode = dip;
1397 
1398 	/*
1399 	 * Find the Hotplug Connection (CN) node
1400 	 */
1401 	while ((anode != NULL) && (strcmp(ddi_binding_name(anode),
1402 	    "hp_attachment") != 0)) {
1403 		anode = ddi_get_parent(anode);
1404 	}
1405 
1406 	if (anode == NULL) {
1407 		DEBUG0("ntbridge child tree not in PROBE state\n");
1408 		return (rc);
1409 	}
1410 	len = sizeof (int);
1411 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_get_parent(anode),
1412 	    DDI_PROP_DONTPASS, PCI_DEV_CONF_MAP_PROP, (caddr_t)&val, &len)
1413 	    != DDI_SUCCESS) {
1414 
1415 		DEBUG1("ntbridge child: no \"%s\" property\n",
1416 		    PCI_DEV_CONF_MAP_PROP);
1417 		return (rc);
1418 	}
1419 	DEBUG0("ntbridge child: success\n");
1420 	return (DDI_SUCCESS);
1421 }
1422 
1423 static uint_t
1424 pcicfg_get_ntbridge_child_range(dev_info_t *dip, uint64_t *boundbase,
1425     uint64_t *boundlen, uint_t space_type)
1426 {
1427 	int		length, found = DDI_FAILURE, acount, i, ibridge;
1428 	pci_regspec_t	*assigned;
1429 
1430 	if ((ibridge = pcicfg_is_ntbridge(dip)) == DDI_FAILURE)
1431 		return (found);
1432 
1433 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1434 	    "assigned-addresses", (caddr_t)&assigned, &length)
1435 	    != DDI_PROP_SUCCESS) {
1436 		DEBUG1("Failed to get assigned-addresses property %llx\n", dip);
1437 		return (found);
1438 	}
1439 	DEBUG1("pcicfg: ntbridge child range: dip = %s\n",
1440 	    ddi_driver_name(dip));
1441 
1442 	acount = length / sizeof (pci_regspec_t);
1443 
1444 	for (i = 0; i < acount; i++) {
1445 		if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1446 		    pcicfg_indirect_map_devs[ibridge].mem_range_bar_offset) &&
1447 		    (space_type == PCI_BASE_SPACE_MEM)) {
1448 			found = DDI_SUCCESS;
1449 			break;
1450 		} else if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1451 		    pcicfg_indirect_map_devs[ibridge].io_range_bar_offset) &&
1452 		    (space_type == PCI_BASE_SPACE_IO)) {
1453 			found = DDI_SUCCESS;
1454 			break;
1455 		} else if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1456 		    pcicfg_indirect_map_devs[ibridge].
1457 		    prefetch_mem_range_bar_offset) &&
1458 		    (space_type == (PCI_BASE_SPACE_MEM |
1459 		    PCI_BASE_PREF_M))) {
1460 			found = DDI_SUCCESS;
1461 			break;
1462 		}
1463 	}
1464 	DEBUG3("pcicfg: ntbridge child range: space=%x, base=%lx, len=%lx\n",
1465 	    space_type, assigned[i].pci_phys_low, assigned[i].pci_size_low);
1466 
1467 	if (found == DDI_SUCCESS)  {
1468 		*boundbase = assigned[i].pci_phys_low;
1469 		*boundlen = assigned[i].pci_size_low;
1470 	}
1471 
1472 	kmem_free(assigned, length);
1473 	return (found);
1474 }
1475 
1476 /*
1477  * This will turn  resources allocated by pcicfg_configure()
1478  * and remove the device tree from the Hotplug Connection (CN)
1479  * and below.  The routine assumes the devices have their
1480  * drivers detached.
1481  */
1482 int
1483 pcicfg_unconfigure(dev_info_t *devi, uint_t device, uint_t function,
1484     pcicfg_flags_t flags)
1485 {
1486 	dev_info_t *child_dip;
1487 	int func;
1488 	int i;
1489 	int max_function, trans_device;
1490 	int circ;
1491 	boolean_t is_pcie;
1492 
1493 	if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED)
1494 		max_function = PCICFG_MAX_ARI_FUNCTION;
1495 	else
1496 		max_function = PCI_MAX_FUNCTIONS;
1497 
1498 	/*
1499 	 * Cycle through devices to make sure none are busy.
1500 	 * If a single device is busy fail the whole unconfigure.
1501 	 */
1502 	is_pcie = is_pcie_fabric(devi);
1503 
1504 	ndi_devi_enter(devi, &circ);
1505 	for (func = 0; func < max_function; func++) {
1506 		if ((function != PCICFG_ALL_FUNC) && (function != func))
1507 			continue;
1508 
1509 		if (max_function == PCICFG_MAX_ARI_FUNCTION)
1510 			trans_device = func >> 3; /* ARI Device */
1511 		else
1512 			trans_device = device;
1513 
1514 		if ((child_dip = pcicfg_devi_find(devi, trans_device,
1515 		    func & 7)) == NULL)
1516 			continue;
1517 
1518 		if (ndi_devi_offline(child_dip, NDI_UNCONFIG) == NDI_SUCCESS)
1519 			continue;
1520 
1521 		/*
1522 		 * Device function is busy. Before returning we have to
1523 		 * put all functions back online which were taken
1524 		 * offline during the process.
1525 		 */
1526 		DEBUG2("Device [0x%x] function [0x%x] is busy\n",
1527 		    trans_device, func & 7);
1528 		/*
1529 		 * If we are only asked to offline one specific function,
1530 		 * and that fails, we just simply return.
1531 		 */
1532 		if (function != PCICFG_ALL_FUNC)
1533 			return (PCICFG_FAILURE);
1534 
1535 		for (i = 0; i < func; i++) {
1536 			if (max_function == PCICFG_MAX_ARI_FUNCTION)
1537 				trans_device = i >> 3;
1538 
1539 			if ((child_dip = pcicfg_devi_find(devi, trans_device,
1540 			    i & 7)) == NULL) {
1541 				DEBUG0("No more devices to put back "
1542 				    "on line!!\n");
1543 				/*
1544 				 * Made it through all functions
1545 				 */
1546 				continue;
1547 			}
1548 			if (ndi_devi_online(child_dip, NDI_CONFIG)
1549 			    != NDI_SUCCESS) {
1550 				DEBUG0("Failed to put back devices state\n");
1551 				goto fail;
1552 			}
1553 		}
1554 		goto fail;
1555 	}
1556 
1557 	/*
1558 	 * Now, tear down all devinfo nodes for this Connector.
1559 	 */
1560 	for (func = 0; func < max_function; func++) {
1561 		if ((function != PCICFG_ALL_FUNC) && (function != func))
1562 			continue;
1563 
1564 		if (max_function == PCICFG_MAX_ARI_FUNCTION)
1565 			trans_device = func >> 3; /* ARI Device */
1566 		else
1567 			trans_device = device;
1568 
1569 		if ((child_dip = pcicfg_devi_find(devi, trans_device, func & 7))
1570 		    == NULL) {
1571 			DEBUG2("No device at %x,%x\n", trans_device, func & 7);
1572 			continue;
1573 		}
1574 
1575 		DEBUG2("Tearing down device [0x%x] function [0x%x]\n",
1576 		    trans_device, func & 7);
1577 
1578 		if (pcicfg_is_ntbridge(child_dip) != DDI_FAILURE)
1579 			if (pcicfg_ntbridge_unconfigure(child_dip) !=
1580 			    PCICFG_SUCCESS) {
1581 				cmn_err(CE_WARN,
1582 				    "ntbridge: unconfigure failed\n");
1583 				goto fail;
1584 			}
1585 
1586 		if (pcicfg_teardown_device(child_dip, flags, is_pcie)
1587 		    != PCICFG_SUCCESS) {
1588 			DEBUG2("Failed to tear down device [0x%x]"
1589 			    "function [0x%x]\n", trans_device, func & 7);
1590 			goto fail;
1591 		}
1592 	}
1593 
1594 	if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED) {
1595 		(void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "ari-enabled");
1596 		(void) pcie_ari_disable(devi);
1597 	}
1598 
1599 	ndi_devi_exit(devi, circ);
1600 	return (PCICFG_SUCCESS);
1601 
1602 fail:
1603 	ndi_devi_exit(devi, circ);
1604 	return (PCICFG_FAILURE);
1605 }
1606 
1607 static int
1608 pcicfg_teardown_device(dev_info_t *dip, pcicfg_flags_t flags, boolean_t is_pcie)
1609 {
1610 	ddi_acc_handle_t	handle;
1611 	int			ret;
1612 
1613 	/*
1614 	 * Free up resources associated with 'dip'
1615 	 */
1616 	if (pcicfg_free_resources(dip, flags) != PCICFG_SUCCESS) {
1617 		DEBUG0("Failed to free resources\n");
1618 		return (PCICFG_FAILURE);
1619 	}
1620 
1621 	/*
1622 	 * disable the device
1623 	 */
1624 
1625 	ret = pcicfg_config_setup(dip, &handle);
1626 	if (ret == PCICFG_SUCCESS) {
1627 		pcicfg_device_off(handle);
1628 		pcicfg_config_teardown(&handle);
1629 	} else if (ret != PCICFG_NODEVICE) {
1630 		/*
1631 		 * It is possible the device no longer exists -- for instance,
1632 		 * if the device has been pulled from a hotpluggable slot on the
1633 		 * system. In this case, do not fail the teardown, though there
1634 		 * is less to clean up.
1635 		 */
1636 		return (PCICFG_FAILURE);
1637 	}
1638 
1639 	if (is_pcie) {
1640 		/*
1641 		 * free pcie_bus_t for the sub-tree
1642 		 */
1643 		if (ddi_get_child(dip) != NULL)
1644 			pcie_fab_fini_bus(dip, PCIE_BUS_ALL);
1645 
1646 		pcie_fini_bus(dip, PCIE_BUS_ALL);
1647 	}
1648 
1649 	/*
1650 	 * The framework provides this routine which can
1651 	 * tear down a sub-tree.
1652 	 */
1653 	if (ndi_devi_offline(dip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
1654 		DEBUG0("Failed to offline and remove node\n");
1655 		return (PCICFG_FAILURE);
1656 	}
1657 
1658 	return (PCICFG_SUCCESS);
1659 }
1660 
1661 /*
1662  * BEGIN GENERIC SUPPORT ROUTINES
1663  */
1664 static pcicfg_phdl_t *
1665 pcicfg_find_phdl(dev_info_t *dip)
1666 {
1667 	pcicfg_phdl_t *entry;
1668 	mutex_enter(&pcicfg_list_mutex);
1669 	for (entry = pcicfg_phdl_list; entry != NULL; entry = entry->next) {
1670 		if (entry->dip == dip) {
1671 			mutex_exit(&pcicfg_list_mutex);
1672 			return (entry);
1673 		}
1674 	}
1675 	mutex_exit(&pcicfg_list_mutex);
1676 
1677 	/*
1678 	 * Did'nt find entry - create one
1679 	 */
1680 	return (pcicfg_create_phdl(dip));
1681 }
1682 
1683 static pcicfg_phdl_t *
1684 pcicfg_create_phdl(dev_info_t *dip)
1685 {
1686 	pcicfg_phdl_t *new;
1687 
1688 	new = (pcicfg_phdl_t *)kmem_zalloc(sizeof (pcicfg_phdl_t), KM_SLEEP);
1689 
1690 	new->dip = dip;
1691 	mutex_enter(&pcicfg_list_mutex);
1692 	new->next = pcicfg_phdl_list;
1693 	pcicfg_phdl_list = new;
1694 	mutex_exit(&pcicfg_list_mutex);
1695 
1696 	return (new);
1697 }
1698 
1699 static int
1700 pcicfg_destroy_phdl(dev_info_t *dip)
1701 {
1702 	pcicfg_phdl_t *entry;
1703 	pcicfg_phdl_t *follow = NULL;
1704 
1705 	mutex_enter(&pcicfg_list_mutex);
1706 	for (entry = pcicfg_phdl_list; entry != NULL; follow = entry,
1707 	    entry = entry->next) {
1708 		if (entry->dip == dip) {
1709 			if (entry == pcicfg_phdl_list) {
1710 				pcicfg_phdl_list = entry->next;
1711 			} else {
1712 				follow->next = entry->next;
1713 			}
1714 			/*
1715 			 * If this entry has any allocated memory
1716 			 * or IO space associated with it, that
1717 			 * must be freed up.
1718 			 */
1719 			if (entry->memory_len > 0) {
1720 				(void) ndi_ra_free(ddi_get_parent(dip),
1721 				    entry->memory_base, entry->memory_len,
1722 				    NDI_RA_TYPE_MEM, NDI_RA_PASS);
1723 			}
1724 			pcicfg_free_hole(&entry->mem_hole);
1725 
1726 			if (entry->io_len > 0) {
1727 				(void) ndi_ra_free(ddi_get_parent(dip),
1728 				    entry->io_base, entry->io_len,
1729 				    NDI_RA_TYPE_IO, NDI_RA_PASS);
1730 			}
1731 			pcicfg_free_hole(&entry->io_hole);
1732 
1733 			if (entry->pf_memory_len > 0) {
1734 				(void) ndi_ra_free(ddi_get_parent(dip),
1735 				    entry->pf_memory_base, entry->pf_memory_len,
1736 				    NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
1737 			}
1738 			pcicfg_free_hole(&entry->pf_mem_hole);
1739 
1740 			/*
1741 			 * Destroy this entry
1742 			 */
1743 			kmem_free((caddr_t)entry, sizeof (pcicfg_phdl_t));
1744 			mutex_exit(&pcicfg_list_mutex);
1745 			return (PCICFG_SUCCESS);
1746 		}
1747 	}
1748 	mutex_exit(&pcicfg_list_mutex);
1749 	/*
1750 	 * Did'nt find the entry
1751 	 */
1752 	return (PCICFG_FAILURE);
1753 }
1754 
1755 static int
1756 pcicfg_bridge_assign(dev_info_t *dip, void *hdl)
1757 {
1758 	ddi_acc_handle_t handle;
1759 	pci_regspec_t *reg;
1760 	int length;
1761 	int rcount;
1762 	int i;
1763 	int offset;
1764 	uint64_t mem_answer;
1765 	uint32_t io_answer;
1766 	int count;
1767 	uint8_t header_type;
1768 	ppb_ranges_t range[PCICFG_RANGE_LEN];
1769 	int bus_range[2];
1770 	uint64_t mem_residual;
1771 	uint64_t pf_mem_residual;
1772 	uint64_t io_residual;
1773 
1774 	pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
1775 
1776 	DEBUG1("bridge assign: assigning addresses to %s\n", ddi_get_name(dip));
1777 
1778 	entry->error = PCICFG_SUCCESS;
1779 
1780 	if (entry == NULL) {
1781 		DEBUG0("Failed to get entry\n");
1782 		entry->error = PCICFG_FAILURE;
1783 		return (DDI_WALK_TERMINATE);
1784 	}
1785 
1786 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
1787 		DEBUG0("Failed to map config space!\n");
1788 		entry->error = PCICFG_FAILURE;
1789 		return (DDI_WALK_TERMINATE);
1790 	}
1791 
1792 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1793 
1794 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1795 
1796 		bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
1797 
1798 		(void) pcicfg_setup_bridge(entry, handle);
1799 
1800 		range[0].child_high = range[0].parent_high |=
1801 		    (PCI_REG_REL_M | PCI_ADDR_IO);
1802 		range[0].child_low = range[0].parent_low = entry->io_last;
1803 		range[1].child_high = range[1].parent_high |=
1804 		    (PCI_REG_REL_M | PCI_ADDR_MEM32);
1805 		range[1].child_low = range[1].parent_low =
1806 		    entry->memory_last;
1807 		range[2].child_high = range[2].parent_high |=
1808 		    (PCI_REG_REL_M | PCI_ADDR_MEM32 | PCI_REG_PF_M);
1809 		range[2].child_low = range[2].parent_low =
1810 		    entry->pf_memory_last;
1811 
1812 		ndi_devi_enter(dip, &count);
1813 		ddi_walk_devs(ddi_get_child(dip),
1814 		    pcicfg_bridge_assign, (void *)entry);
1815 		ndi_devi_exit(dip, count);
1816 
1817 		(void) pcicfg_update_bridge(entry, handle);
1818 
1819 		bus_range[0] = pci_config_get8(handle, PCI_BCNF_SECBUS);
1820 		bus_range[1] = pci_config_get8(handle, PCI_BCNF_SUBBUS);
1821 
1822 		if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1823 		    "bus-range", bus_range, 2) != DDI_SUCCESS) {
1824 			DEBUG0("Failed to set bus-range property");
1825 			entry->error = PCICFG_FAILURE;
1826 			(void) pcicfg_config_teardown(&handle);
1827 			return (DDI_WALK_TERMINATE);
1828 		}
1829 
1830 		/*
1831 		 * Put back memory and I/O space not allocated
1832 		 * under the bridge.
1833 		 */
1834 		mem_residual = entry->memory_len -
1835 		    (entry->memory_last - entry->memory_base);
1836 		if (mem_residual > 0) {
1837 			(void) ndi_ra_free(ddi_get_parent(dip),
1838 			    entry->memory_last, mem_residual,
1839 			    NDI_RA_TYPE_MEM, NDI_RA_PASS);
1840 		}
1841 
1842 		io_residual = entry->io_len - (entry->io_last - entry->io_base);
1843 		if (io_residual > 0) {
1844 			(void) ndi_ra_free(ddi_get_parent(dip), entry->io_last,
1845 			    io_residual, NDI_RA_TYPE_IO, NDI_RA_PASS);
1846 		}
1847 
1848 		pf_mem_residual = entry->pf_memory_len -
1849 		    (entry->pf_memory_last - entry->pf_memory_base);
1850 		if (pf_mem_residual > 0) {
1851 			(void) ndi_ra_free(ddi_get_parent(dip),
1852 			    entry->pf_memory_last, pf_mem_residual,
1853 			    NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
1854 		}
1855 
1856 		if (entry->io_len > 0) {
1857 			range[0].size_low = entry->io_last - entry->io_base;
1858 			if (pcicfg_update_ranges_prop(dip, &range[0])) {
1859 				DEBUG0("Failed to update ranges (i/o)\n");
1860 				entry->error = PCICFG_FAILURE;
1861 				(void) pcicfg_config_teardown(&handle);
1862 				return (DDI_WALK_TERMINATE);
1863 			}
1864 		}
1865 		if (entry->memory_len > 0) {
1866 			range[1].size_low =
1867 			    entry->memory_last - entry->memory_base;
1868 			if (pcicfg_update_ranges_prop(dip, &range[1])) {
1869 				DEBUG0("Failed to update ranges (memory)\n");
1870 				entry->error = PCICFG_FAILURE;
1871 				(void) pcicfg_config_teardown(&handle);
1872 				return (DDI_WALK_TERMINATE);
1873 			}
1874 		}
1875 		if (entry->pf_memory_len > 0) {
1876 			range[2].size_low =
1877 			    entry->pf_memory_last - entry->pf_memory_base;
1878 			if (pcicfg_update_ranges_prop(dip, &range[2])) {
1879 				DEBUG0("Failed to update ranges (PF memory)\n");
1880 				entry->error = PCICFG_FAILURE;
1881 				(void) pcicfg_config_teardown(&handle);
1882 				return (DDI_WALK_TERMINATE);
1883 			}
1884 		}
1885 
1886 		(void) pcicfg_device_on(handle);
1887 
1888 		PCICFG_DUMP_BRIDGE_CONFIG(handle);
1889 
1890 		(void) pcicfg_config_teardown(&handle);
1891 
1892 		return (DDI_WALK_PRUNECHILD);
1893 	}
1894 
1895 	/*
1896 	 * If there is an interrupt pin set program
1897 	 * interrupt line with default values.
1898 	 */
1899 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1900 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1901 	}
1902 
1903 	/*
1904 	 * A single device (under a bridge).
1905 	 * For each "reg" property with a length, allocate memory
1906 	 * and program the base registers.
1907 	 */
1908 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
1909 	    (caddr_t)&reg, &length) != DDI_PROP_SUCCESS) {
1910 		DEBUG0("Failed to read reg property\n");
1911 		entry->error = PCICFG_FAILURE;
1912 		(void) pcicfg_config_teardown(&handle);
1913 		return (DDI_WALK_TERMINATE);
1914 	}
1915 
1916 	rcount = length / sizeof (pci_regspec_t);
1917 	offset = PCI_CONF_BASE0;
1918 	for (i = 0; i < rcount; i++) {
1919 		if ((reg[i].pci_size_low != 0) || (reg[i].pci_size_hi != 0)) {
1920 
1921 			offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
1922 
1923 			switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
1924 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
1925 
1926 				if (reg[i].pci_phys_hi & PCI_REG_PF_M) {
1927 					/* allocate prefetchable memory */
1928 					pcicfg_get_pf_mem(entry,
1929 					    reg[i].pci_size_low, &mem_answer);
1930 				} else { /* get non prefetchable memory */
1931 					pcicfg_get_mem(entry,
1932 					    reg[i].pci_size_low, &mem_answer);
1933 				}
1934 				pci_config_put64(handle, offset, mem_answer);
1935 				DEBUG2("REGISTER off %x (64)LO ----> [0x%x]\n",
1936 				    offset, pci_config_get32(handle, offset));
1937 				DEBUG2("REGISTER off %x (64)HI ----> [0x%x]\n",
1938 				    offset + 4,
1939 				    pci_config_get32(handle, offset + 4));
1940 
1941 				reg[i].pci_phys_hi |= PCI_REG_REL_M;
1942 				reg[i].pci_phys_low = PCICFG_LOADDR(mem_answer);
1943 				reg[i].pci_phys_mid = PCICFG_HIADDR(mem_answer);
1944 				break;
1945 
1946 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
1947 				if (reg[i].pci_phys_hi & PCI_REG_PF_M) {
1948 					/* allocate prefetchable memory */
1949 					pcicfg_get_pf_mem(entry,
1950 					    reg[i].pci_size_low, &mem_answer);
1951 				} else {
1952 					/* get non prefetchable memory */
1953 					pcicfg_get_mem(entry,
1954 					    reg[i].pci_size_low, &mem_answer);
1955 				}
1956 
1957 				pci_config_put32(handle, offset,
1958 				    (uint32_t)mem_answer);
1959 
1960 				DEBUG2("REGISTER off %x(32)LO ----> [0x%x]\n",
1961 				    offset, pci_config_get32(handle, offset));
1962 
1963 				reg[i].pci_phys_hi |= PCI_REG_REL_M;
1964 				reg[i].pci_phys_low = (uint32_t)mem_answer;
1965 
1966 				break;
1967 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
1968 				/* allocate I/O space from the allocator */
1969 
1970 				(void) pcicfg_get_io(entry, reg[i].pci_size_low,
1971 				    &io_answer);
1972 				pci_config_put32(handle, offset, io_answer);
1973 
1974 				DEBUG2("REGISTER off %x (I/O)LO ----> [0x%x]\n",
1975 				    offset, pci_config_get32(handle, offset));
1976 
1977 				reg[i].pci_phys_hi |= PCI_REG_REL_M;
1978 				reg[i].pci_phys_low = io_answer;
1979 
1980 				break;
1981 			default:
1982 				DEBUG0("Unknown register type\n");
1983 				kmem_free(reg, length);
1984 				(void) pcicfg_config_teardown(&handle);
1985 				entry->error = PCICFG_FAILURE;
1986 				return (DDI_WALK_TERMINATE);
1987 			} /* switch */
1988 
1989 			/*
1990 			 * Now that memory locations are assigned,
1991 			 * update the assigned address property.
1992 			 */
1993 			if (pcicfg_update_assigned_prop(dip, &reg[i])
1994 			    != PCICFG_SUCCESS) {
1995 				kmem_free(reg, length);
1996 				(void) pcicfg_config_teardown(&handle);
1997 				entry->error = PCICFG_FAILURE;
1998 				return (DDI_WALK_TERMINATE);
1999 			}
2000 		}
2001 	}
2002 	(void) pcicfg_device_on(handle);
2003 
2004 	PCICFG_DUMP_DEVICE_CONFIG(handle);
2005 
2006 	(void) pcicfg_config_teardown(&handle);
2007 	kmem_free((caddr_t)reg, length);
2008 	return (DDI_WALK_CONTINUE);
2009 }
2010 
2011 static int
2012 pcicfg_device_assign(dev_info_t *dip)
2013 {
2014 	ddi_acc_handle_t	handle;
2015 	pci_regspec_t		*reg;
2016 	int			length;
2017 	int			rcount;
2018 	int			i;
2019 	int			offset;
2020 	ndi_ra_request_t	request;
2021 	uint64_t		answer;
2022 	uint64_t		alen;
2023 
2024 	DEBUG1("%llx now under configuration\n", dip);
2025 
2026 	/* request.ra_len = PCICFG_ROUND_UP(request.ra_len, PCICFG_IOGRAN); */
2027 	if (pcicfg_ntbridge_child(dip) == DDI_SUCCESS) {
2028 
2029 		return (pcicfg_ntbridge_program_child(dip));
2030 	}
2031 	/*
2032 	 * XXX Failure here should be noted
2033 	 */
2034 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
2035 	    (caddr_t)&reg, &length) != DDI_PROP_SUCCESS) {
2036 		DEBUG0("Failed to read reg property\n");
2037 		return (PCICFG_FAILURE);
2038 	}
2039 
2040 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2041 		DEBUG0("Failed to map config space!\n");
2042 		kmem_free(reg, length);
2043 		return (PCICFG_FAILURE);
2044 	}
2045 
2046 	/*
2047 	 * A single device
2048 	 *
2049 	 * For each "reg" property with a length, allocate memory
2050 	 * and program the base registers.
2051 	 */
2052 
2053 	/*
2054 	 * If there is an interrupt pin set program
2055 	 * interrupt line with default values.
2056 	 */
2057 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2058 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2059 	}
2060 
2061 	bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2062 
2063 	/*
2064 	 * Note: Both non-prefetchable and prefetchable memory space
2065 	 * allocations are made within 32bit space. Currently, BIOSs
2066 	 * allocate device memory for PCI devices within the 32bit space
2067 	 * so this will not be a problem.
2068 	 */
2069 	request.ra_flags |= NDI_RA_ALIGN_SIZE | NDI_RA_ALLOC_BOUNDED;
2070 	request.ra_boundbase = 0;
2071 	request.ra_boundlen = PCICFG_4GIG_LIMIT;
2072 
2073 	rcount = length / sizeof (pci_regspec_t);
2074 	offset = PCI_CONF_BASE0;
2075 	for (i = 0; i < rcount; i++) {
2076 		char	*mem_type;
2077 
2078 		if ((reg[i].pci_size_low != 0)|| (reg[i].pci_size_hi != 0)) {
2079 
2080 			offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
2081 			request.ra_len = reg[i].pci_size_low;
2082 
2083 			switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
2084 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2085 				if (reg[i].pci_phys_hi & PCI_REG_PF_M) {
2086 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2087 				} else {
2088 					mem_type = NDI_RA_TYPE_MEM;
2089 				}
2090 				/* allocate memory space from the allocator */
2091 				if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2092 				    &answer, &alen, mem_type, NDI_RA_PASS)
2093 				    != NDI_SUCCESS) {
2094 					DEBUG0("Failed to allocate 64b mem\n");
2095 					kmem_free(reg, length);
2096 					(void) pcicfg_config_teardown(&handle);
2097 					return (PCICFG_NORESRC);
2098 				}
2099 				DEBUG3("64 addr = [0x%x.0x%x] len [0x%x]\n",
2100 				    PCICFG_HIADDR(answer),
2101 				    PCICFG_LOADDR(answer), alen);
2102 				/* program the low word */
2103 				pci_config_put32(handle, offset,
2104 				    PCICFG_LOADDR(answer));
2105 				/* program the high word */
2106 				pci_config_put32(handle, offset + 4,
2107 				    PCICFG_HIADDR(answer));
2108 
2109 				reg[i].pci_phys_hi |= PCI_REG_REL_M;
2110 				reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2111 				reg[i].pci_phys_mid = PCICFG_HIADDR(answer);
2112 				/*
2113 				 * currently support 32b address space
2114 				 * assignments only.
2115 				 */
2116 				reg[i].pci_phys_hi ^=
2117 				    PCI_ADDR_MEM64 ^ PCI_ADDR_MEM32;
2118 
2119 				offset += 8;
2120 				break;
2121 
2122 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2123 				if (reg[i].pci_phys_hi & PCI_REG_PF_M)
2124 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2125 				else
2126 					mem_type = NDI_RA_TYPE_MEM;
2127 				/* allocate memory space from the allocator */
2128 				if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2129 				    &answer, &alen, mem_type, NDI_RA_PASS)
2130 				    != NDI_SUCCESS) {
2131 					DEBUG0("Failed to allocate 32b mem\n");
2132 					kmem_free(reg, length);
2133 					(void) pcicfg_config_teardown(&handle);
2134 					return (PCICFG_NORESRC);
2135 				}
2136 				DEBUG3("32 addr = [0x%x.0x%x] len [0x%x]\n",
2137 				    PCICFG_HIADDR(answer),
2138 				    PCICFG_LOADDR(answer),
2139 				    alen);
2140 				/* program the low word */
2141 				pci_config_put32(handle, offset,
2142 				    PCICFG_LOADDR(answer));
2143 
2144 				reg[i].pci_phys_hi |= PCI_REG_REL_M;
2145 				reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2146 				reg[i].pci_phys_mid = 0;
2147 
2148 				offset += 4;
2149 				break;
2150 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2151 				/*
2152 				 * Try to allocate I/O space. If it fails,
2153 				 * continue here instead of returning failure
2154 				 * so that the hotplug for drivers that don't
2155 				 * use I/O space can succeed, For drivers
2156 				 * that need to use I/O space, the hotplug
2157 				 * will still fail later during driver attach.
2158 				 */
2159 				if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2160 				    &answer, &alen, NDI_RA_TYPE_IO, NDI_RA_PASS)
2161 				    != NDI_SUCCESS) {
2162 					DEBUG0("Failed to allocate I/O\n");
2163 					continue;
2164 				}
2165 				DEBUG3("I/O addr = [0x%x.0x%x] len [0x%x]\n",
2166 				    PCICFG_HIADDR(answer),
2167 				    PCICFG_LOADDR(answer), alen);
2168 				pci_config_put32(handle, offset,
2169 				    PCICFG_LOADDR(answer));
2170 
2171 				reg[i].pci_phys_hi |= PCI_REG_REL_M;
2172 				reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2173 
2174 				offset += 4;
2175 				break;
2176 			default:
2177 				DEBUG0("Unknown register type\n");
2178 				kmem_free(reg, length);
2179 				(void) pcicfg_config_teardown(&handle);
2180 				return (PCICFG_FAILURE);
2181 			} /* switch */
2182 
2183 			/*
2184 			 * Now that memory locations are assigned,
2185 			 * update the assigned address property.
2186 			 */
2187 
2188 			if (pcicfg_update_assigned_prop(dip, &reg[i])
2189 			    != PCICFG_SUCCESS) {
2190 				kmem_free(reg, length);
2191 				(void) pcicfg_config_teardown(&handle);
2192 				return (PCICFG_FAILURE);
2193 			}
2194 		}
2195 	}
2196 
2197 	(void) pcicfg_device_on(handle);
2198 	kmem_free(reg, length);
2199 
2200 	PCICFG_DUMP_DEVICE_CONFIG(handle);
2201 
2202 	(void) pcicfg_config_teardown(&handle);
2203 	return (PCICFG_SUCCESS);
2204 }
2205 
2206 static int
2207 pcicfg_device_assign_readonly(dev_info_t *dip)
2208 {
2209 	ddi_acc_handle_t	handle;
2210 	pci_regspec_t		*assigned;
2211 	int			length;
2212 	int			acount;
2213 	int			i;
2214 	ndi_ra_request_t	request;
2215 	uint64_t		answer;
2216 	uint64_t		alen;
2217 
2218 	DEBUG1("%llx now under configuration\n", dip);
2219 
2220 	/*
2221 	 * we don't support ntbridges for readonly probe.
2222 	 */
2223 	if (pcicfg_ntbridge_child(dip) == DDI_SUCCESS) {
2224 		return (PCICFG_FAILURE);
2225 	}
2226 
2227 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2228 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
2229 	    &length) != DDI_PROP_SUCCESS) {
2230 		DEBUG0("Failed to read assigned-addresses property\n");
2231 		return (PCICFG_FAILURE);
2232 	}
2233 
2234 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2235 		DEBUG0("Failed to map config space!\n");
2236 		kmem_free(assigned, length);
2237 		return (PCICFG_FAILURE);
2238 	}
2239 
2240 	/*
2241 	 * If there is an interrupt pin set program
2242 	 * interrupt line with default values.
2243 	 */
2244 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2245 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2246 	}
2247 	/*
2248 	 * Note: Both non-prefetchable and prefetchable memory space
2249 	 * allocations are made within 32bit space. Currently, BIOSs
2250 	 * allocate device memory for PCI devices within the 32bit space
2251 	 * so this will not be a problem.
2252 	 */
2253 	bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2254 
2255 	request.ra_flags = NDI_RA_ALLOC_SPECIFIED;  /* specified addr */
2256 	request.ra_boundbase = 0;
2257 	request.ra_boundlen = PCICFG_4GIG_LIMIT;
2258 
2259 	acount = length / sizeof (pci_regspec_t);
2260 	for (i = 0; i < acount; i++) {
2261 		char	*mem_type;
2262 
2263 		if ((assigned[i].pci_size_low != 0)||
2264 		    (assigned[i].pci_size_hi != 0)) {
2265 
2266 			request.ra_len = assigned[i].pci_size_low;
2267 
2268 			switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2269 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2270 				request.ra_addr = (uint64_t)PCICFG_LADDR(
2271 				    assigned[i].pci_phys_low,
2272 				    assigned[i].pci_phys_mid);
2273 
2274 				if (assigned[i].pci_phys_hi & PCI_REG_PF_M) {
2275 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2276 				} else {
2277 					mem_type = NDI_RA_TYPE_MEM;
2278 				}
2279 				/* allocate memory space from the allocator */
2280 				if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2281 				    &answer, &alen, mem_type, NDI_RA_PASS)
2282 				    != NDI_SUCCESS) {
2283 					DEBUG0("Failed to allocate 64b mem\n");
2284 					kmem_free(assigned, length);
2285 					return (PCICFG_NORESRC);
2286 				}
2287 
2288 				break;
2289 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2290 				request.ra_addr = (uint64_t)
2291 				    assigned[i].pci_phys_low;
2292 
2293 				if (assigned[i].pci_phys_hi & PCI_REG_PF_M)
2294 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2295 				else
2296 					mem_type = NDI_RA_TYPE_MEM;
2297 				/* allocate memory space from the allocator */
2298 				if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2299 				    &answer, &alen, mem_type, NDI_RA_PASS)
2300 				    != NDI_SUCCESS) {
2301 					DEBUG0("Failed to allocate 32b mem\n");
2302 					kmem_free(assigned, length);
2303 					return (PCICFG_NORESRC);
2304 				}
2305 
2306 				break;
2307 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2308 				request.ra_addr = (uint64_t)
2309 				    assigned[i].pci_phys_low;
2310 
2311 				/* allocate I/O space from the allocator */
2312 				if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2313 				    &answer, &alen, NDI_RA_TYPE_IO, NDI_RA_PASS)
2314 				    != NDI_SUCCESS) {
2315 					DEBUG0("Failed to allocate I/O\n");
2316 					kmem_free(assigned, length);
2317 					return (PCICFG_NORESRC);
2318 				}
2319 
2320 				break;
2321 			default:
2322 				DEBUG0("Unknown register type\n");
2323 				kmem_free(assigned, length);
2324 				return (PCICFG_FAILURE);
2325 			} /* switch */
2326 		}
2327 	}
2328 
2329 	(void) pcicfg_device_on(handle);
2330 	kmem_free(assigned, length);
2331 
2332 	PCICFG_DUMP_DEVICE_CONFIG(handle);
2333 
2334 	(void) pcicfg_config_teardown(&handle);
2335 	return (PCICFG_SUCCESS);
2336 }
2337 
2338 #ifdef	DEBUG
2339 /*
2340  * This function is useful in debug mode, where we can measure how
2341  * much memory was wasted/unallocated in bridge device's domain.
2342  */
2343 static uint64_t
2344 pcicfg_unused_space(hole_t *hole, uint32_t *hole_count)
2345 {
2346 	uint64_t len = 0;
2347 	uint32_t count = 0;
2348 
2349 	do {
2350 		len += hole->len;
2351 		hole = hole->next;
2352 		count++;
2353 	} while (hole);
2354 	*hole_count = count;
2355 	return (len);
2356 }
2357 #endif
2358 
2359 /*
2360  * This function frees data structures that hold the hole information
2361  * which are allocated in pcicfg_alloc_hole(). This is not freeing
2362  * any memory allocated through NDI calls.
2363  */
2364 static void
2365 pcicfg_free_hole(hole_t *addr_hole)
2366 {
2367 	hole_t *nhole, *hole = addr_hole->next;
2368 
2369 	while (hole) {
2370 		nhole = hole->next;
2371 		kmem_free(hole, sizeof (hole_t));
2372 		hole = nhole;
2373 	}
2374 }
2375 
2376 static uint64_t
2377 pcicfg_alloc_hole(hole_t *addr_hole, uint64_t *alast, uint32_t length)
2378 {
2379 	uint64_t actual_hole_start, ostart, olen;
2380 	hole_t	*hole = addr_hole, *thole, *nhole;
2381 
2382 	do {
2383 		actual_hole_start = PCICFG_ROUND_UP(hole->start, length);
2384 		if (((actual_hole_start - hole->start) + length) <= hole->len) {
2385 			DEBUG3("hole found. start %llx, len %llx, req=0x%x\n",
2386 			    hole->start, hole->len, length);
2387 			ostart = hole->start;
2388 			olen = hole->len;
2389 			/* current hole parameters adjust */
2390 			if ((actual_hole_start - hole->start) == 0) {
2391 				hole->start += length;
2392 				hole->len -= length;
2393 				if (hole->start > *alast)
2394 					*alast = hole->start;
2395 			} else {
2396 				hole->len = actual_hole_start - hole->start;
2397 				nhole = (hole_t *)kmem_zalloc(sizeof (hole_t),
2398 				    KM_SLEEP);
2399 				nhole->start = actual_hole_start + length;
2400 				nhole->len = (ostart + olen) - nhole->start;
2401 				nhole->next = NULL;
2402 				thole = hole->next;
2403 				hole->next = nhole;
2404 				nhole->next = thole;
2405 				if (nhole->start > *alast)
2406 					*alast = nhole->start;
2407 				DEBUG2("put new hole to %llx, %llx\n",
2408 				    nhole->start, nhole->len);
2409 			}
2410 			DEBUG2("adjust current hole to %llx, %llx\n",
2411 			    hole->start, hole->len);
2412 			break;
2413 		}
2414 		actual_hole_start = 0;
2415 		hole = hole->next;
2416 	} while (hole);
2417 
2418 	DEBUG1("return hole at %llx\n", actual_hole_start);
2419 	return (actual_hole_start);
2420 }
2421 
2422 static void
2423 pcicfg_get_mem(pcicfg_phdl_t *entry, uint32_t length, uint64_t *ans)
2424 {
2425 	uint64_t new_mem;
2426 
2427 	/* See if there is a hole, that can hold this request. */
2428 	new_mem = pcicfg_alloc_hole(&entry->mem_hole, &entry->memory_last,
2429 	    length);
2430 	if (new_mem) {	/* if non-zero, found a hole. */
2431 		if (ans != NULL)
2432 			*ans = new_mem;
2433 	} else
2434 		cmn_err(CE_WARN, "No %u bytes memory window for %s\n",
2435 		    length, ddi_get_name(entry->dip));
2436 }
2437 
2438 static void
2439 pcicfg_get_io(pcicfg_phdl_t *entry, uint32_t length, uint32_t *ans)
2440 {
2441 	uint32_t new_io;
2442 	uint64_t io_last;
2443 
2444 	/*
2445 	 * See if there is a hole, that can hold this request.
2446 	 * Pass 64 bit parameters and then truncate to 32 bit.
2447 	 */
2448 	io_last = entry->io_last;
2449 	new_io = (uint32_t)pcicfg_alloc_hole(&entry->io_hole, &io_last, length);
2450 	if (new_io) {	/* if non-zero, found a hole. */
2451 		entry->io_last = (uint32_t)io_last;
2452 		if (ans != NULL)
2453 			*ans = new_io;
2454 	} else
2455 		cmn_err(CE_WARN, "No %u bytes IO space window for %s\n",
2456 		    length, ddi_get_name(entry->dip));
2457 }
2458 
2459 static void
2460 pcicfg_get_pf_mem(pcicfg_phdl_t *entry, uint32_t length, uint64_t *ans)
2461 {
2462 	uint64_t new_mem;
2463 
2464 	/* See if there is a hole, that can hold this request. */
2465 	new_mem = pcicfg_alloc_hole(&entry->pf_mem_hole, &entry->pf_memory_last,
2466 	    length);
2467 	if (new_mem) {	/* if non-zero, found a hole. */
2468 		if (ans != NULL)
2469 			*ans = new_mem;
2470 	} else
2471 		cmn_err(CE_WARN, "No %u bytes PF memory window for %s\n",
2472 		    length, ddi_get_name(entry->dip));
2473 }
2474 
2475 #ifdef __sparc
2476 static int
2477 pcicfg_sum_resources(dev_info_t *dip, void *hdl)
2478 {
2479 	pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
2480 	pci_regspec_t *pci_rp;
2481 	int length;
2482 	int rcount;
2483 	int i;
2484 	ndi_ra_request_t *pf_mem_request;
2485 	ndi_ra_request_t *mem_request;
2486 	ndi_ra_request_t *io_request;
2487 	uint8_t header_type;
2488 	ddi_acc_handle_t handle;
2489 
2490 	entry->error = PCICFG_SUCCESS;
2491 
2492 	pf_mem_request = &entry->pf_mem_req;
2493 	mem_request = &entry->mem_req;
2494 	io_request =  &entry->io_req;
2495 
2496 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2497 		DEBUG0("Failed to map config space!\n");
2498 		entry->error = PCICFG_FAILURE;
2499 		return (DDI_WALK_TERMINATE);
2500 	}
2501 
2502 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2503 
2504 	/*
2505 	 * If its a bridge - just record the highest bus seen
2506 	 */
2507 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2508 
2509 		if (entry->highest_bus < pci_config_get8(handle,
2510 		    PCI_BCNF_SECBUS)) {
2511 			entry->highest_bus =
2512 			    pci_config_get8(handle, PCI_BCNF_SECBUS);
2513 		}
2514 		(void) pcicfg_config_teardown(&handle);
2515 		entry->error = PCICFG_FAILURE;
2516 		return (DDI_WALK_CONTINUE);
2517 	} else {
2518 		if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2519 		    "reg", (caddr_t)&pci_rp, &length) != DDI_PROP_SUCCESS) {
2520 			/*
2521 			 * If one node in (the subtree of nodes)
2522 			 * doesn't have a "reg" property fail the
2523 			 * allocation.
2524 			 */
2525 			entry->memory_len = 0;
2526 			entry->io_len = 0;
2527 			entry->pf_memory_len = 0;
2528 			entry->error = PCICFG_FAILURE;
2529 			(void) pcicfg_config_teardown(&handle);
2530 			return (DDI_WALK_TERMINATE);
2531 		}
2532 		/*
2533 		 * For each "reg" property with a length, add that to the
2534 		 * total memory (or I/O) to allocate.
2535 		 */
2536 		rcount = length / sizeof (pci_regspec_t);
2537 
2538 		for (i = 0; i < rcount; i++) {
2539 
2540 			switch (PCI_REG_ADDR_G(pci_rp[i].pci_phys_hi)) {
2541 
2542 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2543 				if (pci_rp[i].pci_phys_hi & PCI_REG_PF_M) {
2544 					pf_mem_request->ra_len =
2545 					    pci_rp[i].pci_size_low +
2546 					    PCICFG_ROUND_UP(
2547 					    pf_mem_request->ra_len,
2548 					    pci_rp[i].pci_size_low);
2549 					DEBUG1("ADDING 32 --->0x%x\n",
2550 					    pci_rp[i].pci_size_low);
2551 				} else {
2552 					mem_request->ra_len =
2553 					    pci_rp[i].pci_size_low +
2554 					    PCICFG_ROUND_UP(mem_request->ra_len,
2555 					    pci_rp[i].pci_size_low);
2556 					DEBUG1("ADDING 32 --->0x%x\n",
2557 					    pci_rp[i].pci_size_low);
2558 				}
2559 
2560 				break;
2561 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2562 				if (pci_rp[i].pci_phys_hi & PCI_REG_PF_M) {
2563 					pf_mem_request->ra_len =
2564 					    pci_rp[i].pci_size_low +
2565 					    PCICFG_ROUND_UP(
2566 					    pf_mem_request->ra_len,
2567 					    pci_rp[i].pci_size_low);
2568 					DEBUG1("ADDING 64 --->0x%x\n",
2569 					    pci_rp[i].pci_size_low);
2570 				} else {
2571 					mem_request->ra_len =
2572 					    pci_rp[i].pci_size_low +
2573 					    PCICFG_ROUND_UP(mem_request->ra_len,
2574 					    pci_rp[i].pci_size_low);
2575 					DEBUG1("ADDING 64 --->0x%x\n",
2576 					    pci_rp[i].pci_size_low);
2577 				}
2578 
2579 				break;
2580 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2581 				io_request->ra_len =
2582 				    pci_rp[i].pci_size_low +
2583 				    PCICFG_ROUND_UP(io_request->ra_len,
2584 				    pci_rp[i].pci_size_low);
2585 				DEBUG1("ADDING I/O --->0x%x\n",
2586 				    pci_rp[i].pci_size_low);
2587 				break;
2588 			default:
2589 				/* Config space register - not included */
2590 				break;
2591 			}
2592 		}
2593 
2594 		/*
2595 		 * free the memory allocated by ddi_getlongprop
2596 		 */
2597 		kmem_free(pci_rp, length);
2598 
2599 		/*
2600 		 * continue the walk to the next sibling to sum memory
2601 		 */
2602 
2603 		(void) pcicfg_config_teardown(&handle);
2604 
2605 		return (DDI_WALK_CONTINUE);
2606 	}
2607 }
2608 #endif /* __sparc */
2609 
2610 static int
2611 pcicfg_free_bridge_resources(dev_info_t *dip)
2612 {
2613 	ppb_ranges_t		*ranges;
2614 	uint_t			*bus;
2615 	int			k;
2616 	int			length = 0;
2617 	int			i;
2618 
2619 
2620 	if ((i = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2621 	    "ranges", (caddr_t)&ranges, &length)) != DDI_PROP_SUCCESS) {
2622 		DEBUG0("Failed to read ranges property\n");
2623 		if (ddi_get_child(dip)) {
2624 			cmn_err(CE_WARN, "No ranges property found for %s",
2625 			    ddi_get_name(dip));
2626 			/*
2627 			 * strictly speaking, we can check for children with
2628 			 * assigned-addresses but for now it is better to
2629 			 * be conservative and assume that if there are child
2630 			 * nodes, then they do consume PCI memory or IO
2631 			 * resources, Hence return failure.
2632 			 */
2633 			return (PCICFG_FAILURE);
2634 		}
2635 		length = 0;
2636 	}
2637 
2638 	for (i = 0; i < length / sizeof (ppb_ranges_t); i++) {
2639 		char *mem_type;
2640 
2641 		if (ranges[i].size_low != 0 || ranges[i].size_high != 0) {
2642 			switch (ranges[i].parent_high & PCI_REG_ADDR_M) {
2643 			case PCI_ADDR_IO:
2644 				DEBUG2("Free I/O    base/length = "
2645 				    "[0x%x]/[0x%x]\n", ranges[i].child_low,
2646 				    ranges[i].size_low);
2647 				if (ndi_ra_free(ddi_get_parent(dip),
2648 				    (uint64_t)ranges[i].child_low,
2649 				    (uint64_t)ranges[i].size_low,
2650 				    NDI_RA_TYPE_IO, NDI_RA_PASS)
2651 				    != NDI_SUCCESS) {
2652 					DEBUG0("Trouble freeing "
2653 					    "PCI i/o space\n");
2654 					kmem_free(ranges, length);
2655 					return (PCICFG_FAILURE);
2656 				}
2657 				break;
2658 			case PCI_ADDR_MEM32:
2659 			case PCI_ADDR_MEM64:
2660 				if (ranges[i].parent_high & PCI_REG_PF_M) {
2661 					DEBUG3("Free PF Memory base/length = "
2662 					    "[0x%x.0x%x]/[0x%x]\n",
2663 					    ranges[i].child_mid,
2664 					    ranges[i].child_low,
2665 					    ranges[i].size_low);
2666 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2667 				} else {
2668 					DEBUG3("Free Memory base/length"
2669 					    " = [0x%x.0x%x]/[0x%x]\n",
2670 					    ranges[i].child_mid,
2671 					    ranges[i].child_low,
2672 					    ranges[i].size_low)
2673 					mem_type = NDI_RA_TYPE_MEM;
2674 				}
2675 				if (ndi_ra_free(ddi_get_parent(dip),
2676 				    PCICFG_LADDR(ranges[i].child_low,
2677 				    ranges[i].child_mid),
2678 				    (uint64_t)ranges[i].size_low,
2679 				    mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
2680 					DEBUG0("Trouble freeing "
2681 					    "PCI memory space\n");
2682 					kmem_free(ranges, length);
2683 					return (PCICFG_FAILURE);
2684 				}
2685 				break;
2686 			default:
2687 				DEBUG0("Unknown memory space\n");
2688 				break;
2689 			}
2690 		}
2691 	}
2692 
2693 	if (length)
2694 		kmem_free(ranges, length);
2695 
2696 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2697 	    "bus-range", (caddr_t)&bus, &k) != DDI_PROP_SUCCESS) {
2698 		DEBUG0("Failed to read bus-range property\n");
2699 		return (PCICFG_FAILURE);
2700 	}
2701 
2702 	DEBUG2("Need to free bus [%d] range [%d]\n",
2703 	    bus[0], bus[1] - bus[0] + 1);
2704 
2705 	if (ndi_ra_free(ddi_get_parent(dip), (uint64_t)bus[0],
2706 	    (uint64_t)(bus[1] - bus[0] + 1), NDI_RA_TYPE_PCI_BUSNUM,
2707 	    NDI_RA_PASS) != NDI_SUCCESS) {
2708 		DEBUG0("Failed to free a bus number\n");
2709 		kmem_free(bus, k);
2710 		return (PCICFG_FAILURE);
2711 	}
2712 
2713 	kmem_free(bus, k);
2714 	return (PCICFG_SUCCESS);
2715 }
2716 
2717 static int
2718 pcicfg_free_device_resources(dev_info_t *dip)
2719 {
2720 	pci_regspec_t *assigned;
2721 
2722 	int length;
2723 	int acount;
2724 	int i;
2725 
2726 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2727 	    "assigned-addresses", (caddr_t)&assigned, &length)
2728 	    != DDI_PROP_SUCCESS) {
2729 		DEBUG0("Failed to read assigned-addresses property\n");
2730 		return (PCICFG_FAILURE);
2731 	}
2732 
2733 	/*
2734 	 * For each "assigned-addresses" property entry with a length,
2735 	 * call the memory allocation routines to return the
2736 	 * resource.
2737 	 */
2738 	acount = length / sizeof (pci_regspec_t);
2739 	for (i = 0; i < acount; i++) {
2740 		char *mem_type;
2741 
2742 		/*
2743 		 * Free the resource if the size of it is not zero.
2744 		 */
2745 		if ((assigned[i].pci_size_low != 0)||
2746 		    (assigned[i].pci_size_hi != 0)) {
2747 			switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2748 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2749 				/*
2750 				 * Check the assigned address for zero.
2751 				 * (Workaround for Devconf (x86) bug to
2752 				 * skip bogus entry for ROM base address
2753 				 * register. If the assigned address is
2754 				 * zero then ignore the entry
2755 				 * (see bugid 4281306)).
2756 				 */
2757 				if (assigned[i].pci_phys_low == 0)
2758 					break; /* ignore the entry */
2759 
2760 				if (assigned[i].pci_phys_hi & PCI_REG_PF_M)
2761 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2762 				else
2763 					mem_type = NDI_RA_TYPE_MEM;
2764 
2765 				if (ndi_ra_free(ddi_get_parent(dip),
2766 				    (uint64_t)assigned[i].pci_phys_low,
2767 				    (uint64_t)assigned[i].pci_size_low,
2768 				    mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
2769 					DEBUG0("Trouble freeing "
2770 					    "PCI memory space\n");
2771 					kmem_free(assigned, length);
2772 					return (PCICFG_FAILURE);
2773 				}
2774 
2775 				DEBUG4("Returned 0x%x of 32 bit %s space"
2776 				    " @ 0x%x from register 0x%x\n",
2777 				    assigned[i].pci_size_low, mem_type,
2778 				    assigned[i].pci_phys_low,
2779 				    PCI_REG_REG_G(assigned[i].pci_phys_hi));
2780 
2781 			break;
2782 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2783 				if (assigned[i].pci_phys_hi & PCI_REG_PF_M)
2784 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2785 				else
2786 					mem_type = NDI_RA_TYPE_MEM;
2787 
2788 				if (ndi_ra_free(ddi_get_parent(dip),
2789 				    PCICFG_LADDR(assigned[i].pci_phys_low,
2790 				    assigned[i].pci_phys_mid),
2791 				    (uint64_t)assigned[i].pci_size_low,
2792 				    mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
2793 					DEBUG0("Trouble freeing "
2794 					    "PCI memory space\n");
2795 					kmem_free(assigned, length);
2796 					return (PCICFG_FAILURE);
2797 				}
2798 
2799 				DEBUG5("Returned 0x%x of 64 bit %s space"
2800 				    " @ 0x%x.0x%x from register 0x%x\n",
2801 				    assigned[i].pci_size_low,
2802 				    mem_type, assigned[i].pci_phys_mid,
2803 				    assigned[i].pci_phys_low,
2804 				    PCI_REG_REG_G(assigned[i].pci_phys_hi));
2805 
2806 			break;
2807 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2808 				if (ndi_ra_free(ddi_get_parent(dip),
2809 				    (uint64_t)assigned[i].pci_phys_low,
2810 				    (uint64_t)assigned[i].pci_size_low,
2811 				    NDI_RA_TYPE_IO, NDI_RA_PASS) !=
2812 				    NDI_SUCCESS) {
2813 					DEBUG0("Trouble freeing "
2814 					    "PCI IO space\n");
2815 					kmem_free(assigned, length);
2816 					return (PCICFG_FAILURE);
2817 				}
2818 				DEBUG3("Returned 0x%x of IO space @ 0x%x from "
2819 				    "register 0x%x\n", assigned[i].pci_size_low,
2820 				    assigned[i].pci_phys_low,
2821 				    PCI_REG_REG_G(assigned[i].pci_phys_hi));
2822 			break;
2823 			default:
2824 				DEBUG0("Unknown register type\n");
2825 				kmem_free(assigned, length);
2826 				return (PCICFG_FAILURE);
2827 			} /* switch */
2828 		}
2829 	}
2830 	kmem_free(assigned, length);
2831 	return (PCICFG_SUCCESS);
2832 }
2833 
2834 static int
2835 pcicfg_free_resources(dev_info_t *dip, pcicfg_flags_t flags)
2836 {
2837 	ddi_acc_handle_t handle;
2838 	uint8_t header_type;
2839 
2840 	if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
2841 		DEBUG0("Failed to map config space!\n");
2842 		return (PCICFG_FAILURE);
2843 	}
2844 
2845 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2846 
2847 	(void) pci_config_teardown(&handle);
2848 
2849 	/*
2850 	 * A different algorithm is used for bridges and leaf devices.
2851 	 */
2852 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2853 		/*
2854 		 * We only support readonly probing for leaf devices.
2855 		 */
2856 		if (flags & PCICFG_FLAG_READ_ONLY)
2857 			return (PCICFG_FAILURE);
2858 
2859 		if (pcicfg_free_bridge_resources(dip) != PCICFG_SUCCESS) {
2860 			DEBUG0("Failed freeing up bridge resources\n");
2861 			return (PCICFG_FAILURE);
2862 		}
2863 	} else {
2864 		if (pcicfg_free_device_resources(dip) != PCICFG_SUCCESS) {
2865 			DEBUG0("Failed freeing up device resources\n");
2866 			return (PCICFG_FAILURE);
2867 		}
2868 	}
2869 
2870 	return (PCICFG_SUCCESS);
2871 }
2872 
2873 #ifndef _DONT_USE_1275_GENERIC_NAMES
2874 static char *
2875 pcicfg_get_class_name(uint32_t classcode)
2876 {
2877 	struct pcicfg_name_entry *ptr;
2878 
2879 	for (ptr = &pcicfg_class_lookup[0]; ptr->name != NULL; ptr++) {
2880 		if (ptr->class_code == classcode) {
2881 			return (ptr->name);
2882 		}
2883 	}
2884 	return (NULL);
2885 }
2886 #endif /* _DONT_USE_1275_GENERIC_NAMES */
2887 
2888 static dev_info_t *
2889 pcicfg_devi_find(dev_info_t *dip, uint_t device, uint_t function)
2890 {
2891 	struct pcicfg_find_ctrl ctrl;
2892 	int count;
2893 
2894 	ctrl.device = device;
2895 	ctrl.function = function;
2896 	ctrl.dip = NULL;
2897 
2898 	ndi_devi_enter(dip, &count);
2899 	ddi_walk_devs(ddi_get_child(dip), pcicfg_match_dev, (void *)&ctrl);
2900 	ndi_devi_exit(dip, count);
2901 
2902 	return (ctrl.dip);
2903 }
2904 
2905 static int
2906 pcicfg_match_dev(dev_info_t *dip, void *hdl)
2907 {
2908 	struct pcicfg_find_ctrl *ctrl = (struct pcicfg_find_ctrl *)hdl;
2909 	pci_regspec_t *pci_rp;
2910 	int length;
2911 	int pci_dev;
2912 	int pci_func;
2913 
2914 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2915 	    "reg", (int **)&pci_rp, (uint_t *)&length) != DDI_PROP_SUCCESS) {
2916 		ctrl->dip = NULL;
2917 		return (DDI_WALK_TERMINATE);
2918 	}
2919 
2920 	/* get the PCI device address info */
2921 	pci_dev = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
2922 	pci_func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
2923 
2924 	/*
2925 	 * free the memory allocated by ddi_prop_lookup_int_array
2926 	 */
2927 	ddi_prop_free(pci_rp);
2928 
2929 
2930 	if ((pci_dev == ctrl->device) && (pci_func == ctrl->function)) {
2931 		/* found the match for the specified device address */
2932 		ctrl->dip = dip;
2933 		return (DDI_WALK_TERMINATE);
2934 	}
2935 
2936 	/*
2937 	 * continue the walk to the next sibling to look for a match.
2938 	 */
2939 	return (DDI_WALK_PRUNECHILD);
2940 }
2941 
2942 static int
2943 pcicfg_update_assigned_prop(dev_info_t *dip, pci_regspec_t *newone)
2944 {
2945 	int		alen;
2946 	pci_regspec_t	*assigned;
2947 	caddr_t		newreg;
2948 	uint_t		status;
2949 
2950 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2951 	    "assigned-addresses", (caddr_t)&assigned, &alen);
2952 	switch (status) {
2953 		case DDI_PROP_SUCCESS:
2954 		break;
2955 		case DDI_PROP_NO_MEMORY:
2956 			DEBUG0("no memory for assigned-addresses property\n");
2957 			return (PCICFG_FAILURE);
2958 		default:
2959 			(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2960 			    "assigned-addresses", (int *)newone,
2961 			    sizeof (*newone)/sizeof (int));
2962 			return (PCICFG_SUCCESS);
2963 	}
2964 
2965 	/*
2966 	 * Allocate memory for the existing
2967 	 * assigned-addresses(s) plus one and then
2968 	 * build it.
2969 	 */
2970 
2971 	newreg = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
2972 
2973 	bcopy(assigned, newreg, alen);
2974 	bcopy(newone, newreg + alen, sizeof (*newone));
2975 
2976 	/*
2977 	 * Write out the new "assigned-addresses" spec
2978 	 */
2979 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2980 	    "assigned-addresses", (int *)newreg,
2981 	    (alen + sizeof (*newone))/sizeof (int));
2982 
2983 	kmem_free((caddr_t)newreg, alen+sizeof (*newone));
2984 	kmem_free(assigned, alen);
2985 
2986 	return (PCICFG_SUCCESS);
2987 }
2988 
2989 static int
2990 pcicfg_update_ranges_prop(dev_info_t *dip, ppb_ranges_t *addition)
2991 {
2992 	int		rlen;
2993 	ppb_ranges_t	*ranges;
2994 	caddr_t		newreg;
2995 	uint_t		status;
2996 
2997 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2998 	    "ranges", (caddr_t)&ranges, &rlen);
2999 
3000 
3001 	switch (status) {
3002 		case DDI_PROP_SUCCESS:
3003 			break;
3004 		case DDI_PROP_NO_MEMORY:
3005 			DEBUG0("ranges present, but unable to get memory\n");
3006 			return (PCICFG_FAILURE);
3007 		default:
3008 			DEBUG0("no ranges property - creating one\n");
3009 			if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
3010 			    dip, "ranges", (int *)addition,
3011 			    sizeof (ppb_ranges_t)/sizeof (int))
3012 			    != DDI_SUCCESS) {
3013 				DEBUG0("Did'nt create ranges property\n");
3014 				return (PCICFG_FAILURE);
3015 			}
3016 			return (PCICFG_SUCCESS);
3017 	}
3018 
3019 	/*
3020 	 * Allocate memory for the existing ranges plus one and then
3021 	 * build it.
3022 	 */
3023 	newreg = kmem_zalloc(rlen+sizeof (ppb_ranges_t), KM_SLEEP);
3024 
3025 	bcopy(ranges, newreg, rlen);
3026 	bcopy(addition, newreg + rlen, sizeof (ppb_ranges_t));
3027 
3028 	/*
3029 	 * Write out the new "ranges" property
3030 	 */
3031 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges",
3032 	    (int *)newreg, (rlen + sizeof (ppb_ranges_t))/sizeof (int));
3033 
3034 	DEBUG1("Updating ranges property for %d entries",
3035 	    rlen / sizeof (ppb_ranges_t) + 1);
3036 
3037 	kmem_free((caddr_t)newreg, rlen+sizeof (ppb_ranges_t));
3038 
3039 	kmem_free((caddr_t)ranges, rlen);
3040 
3041 	return (PCICFG_SUCCESS);
3042 }
3043 
3044 static int
3045 pcicfg_update_reg_prop(dev_info_t *dip, uint32_t regvalue, uint_t reg_offset)
3046 {
3047 	int		rlen;
3048 	pci_regspec_t	*reg;
3049 	caddr_t		newreg;
3050 	uint32_t	hiword;
3051 	pci_regspec_t	addition;
3052 	uint32_t	size;
3053 	uint_t		status;
3054 
3055 	status = ddi_getlongprop(DDI_DEV_T_ANY,
3056 	    dip, DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &rlen);
3057 
3058 	switch (status) {
3059 		case DDI_PROP_SUCCESS:
3060 		break;
3061 		case DDI_PROP_NO_MEMORY:
3062 			DEBUG0("reg present, but unable to get memory\n");
3063 			return (PCICFG_FAILURE);
3064 		default:
3065 			DEBUG0("no reg property\n");
3066 			return (PCICFG_FAILURE);
3067 	}
3068 
3069 	/*
3070 	 * Allocate memory for the existing reg(s) plus one and then
3071 	 * build it.
3072 	 */
3073 	newreg = kmem_zalloc(rlen+sizeof (pci_regspec_t), KM_SLEEP);
3074 
3075 	/*
3076 	 * Build the regspec, then add it to the existing one(s)
3077 	 */
3078 
3079 	hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3080 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3081 	    PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3082 
3083 	if (reg_offset == PCI_CONF_ROM) {
3084 		size = (~(PCI_BASE_ROM_ADDR_M & regvalue))+1;
3085 		hiword |= PCI_ADDR_MEM32;
3086 	} else {
3087 		size = (~(PCI_BASE_M_ADDR_M & regvalue))+1;
3088 
3089 		if ((PCI_BASE_SPACE_M & regvalue) == PCI_BASE_SPACE_MEM) {
3090 			if ((PCI_BASE_TYPE_M & regvalue) == PCI_BASE_TYPE_MEM) {
3091 				hiword |= PCI_ADDR_MEM32;
3092 			} else if ((PCI_BASE_TYPE_M & regvalue)
3093 			    == PCI_BASE_TYPE_ALL) {
3094 				hiword |= PCI_ADDR_MEM64;
3095 			}
3096 			if (regvalue & PCI_BASE_PREF_M)
3097 				hiword |= PCI_REG_PF_M;
3098 		} else {
3099 			hiword |= PCI_ADDR_IO;
3100 		}
3101 	}
3102 
3103 	addition.pci_phys_hi = hiword;
3104 	addition.pci_phys_mid = 0;
3105 	addition.pci_phys_low = 0;
3106 	addition.pci_size_hi = 0;
3107 	addition.pci_size_low = size;
3108 
3109 	bcopy(reg, newreg, rlen);
3110 	bcopy(&addition, newreg + rlen, sizeof (pci_regspec_t));
3111 
3112 	DEBUG3("updating BAR@off %x with %x,%x\n", reg_offset, hiword, size);
3113 	/*
3114 	 * Write out the new "reg" property
3115 	 */
3116 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg",
3117 	    (int *)newreg, (rlen + sizeof (pci_regspec_t))/sizeof (int));
3118 
3119 	kmem_free((caddr_t)newreg, rlen+sizeof (pci_regspec_t));
3120 	kmem_free((caddr_t)reg, rlen);
3121 
3122 	return (PCICFG_SUCCESS);
3123 }
3124 
3125 static int
3126 pcicfg_update_assigned_prop_value(dev_info_t *dip, uint32_t size,
3127     uint32_t base, uint32_t base_hi, uint_t reg_offset)
3128 {
3129 	int		rlen;
3130 	pci_regspec_t	*reg;
3131 	uint32_t	hiword;
3132 	pci_regspec_t	addition;
3133 	uint_t		status;
3134 
3135 	status = ddi_getlongprop(DDI_DEV_T_ANY,
3136 	    dip, DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &rlen);
3137 
3138 	switch (status) {
3139 		case DDI_PROP_SUCCESS:
3140 		break;
3141 		case DDI_PROP_NO_MEMORY:
3142 			DEBUG0("reg present, but unable to get memory\n");
3143 			return (PCICFG_FAILURE);
3144 		default:
3145 			/*
3146 			 * Since the config space "reg" entry should have been
3147 			 * created, we expect a "reg" property already
3148 			 * present here.
3149 			 */
3150 			DEBUG0("no reg property\n");
3151 			return (PCICFG_FAILURE);
3152 	}
3153 
3154 	/*
3155 	 * Build the regspec, then add it to the existing one(s)
3156 	 */
3157 
3158 	hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3159 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3160 	    PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3161 
3162 	hiword |= PCI_REG_REL_M;
3163 
3164 	if (reg_offset == PCI_CONF_ROM) {
3165 		hiword |= PCI_ADDR_MEM32;
3166 
3167 		base = PCI_BASE_ROM_ADDR_M & base;
3168 	} else {
3169 		if ((PCI_BASE_SPACE_M & base) == PCI_BASE_SPACE_MEM) {
3170 			if ((PCI_BASE_TYPE_M & base) == PCI_BASE_TYPE_MEM) {
3171 				hiword |= PCI_ADDR_MEM32;
3172 			} else if ((PCI_BASE_TYPE_M & base)
3173 			    == PCI_BASE_TYPE_ALL) {
3174 				hiword |= PCI_ADDR_MEM64;
3175 			}
3176 			if (base & PCI_BASE_PREF_M)
3177 				hiword |= PCI_REG_PF_M;
3178 
3179 			base = PCI_BASE_M_ADDR_M & base;
3180 		} else {
3181 			hiword |= PCI_ADDR_IO;
3182 
3183 			base = PCI_BASE_IO_ADDR_M & base;
3184 			base_hi = 0;
3185 		}
3186 	}
3187 
3188 	addition.pci_phys_hi = hiword;
3189 	addition.pci_phys_mid = base_hi;
3190 	addition.pci_phys_low = base;
3191 	addition.pci_size_hi = 0;
3192 	addition.pci_size_low = size;
3193 
3194 	DEBUG3("updating BAR@off %x with %x,%x\n", reg_offset, hiword, size);
3195 
3196 	kmem_free((caddr_t)reg, rlen);
3197 
3198 	return (pcicfg_update_assigned_prop(dip, &addition));
3199 }
3200 
3201 static void
3202 pcicfg_device_on(ddi_acc_handle_t config_handle)
3203 {
3204 	/*
3205 	 * Enable memory, IO, and bus mastership
3206 	 * XXX should we enable parity, SERR#,
3207 	 * fast back-to-back, and addr. stepping?
3208 	 */
3209 	pci_config_put16(config_handle, PCI_CONF_COMM,
3210 	    pci_config_get16(config_handle, PCI_CONF_COMM) | 0x7);
3211 }
3212 
3213 static void
3214 pcicfg_device_off(ddi_acc_handle_t config_handle)
3215 {
3216 	/*
3217 	 * Disable I/O and memory traffic through the bridge
3218 	 */
3219 	pci_config_put16(config_handle, PCI_CONF_COMM, 0x0);
3220 }
3221 
3222 /*
3223  * Setup the basic 1275 properties based on information found in the config
3224  * header of the PCI device
3225  */
3226 static int
3227 pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3228     uint8_t pcie_dev)
3229 {
3230 	int ret;
3231 	uint16_t cap_id_loc, val;
3232 	uint32_t wordval;
3233 	uint8_t byteval;
3234 
3235 	/* These two exists only for non-bridges */
3236 	if (((pci_config_get8(config_handle, PCI_CONF_HEADER) &
3237 	    PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) && !pcie_dev) {
3238 		byteval = pci_config_get8(config_handle, PCI_CONF_MIN_G);
3239 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3240 		    "min-grant", byteval)) != DDI_SUCCESS) {
3241 			return (ret);
3242 		}
3243 
3244 		byteval = pci_config_get8(config_handle, PCI_CONF_MAX_L);
3245 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3246 		    "max-latency", byteval)) != DDI_SUCCESS) {
3247 			return (ret);
3248 		}
3249 	}
3250 
3251 	/*
3252 	 * These should always exist and have the value of the
3253 	 * corresponding register value
3254 	 */
3255 	val = pci_config_get16(config_handle, PCI_CONF_VENID);
3256 
3257 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id", val))
3258 	    != DDI_SUCCESS) {
3259 		return (ret);
3260 	}
3261 	val = pci_config_get16(config_handle, PCI_CONF_DEVID);
3262 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id", val))
3263 	    != DDI_SUCCESS) {
3264 		return (ret);
3265 	}
3266 	byteval = pci_config_get8(config_handle, PCI_CONF_REVID);
3267 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3268 	    "revision-id", byteval)) != DDI_SUCCESS) {
3269 		return (ret);
3270 	}
3271 
3272 	wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3273 	    (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3274 
3275 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3276 	    "class-code", wordval)) != DDI_SUCCESS) {
3277 		return (ret);
3278 	}
3279 	val = (pci_config_get16(config_handle, PCI_CONF_STAT) &
3280 	    PCI_STAT_DEVSELT);
3281 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3282 	    "devsel-speed", val)) != DDI_SUCCESS) {
3283 		return (ret);
3284 	}
3285 
3286 	/*
3287 	 * The next three are bits set in the status register.  The property is
3288 	 * present (but with no value other than its own existence) if the bit
3289 	 * is set, non-existent otherwise
3290 	 */
3291 	if ((!pcie_dev) &&
3292 	    (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_FBBC)) {
3293 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3294 		    "fast-back-to-back", 0)) != DDI_SUCCESS) {
3295 			return (ret);
3296 		}
3297 	}
3298 	if ((!pcie_dev) &&
3299 	    (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_66MHZ)) {
3300 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3301 		    "66mhz-capable", 0)) != DDI_SUCCESS) {
3302 			return (ret);
3303 		}
3304 	}
3305 	if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_UDF) {
3306 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3307 		    "udf-supported", 0)) != DDI_SUCCESS) {
3308 			return (ret);
3309 		}
3310 	}
3311 
3312 	/*
3313 	 * These next three are optional and are not present
3314 	 * if the corresponding register is zero.  If the value
3315 	 * is non-zero then the property exists with the value
3316 	 * of the register.
3317 	 */
3318 	if ((val = pci_config_get16(config_handle, PCI_CONF_SUBVENID)) != 0) {
3319 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3320 		    "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3321 			return (ret);
3322 		}
3323 	}
3324 	if ((val = pci_config_get16(config_handle, PCI_CONF_SUBSYSID)) != 0) {
3325 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3326 		    "subsystem-id", val)) != DDI_SUCCESS) {
3327 			return (ret);
3328 		}
3329 	}
3330 	if ((val = pci_config_get16(config_handle, PCI_CONF_CACHE_LINESZ))
3331 	    != 0) {
3332 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3333 		    "cache-line-size", val)) != DDI_SUCCESS) {
3334 			return (ret);
3335 		}
3336 	}
3337 
3338 	/*
3339 	 * If the Interrupt Pin register is non-zero then the
3340 	 * interrupts property exists
3341 	 */
3342 	if ((byteval = pci_config_get8(config_handle, PCI_CONF_IPIN)) != 0) {
3343 		/*
3344 		 * If interrupt pin is non-zero,
3345 		 * record the interrupt line used
3346 		 */
3347 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3348 		    "interrupts", byteval)) != DDI_SUCCESS) {
3349 			return (ret);
3350 		}
3351 	}
3352 	(void) PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
3353 	if (pcie_dev && cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
3354 		val = pci_config_get16(config_handle, cap_id_loc + PCIE_PCIECAP)
3355 		    & PCIE_PCIECAP_SLOT_IMPL;
3356 		/* if slot implemented, get physical slot number */
3357 		if (val) {
3358 			wordval = pci_config_get32(config_handle, cap_id_loc +
3359 			    PCIE_SLOTCAP);
3360 			/* create the property only if slotnum set correctly? */
3361 			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3362 			    "physical-slot#", PCIE_SLOTCAP_PHY_SLOT_NUM(
3363 			    wordval))) != DDI_SUCCESS) {
3364 				return (ret);
3365 			}
3366 		}
3367 	}
3368 
3369 	return (PCICFG_SUCCESS);
3370 }
3371 
3372 static int
3373 pcicfg_set_busnode_props(dev_info_t *dip, uint8_t pcie_device_type)
3374 {
3375 	int ret;
3376 	char device_type[8];
3377 
3378 	if (pcie_device_type)
3379 		(void) strcpy(device_type, "pciex");
3380 	else
3381 		(void) strcpy(device_type, "pci");
3382 
3383 	if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
3384 	    "device_type", device_type)) != DDI_SUCCESS) {
3385 		return (ret);
3386 	}
3387 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3388 	    "#address-cells", 3)) != DDI_SUCCESS) {
3389 		return (ret);
3390 	}
3391 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "#size-cells", 2))
3392 	    != DDI_SUCCESS) {
3393 		return (ret);
3394 	}
3395 	return (PCICFG_SUCCESS);
3396 }
3397 
3398 static int
3399 pcicfg_set_childnode_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3400     uint8_t pcie_dev)
3401 {
3402 
3403 	int		ret;
3404 	char		*name;
3405 	char		buffer[64], pprefix[8], nprefix[8];
3406 	uint16_t	classcode;
3407 	uint8_t		revid, pif, pclass, psubclass;
3408 	char		*compat[24];
3409 	int		i;
3410 	int		n;
3411 	uint16_t		sub_vid, sub_sid, vid, did;
3412 	/* set the property prefix based on the device type */
3413 	if (pcie_dev) {
3414 		(void) sprintf(pprefix, "pciex");
3415 	} else
3416 		(void) sprintf(pprefix, "pci");
3417 
3418 	/* set the prefix right for name property */
3419 	/* x86 platforms need to go with pci for upgrade purposes */
3420 	(void) sprintf(nprefix, "pci");
3421 
3422 	/*
3423 	 * NOTE: These are for both a child and PCI-PCI bridge node
3424 	 */
3425 	sub_vid = pci_config_get16(config_handle, PCI_CONF_SUBVENID);
3426 	sub_sid = pci_config_get16(config_handle, PCI_CONF_SUBSYSID);
3427 	vid = pci_config_get16(config_handle, PCI_CONF_VENID);
3428 	did = pci_config_get16(config_handle, PCI_CONF_DEVID);
3429 	revid = pci_config_get8(config_handle, PCI_CONF_REVID);
3430 	pif = pci_config_get8(config_handle, PCI_CONF_PROGCLASS);
3431 	classcode = pci_config_get16(config_handle, PCI_CONF_SUBCLASS);
3432 	pclass = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
3433 	psubclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
3434 
3435 	if (!sub_vid)
3436 		(void) sprintf(buffer, "%s%x,%x", nprefix, vid, did);
3437 	else
3438 		(void) sprintf(buffer, "%s%x,%x", nprefix, sub_vid, sub_sid);
3439 
3440 	/*
3441 	 * In some environments, trying to use "generic" 1275 names is
3442 	 * not the convention.  In those cases use the name as created
3443 	 * above.  In all the rest of the cases, check to see if there
3444 	 * is a generic name first.
3445 	 */
3446 #ifdef _DONT_USE_1275_GENERIC_NAMES
3447 	name = buffer;
3448 #else
3449 	if ((name = pcicfg_get_class_name(classcode)) == NULL) {
3450 		/*
3451 		 * Set name to the above fabricated name
3452 		 */
3453 		name = buffer;
3454 	}
3455 #endif
3456 
3457 	/*
3458 	 * The node name field needs to be filled in with the name
3459 	 */
3460 	if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3461 		DEBUG0("Failed to set nodename for node\n");
3462 		return (PCICFG_FAILURE);
3463 	}
3464 
3465 	/*
3466 	 * Create the compatible property as an array of pointers
3467 	 * to strings.  Start with the buffer created above.
3468 	 */
3469 	n = 0;
3470 
3471 	/*
3472 	 * Setup 'compatible' as per the PCI2.1 bindings document.
3473 	 *	pci[ex]VVVV,DDDD.SSSS.ssss.RR
3474 	 *	pci[ex]VVVV,DDDD.SSSS.ssss
3475 	 *	pciSSSS.ssss  -> not created for PCIe as per PCIe bindings
3476 	 *	pci[ex]VVVV,DDDD.RR
3477 	 *	pci[ex]VVVV,DDDD
3478 	 *	pci[ex]class,CCSSPP
3479 	 *	pci[ex]class,CCSS
3480 	 * Add legacy entries for compatibility with legacy devices and OS
3481 	 * for x86.
3482 	 *	pciVVVV,DDDD.SSSS.ssss.RR
3483 	 *	pciVVVV,DDDD.SSSS.ssss
3484 	 *	pciSSSS.ssss
3485 	 *	pciVVVV,DDDD.RR
3486 	 *	pciVVVV,DDDD
3487 	 *	pciclass,CCSSPP
3488 	 *	pciclass,CCSS
3489 	 */
3490 
3491 	do {
3492 		if (sub_vid) {
3493 			/* pci[ex]VVVV,DDDD.SSSS.ssss.RR */
3494 			(void) sprintf(buffer, "%s%x,%x.%x.%x.%x", pprefix, vid,
3495 			    did, sub_vid, sub_sid, revid);
3496 			compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3497 			(void) strcpy(compat[n++], buffer);
3498 
3499 			/* pci[ex]VVVV,DDDD.SSSS.ssss */
3500 			(void) sprintf(buffer, "%s%x,%x.%x.%x", pprefix,  vid,
3501 			    did, sub_vid, sub_sid);
3502 			compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3503 			(void) strcpy(compat[n++], buffer);
3504 
3505 			/* pciSSSS.ssss  -> not created for PCIe as per PCIe */
3506 			/* binding to IEEE 1275 spec.			 */
3507 			if (!pcie_dev && pcicfg_do_legacy_props) {
3508 				(void) sprintf(buffer, "pci%x,%x", sub_vid,
3509 				    sub_sid);
3510 				compat[n] = kmem_alloc(strlen(buffer) + 1,
3511 				    KM_SLEEP);
3512 				(void) strcpy(compat[n++], buffer);
3513 			}
3514 		}
3515 
3516 		/* pci[ex]VVVV,DDDD.RR */
3517 		(void) sprintf(buffer, "%s%x,%x.%x", pprefix,  vid, did, revid);
3518 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3519 		(void) strcpy(compat[n++], buffer);
3520 
3521 		/* pci[ex]VVVV,DDDD */
3522 		(void) sprintf(buffer, "%s%x,%x", pprefix, vid, did);
3523 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3524 		(void) strcpy(compat[n++], buffer);
3525 
3526 		/* pci[ex]class,CCSSPP */
3527 		(void) sprintf(buffer, "%sclass,%02x%02x%02x", pprefix, pclass,
3528 		    psubclass, pif);
3529 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3530 		(void) strcpy(compat[n++], buffer);
3531 
3532 		/* pci[ex]class,CCSS */
3533 		(void) sprintf(buffer, "%sclass,%04x", pprefix, classcode);
3534 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3535 		(void) strcpy(compat[n++], buffer);
3536 
3537 		if (!pcie_dev)
3538 			break;
3539 
3540 		/* also add compatible names using "pci" prefix */
3541 		(void) sprintf(pprefix, "pci");
3542 		pcie_dev = 0;
3543 
3544 	} while (pcicfg_do_legacy_props);
3545 
3546 	ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible",
3547 	    (char **)compat, n);
3548 
3549 	for (i = 0; i < n; i++) {
3550 		kmem_free(compat[i], strlen(compat[i]) + 1);
3551 	}
3552 
3553 	return (ret);
3554 }
3555 
3556 /*
3557  * Program the bus numbers into the bridge
3558  */
3559 static void
3560 pcicfg_set_bus_numbers(ddi_acc_handle_t config_handle, uint_t primary,
3561     uint_t secondary, uint_t subordinate)
3562 {
3563 	DEBUG3("Setting bridge bus-range %d,%d,%d\n", primary, secondary,
3564 	    subordinate);
3565 	/*
3566 	 * Primary bus#
3567 	 */
3568 	pci_config_put8(config_handle, PCI_BCNF_PRIBUS, primary);
3569 
3570 	/*
3571 	 * Secondary bus#
3572 	 */
3573 	pci_config_put8(config_handle, PCI_BCNF_SECBUS, secondary);
3574 
3575 	/*
3576 	 * Set the subordinate bus number to ff in order to pass through any
3577 	 * type 1 cycle with a bus number higher than the secondary bus#
3578 	 */
3579 	pci_config_put8(config_handle, PCI_BCNF_SUBBUS, subordinate);
3580 }
3581 
3582 /*
3583  * Put bridge registers into initial state
3584  */
3585 static void
3586 pcicfg_setup_bridge(pcicfg_phdl_t *entry, ddi_acc_handle_t handle)
3587 {
3588 	/*
3589 	 * The highest bus seen during probing is the max-subordinate bus
3590 	 */
3591 	pci_config_put8(handle, PCI_BCNF_SUBBUS, entry->highest_bus);
3592 
3593 	/*
3594 	 * Reset the secondary bus
3595 	 */
3596 	pci_config_put16(handle, PCI_BCNF_BCNTRL,
3597 	    pci_config_get16(handle, PCI_BCNF_BCNTRL) | 0x40);
3598 	drv_usecwait(1000);
3599 	pci_config_put16(handle, PCI_BCNF_BCNTRL,
3600 	    pci_config_get16(handle, PCI_BCNF_BCNTRL) & ~0x40);
3601 	drv_usecwait(1000);
3602 
3603 	/*
3604 	 * Program the memory base register with the
3605 	 * start of the memory range
3606 	 */
3607 	pci_config_put16(handle, PCI_BCNF_MEM_BASE,
3608 	    PCICFG_HIWORD(PCICFG_LOADDR(entry->memory_last)));
3609 
3610 	/*
3611 	 * Program the I/O base register with the start of the I/O range
3612 	 */
3613 	pci_config_put8(handle, PCI_BCNF_IO_BASE_LOW,
3614 	    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(entry->io_last))));
3615 	pci_config_put16(handle, PCI_BCNF_IO_BASE_HI,
3616 	    PCICFG_HIWORD(PCICFG_LOADDR(entry->io_last)));
3617 
3618 	/*
3619 	 * Program the PF memory base register with the start of
3620 	 * PF memory range
3621 	 */
3622 	pci_config_put16(handle, PCI_BCNF_PF_BASE_LOW,
3623 	    PCICFG_HIWORD(PCICFG_LOADDR(entry->pf_memory_last)));
3624 	pci_config_put32(handle, PCI_BCNF_PF_BASE_HIGH,
3625 	    PCICFG_HIADDR(entry->pf_memory_last));
3626 
3627 	/*
3628 	 * Clear status bits
3629 	 */
3630 	pci_config_put16(handle, PCI_BCNF_SEC_STATUS, 0xffff);
3631 
3632 	/*
3633 	 * Needs to be set to this value
3634 	 */
3635 	pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
3636 
3637 	/*
3638 	 * XXX - may be delay should be used since noone configures
3639 	 * devices in the interrupt context
3640 	 */
3641 	drv_usecwait(pcicfg_sec_reset_delay);	/* 1 sec wait */
3642 }
3643 
3644 static void
3645 pcicfg_update_bridge(pcicfg_phdl_t *entry, ddi_acc_handle_t handle)
3646 {
3647 	uint_t length;
3648 
3649 	/*
3650 	 * Program the memory limit register with the end of the memory range
3651 	 */
3652 
3653 	DEBUG1("DOWN ROUNDED ===>[0x%x]\n",
3654 	    PCICFG_ROUND_DOWN(entry->memory_last, PCICFG_MEMGRAN));
3655 
3656 	pci_config_put16(handle, PCI_BCNF_MEM_LIMIT,
3657 	    PCICFG_HIWORD(PCICFG_LOADDR(
3658 	    PCICFG_ROUND_DOWN(entry->memory_last, PCICFG_MEMGRAN))));
3659 	/*
3660 	 * Since this is a bridge, the rest of this range will
3661 	 * be responded to by the bridge.  We have to round up
3662 	 * so no other device claims it.
3663 	 */
3664 	if ((length = (PCICFG_ROUND_UP(entry->memory_last, PCICFG_MEMGRAN)
3665 	    - entry->memory_last)) > 0) {
3666 		(void) pcicfg_get_mem(entry, length, NULL);
3667 		DEBUG1("Added [0x%x]at the top of the bridge (mem)\n", length);
3668 	}
3669 
3670 	/*
3671 	 * Program the PF memory limit register with the end of the memory range
3672 	 */
3673 
3674 	DEBUG1("DOWN ROUNDED ===>[0x%x]\n",
3675 	    PCICFG_ROUND_DOWN(entry->pf_memory_last, PCICFG_MEMGRAN));
3676 
3677 	pci_config_put16(handle, PCI_BCNF_PF_LIMIT_LOW,
3678 	    PCICFG_HIWORD(PCICFG_LOADDR(PCICFG_ROUND_DOWN(
3679 	    entry->pf_memory_last, PCICFG_MEMGRAN))));
3680 	pci_config_put32(handle, PCI_BCNF_PF_LIMIT_HIGH, PCICFG_HIADDR(
3681 	    PCICFG_ROUND_DOWN(entry->pf_memory_last, PCICFG_MEMGRAN)));
3682 	if ((length = (PCICFG_ROUND_UP(entry->pf_memory_last, PCICFG_MEMGRAN)
3683 	    - entry->pf_memory_last)) > 0) {
3684 		(void) pcicfg_get_pf_mem(entry, length, NULL);
3685 		DEBUG1("Added [0x%x]at the top of the bridge (PF mem)\n",
3686 		    length);
3687 	}
3688 
3689 	/*
3690 	 * Program the I/O limit register with the end of the I/O range
3691 	 */
3692 	pci_config_put8(handle, PCI_BCNF_IO_LIMIT_LOW,
3693 	    PCICFG_HIBYTE(PCICFG_LOWORD(
3694 	    PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last, PCICFG_IOGRAN)))));
3695 
3696 	pci_config_put16(handle, PCI_BCNF_IO_LIMIT_HI, PCICFG_HIWORD(
3697 	    PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last, PCICFG_IOGRAN))));
3698 
3699 	/*
3700 	 * Same as above for I/O space. Since this is a
3701 	 * bridge, the rest of this range will be responded
3702 	 * to by the bridge.  We have to round up so no
3703 	 * other device claims it.
3704 	 */
3705 	if ((length = (PCICFG_ROUND_UP(entry->io_last, PCICFG_IOGRAN)
3706 	    - entry->io_last)) > 0) {
3707 		(void) pcicfg_get_io(entry, length, NULL);
3708 		DEBUG1("Added [0x%x]at the top of the bridge (I/O)\n", length);
3709 	}
3710 }
3711 
3712 static int
3713 pcicfg_probe_children(dev_info_t *parent, uint_t bus, uint_t device,
3714     uint_t func, uint_t *highest_bus, pcicfg_flags_t flags, boolean_t is_pcie)
3715 {
3716 	dev_info_t		*new_child;
3717 	ddi_acc_handle_t	config_handle;
3718 	uint8_t			header_type, pcie_dev = 0;
3719 	int			ret = PCICFG_FAILURE;
3720 
3721 	/*
3722 	 * This node will be put immediately below
3723 	 * "parent". Allocate a blank device node.  It will either
3724 	 * be filled in or freed up based on further probing.
3725 	 */
3726 
3727 	ndi_devi_alloc_sleep(parent, DEVI_PSEUDO_NEXNAME,
3728 	    (pnode_t)DEVI_SID_NODEID, &new_child);
3729 
3730 	if (pcicfg_add_config_reg(new_child, bus, device, func)
3731 	    != DDI_SUCCESS) {
3732 		DEBUG0("pcicfg_probe_children():Failed to add candidate REG\n");
3733 		goto failedconfig;
3734 	}
3735 
3736 	if ((ret = pcicfg_config_setup(new_child, &config_handle))
3737 	    != PCICFG_SUCCESS) {
3738 		if (ret == PCICFG_NODEVICE) {
3739 			(void) ndi_devi_free(new_child);
3740 			return (ret);
3741 		}
3742 		DEBUG0("pcicfg_probe_children():"
3743 		"Failed to setup config space\n");
3744 		goto failedconfig;
3745 	}
3746 
3747 	if (is_pcie)
3748 		(void) pcie_init_bus(new_child, PCI_GETBDF(bus, device, func),
3749 		    PCIE_BUS_INITIAL);
3750 
3751 	/*
3752 	 * As soon as we have access to config space,
3753 	 * turn off device. It will get turned on
3754 	 * later (after memory is assigned).
3755 	 */
3756 	(void) pcicfg_device_off(config_handle);
3757 
3758 	/* check if we are PCIe device */
3759 	if (pcicfg_pcie_dev(new_child, config_handle) == DDI_SUCCESS) {
3760 		DEBUG0("PCIe device detected\n");
3761 		pcie_dev = 1;
3762 	}
3763 
3764 	/*
3765 	 * Set 1275 properties common to all devices
3766 	 */
3767 	if (pcicfg_set_standard_props(new_child, config_handle, pcie_dev)
3768 	    != PCICFG_SUCCESS) {
3769 		DEBUG0("Failed to set standard properties\n");
3770 		goto failedchild;
3771 	}
3772 
3773 	/*
3774 	 * Child node properties  NOTE: Both for PCI-PCI bridge and child node
3775 	 */
3776 	if (pcicfg_set_childnode_props(new_child, config_handle, pcie_dev)
3777 	    != PCICFG_SUCCESS) {
3778 		goto failedchild;
3779 	}
3780 
3781 	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
3782 
3783 	/*
3784 	 * If this is not a multi-function card only probe function zero.
3785 	 */
3786 	if ((!(header_type & PCI_HEADER_MULTI)) && (func != 0)) {
3787 
3788 		ret = PCICFG_NODEVICE;
3789 		goto failedchild;
3790 	}
3791 
3792 	/*
3793 	 * Attach the child to its parent
3794 	 */
3795 	(void) i_ndi_config_node(new_child, DS_LINKED, 0);
3796 
3797 	DEVI_SET_PCI(new_child);
3798 
3799 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
3800 
3801 		DEBUG3("--Bridge found bus [0x%x] device[0x%x] func [0x%x]\n",
3802 		    bus, device, func);
3803 
3804 		/* Only support read-only probe for leaf device */
3805 		if (flags & PCICFG_FLAG_READ_ONLY)
3806 			goto failedchild;
3807 
3808 		ret = pcicfg_probe_bridge(new_child, config_handle, bus,
3809 		    highest_bus, is_pcie);
3810 		if (ret != PCICFG_SUCCESS) {
3811 			(void) pcicfg_free_bridge_resources(new_child);
3812 			goto failedchild;
3813 		}
3814 
3815 	} else {
3816 
3817 		DEBUG3("--Leaf device found bus [0x%x] device"
3818 		    "[0x%x] func [0x%x]\n", bus, device, func);
3819 
3820 		if (flags & PCICFG_FLAG_READ_ONLY) {
3821 			/*
3822 			 * with read-only probe, don't do any resource
3823 			 * allocation, just read the BARs and update props.
3824 			 */
3825 			ret = pcicfg_populate_props_from_bar(new_child,
3826 			    config_handle);
3827 			if (ret != PCICFG_SUCCESS)
3828 				goto failedchild;
3829 
3830 			/*
3831 			 * now allocate the resources, just remove the
3832 			 * resources from the parent busra pool.
3833 			 */
3834 			ret = pcicfg_device_assign_readonly(new_child);
3835 			if (ret != PCICFG_SUCCESS) {
3836 				(void) pcicfg_free_device_resources(new_child);
3837 				goto failedchild;
3838 			}
3839 
3840 		} else {
3841 			/*
3842 			 * update "reg" property by sizing the BARs.
3843 			 */
3844 			ret = pcicfg_populate_reg_props(new_child,
3845 			    config_handle);
3846 			if (ret != PCICFG_SUCCESS)
3847 				goto failedchild;
3848 
3849 			/* now allocate & program the resources */
3850 			ret = pcicfg_device_assign(new_child);
3851 			if (ret != PCICFG_SUCCESS) {
3852 				(void) pcicfg_free_device_resources(new_child);
3853 				goto failedchild;
3854 			}
3855 		}
3856 
3857 		(void) ndi_devi_bind_driver(new_child, 0);
3858 	}
3859 
3860 	(void) pcicfg_config_teardown(&config_handle);
3861 
3862 	/*
3863 	 * Properties have been setted up, so initialize the remaining
3864 	 * bus_t fields
3865 	 */
3866 	if (is_pcie)
3867 		(void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
3868 
3869 	return (PCICFG_SUCCESS);
3870 
3871 failedchild:
3872 	/*
3873 	 * XXX check if it should be taken offline (if online)
3874 	 */
3875 	(void) pcicfg_config_teardown(&config_handle);
3876 
3877 	if (is_pcie)
3878 		pcie_fini_bus(new_child, PCIE_BUS_FINAL);
3879 
3880 failedconfig:
3881 
3882 	(void) ndi_devi_free(new_child);
3883 	return (ret);
3884 }
3885 
3886 /*
3887  * Sizing the BARs and update "reg" property
3888  */
3889 static int
3890 pcicfg_populate_reg_props(dev_info_t *new_child, ddi_acc_handle_t config_handle)
3891 {
3892 	int		i;
3893 	uint32_t	request;
3894 
3895 	i = PCI_CONF_BASE0;
3896 
3897 	while (i <= PCI_CONF_BASE5) {
3898 
3899 		pci_config_put32(config_handle, i, 0xffffffff);
3900 
3901 		request = pci_config_get32(config_handle, i);
3902 		/*
3903 		 * If its a zero length, don't do
3904 		 * any programming.
3905 		 */
3906 		if (request != 0) {
3907 			/*
3908 			 * Add to the "reg" property
3909 			 */
3910 			if (pcicfg_update_reg_prop(new_child,
3911 			    request, i) != PCICFG_SUCCESS) {
3912 				goto failedchild;
3913 			}
3914 		} else {
3915 			DEBUG1("BASE register [0x%x] asks for "
3916 			    "[0x0]=[0x0](32)\n", i);
3917 			i += 4;
3918 			continue;
3919 		}
3920 
3921 		/*
3922 		 * Increment by eight if it is 64 bit address space
3923 		 */
3924 		if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
3925 			DEBUG3("BASE register [0x%x] asks for "
3926 			    "[0x%x]=[0x%x] (64)\n",
3927 			    i, request, (~(PCI_BASE_M_ADDR_M & request))+1);
3928 			i += 8;
3929 		} else {
3930 			DEBUG3("BASE register [0x%x] asks for "
3931 			    "[0x%x]=[0x%x](32)\n",
3932 			    i, request, (~(PCI_BASE_M_ADDR_M & request))+1);
3933 			i += 4;
3934 		}
3935 	}
3936 
3937 	/*
3938 	 * Get the ROM size and create register for it
3939 	 */
3940 	pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
3941 
3942 	request = pci_config_get32(config_handle, PCI_CONF_ROM);
3943 	/*
3944 	 * If its a zero length, don't do
3945 	 * any programming.
3946 	 */
3947 
3948 	if (request != 0) {
3949 		DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
3950 		    PCI_CONF_ROM, request,
3951 		    (~(PCI_BASE_ROM_ADDR_M & request)) + 1);
3952 		/*
3953 		 * Add to the "reg" property
3954 		 */
3955 		if (pcicfg_update_reg_prop(new_child, request, PCI_CONF_ROM)
3956 		    != PCICFG_SUCCESS) {
3957 			goto failedchild;
3958 		}
3959 	}
3960 
3961 	return (PCICFG_SUCCESS);
3962 
3963 failedchild:
3964 	return (PCICFG_FAILURE);
3965 }
3966 
3967 /*
3968  * Read the BARs and update properties. Used in virtual hotplug.
3969  */
3970 static int
3971 pcicfg_populate_props_from_bar(dev_info_t *new_child,
3972     ddi_acc_handle_t config_handle)
3973 {
3974 	uint32_t request, base, base_hi, size;
3975 	int i;
3976 
3977 	i = PCI_CONF_BASE0;
3978 
3979 	while (i <= PCI_CONF_BASE5) {
3980 		/*
3981 		 * determine the size of the address space
3982 		 */
3983 		base = pci_config_get32(config_handle, i);
3984 		pci_config_put32(config_handle, i, 0xffffffff);
3985 		request = pci_config_get32(config_handle, i);
3986 		pci_config_put32(config_handle, i, base);
3987 
3988 		/*
3989 		 * If its a zero length, don't do any programming.
3990 		 */
3991 		if (request != 0) {
3992 			/*
3993 			 * Add to the "reg" property
3994 			 */
3995 			if (pcicfg_update_reg_prop(new_child,
3996 			    request, i) != PCICFG_SUCCESS) {
3997 				goto failedchild;
3998 			}
3999 
4000 			if ((PCI_BASE_SPACE_IO & request) == 0 &&
4001 			    (PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4002 				base_hi = pci_config_get32(config_handle, i+4);
4003 			} else {
4004 				base_hi = 0;
4005 			}
4006 			/*
4007 			 * Add to "assigned-addresses" property
4008 			 */
4009 			size = (~(PCI_BASE_M_ADDR_M & request))+1;
4010 			if (pcicfg_update_assigned_prop_value(new_child,
4011 			    size, base, base_hi, i) != PCICFG_SUCCESS) {
4012 				goto failedchild;
4013 			}
4014 		} else {
4015 			DEBUG1("BASE register [0x%x] asks for [0x0]=[0x0]"
4016 			    "(32)\n", i);
4017 			i += 4;
4018 			continue;
4019 		}
4020 
4021 		/*
4022 		 * Increment by eight if it is 64 bit address space
4023 		 */
4024 		if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4025 			DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]"
4026 			    "(64)\n", i, request,
4027 			    (~(PCI_BASE_M_ADDR_M & request)) + 1);
4028 			i += 8;
4029 		} else {
4030 			DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]"
4031 			    "(32)\n", i, request,
4032 			    (~(PCI_BASE_M_ADDR_M & request)) + 1);
4033 			i += 4;
4034 		}
4035 	}
4036 
4037 	/*
4038 	 * Get the ROM size and create register for it
4039 	 */
4040 	base = pci_config_get32(config_handle, PCI_CONF_ROM);
4041 	pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
4042 	request = pci_config_get32(config_handle, PCI_CONF_ROM);
4043 	pci_config_put32(config_handle, PCI_CONF_ROM, base);
4044 
4045 	/*
4046 	 * If its a zero length, don't do
4047 	 * any programming.
4048 	 */
4049 	if (request != 0) {
4050 		DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
4051 		    PCI_CONF_ROM, request,
4052 		    (~(PCI_BASE_ROM_ADDR_M & request)) + 1);
4053 		/*
4054 		 * Add to the "reg" property
4055 		 */
4056 		if (pcicfg_update_reg_prop(new_child, request, PCI_CONF_ROM)
4057 		    != PCICFG_SUCCESS) {
4058 			goto failedchild;
4059 		}
4060 		/*
4061 		 * Add to "assigned-addresses" property
4062 		 */
4063 		size = (~(PCI_BASE_ROM_ADDR_M & request))+1;
4064 		if (pcicfg_update_assigned_prop_value(new_child, size,
4065 		    base, 0, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4066 			goto failedchild;
4067 		}
4068 	}
4069 
4070 	return (PCICFG_SUCCESS);
4071 
4072 failedchild:
4073 	return (PCICFG_FAILURE);
4074 }
4075 
4076 static int
4077 pcicfg_probe_bridge(dev_info_t *new_child, ddi_acc_handle_t h, uint_t bus,
4078     uint_t *highest_bus, boolean_t is_pcie)
4079 {
4080 	uint64_t next_bus;
4081 	uint_t new_bus, num_slots;
4082 	ndi_ra_request_t req;
4083 	int rval, i, j;
4084 	uint64_t mem_answer, io_answer, mem_base, io_base, mem_alen, io_alen;
4085 	uint64_t pf_mem_answer, pf_mem_base, pf_mem_alen;
4086 	uint64_t mem_size, io_size, pf_mem_size;
4087 	uint64_t mem_end, pf_mem_end, io_end;
4088 	uint64_t round_answer, round_len;
4089 	ppb_ranges_t range[PCICFG_RANGE_LEN];
4090 	int bus_range[2];
4091 	pcicfg_phdl_t phdl;
4092 	int count;
4093 	uint64_t pcibus_base, pcibus_alen;
4094 	uint64_t max_bus;
4095 	uint8_t pcie_device_type = 0;
4096 	uint_t pf_mem_supported = 0;
4097 	dev_info_t *new_device;
4098 	int trans_device;
4099 	int ari_mode = B_FALSE;
4100 	int max_function = PCI_MAX_FUNCTIONS;
4101 
4102 	io_answer = io_base = io_alen = io_size = 0;
4103 	pf_mem_answer = pf_mem_base = pf_mem_size = pf_mem_alen = 0;
4104 
4105 	/*
4106 	 * Set "device_type" to "pci", the actual type will be set later
4107 	 * by pcicfg_set_busnode_props() below. This is needed as the
4108 	 * pcicfg_ra_free() below would update "available" property based
4109 	 * on "device_type".
4110 	 *
4111 	 * This code can be removed later after PCI configurator is changed
4112 	 * to use PCIRM, which automatically update properties upon allocation
4113 	 * and free, at that time we'll be able to remove the code inside
4114 	 * ndi_ra_alloc/free() which currently updates "available" property
4115 	 * for pci/pcie devices in pcie fabric.
4116 	 */
4117 	if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
4118 	    "device_type", "pci") != DDI_SUCCESS) {
4119 		DEBUG0("Failed to set \"device_type\" props\n");
4120 		return (PCICFG_FAILURE);
4121 	}
4122 
4123 	/*
4124 	 * setup resource maps for the bridge node
4125 	 */
4126 	if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_PCI_BUSNUM)
4127 	    == NDI_FAILURE) {
4128 		DEBUG0("Can not setup resource map - NDI_RA_TYPE_PCI_BUSNUM\n");
4129 		rval = PCICFG_FAILURE;
4130 		goto cleanup;
4131 	}
4132 	if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
4133 		DEBUG0("Can not setup resource map - NDI_RA_TYPE_MEM\n");
4134 		rval = PCICFG_FAILURE;
4135 		goto cleanup;
4136 	}
4137 	if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_IO) == NDI_FAILURE) {
4138 		DEBUG0("Can not setup resource map - NDI_RA_TYPE_IO\n");
4139 		rval = PCICFG_FAILURE;
4140 		goto cleanup;
4141 	}
4142 	if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_PCI_PREFETCH_MEM) ==
4143 	    NDI_FAILURE) {
4144 		DEBUG0("Can not setup resource map -"
4145 		    " NDI_RA_TYPE_PCI_PREFETCH_MEM\n");
4146 		rval = PCICFG_FAILURE;
4147 		goto cleanup;
4148 	}
4149 
4150 	/*
4151 	 * Allocate bus range pool for the bridge.
4152 	 */
4153 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4154 	req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4155 	req.ra_boundbase = 0;
4156 	req.ra_boundlen = req.ra_len = (PCI_MAX_BUS_NUM -1);
4157 	req.ra_align_mask = 0;  /* no alignment needed */
4158 
4159 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4160 	    &pcibus_base, &pcibus_alen, NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4161 
4162 	if (rval != NDI_SUCCESS) {
4163 		if (rval == NDI_RA_PARTIAL_REQ) {
4164 			/*EMPTY*/
4165 			DEBUG0("NDI_RA_PARTIAL_REQ returned for bus range\n");
4166 		} else {
4167 			DEBUG0(
4168 			    "Failed to allocate bus range for bridge\n");
4169 			rval = PCICFG_NORESRC;
4170 			goto cleanup;
4171 		}
4172 	}
4173 
4174 	DEBUG2("Bus Range Allocated [base=%d] [len=%d]\n",
4175 	    pcibus_base, pcibus_alen);
4176 
4177 	/*
4178 	 * Put available bus range into the pool.
4179 	 * Take the first one for this bridge to use and don't give
4180 	 * to child.
4181 	 */
4182 	(void) ndi_ra_free(new_child, pcibus_base+1, pcibus_alen-1,
4183 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4184 
4185 	next_bus = pcibus_base;
4186 	max_bus = pcibus_base + pcibus_alen - 1;
4187 
4188 	new_bus = next_bus;
4189 
4190 	DEBUG1("NEW bus found  ->[%d]\n", new_bus);
4191 
4192 	/* Keep track of highest bus for subordinate bus programming */
4193 	*highest_bus = new_bus;
4194 
4195 	/*
4196 	 * Allocate (non-prefetchable) Memory Space for Bridge
4197 	 */
4198 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4199 	req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4200 	req.ra_boundbase = 0;
4201 	/*
4202 	 * limit the boundlen,len to a 32b quantity. It should be Ok to
4203 	 * lose alignment-based-size of resource due to this.
4204 	 */
4205 	req.ra_boundlen = PCICFG_4GIG_LIMIT;
4206 	req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
4207 	req.ra_align_mask =
4208 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
4209 
4210 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4211 	    &mem_answer, &mem_alen,  NDI_RA_TYPE_MEM, NDI_RA_PASS);
4212 
4213 	if (rval != NDI_SUCCESS) {
4214 		if (rval == NDI_RA_PARTIAL_REQ) {
4215 			/*EMPTY*/
4216 			DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
4217 		} else {
4218 			DEBUG0(
4219 			    "Failed to allocate memory for bridge\n");
4220 			rval = PCICFG_NORESRC;
4221 			goto cleanup;
4222 		}
4223 	}
4224 
4225 	DEBUG3("Bridge Memory Allocated [0x%x.%x] len [0x%x]\n",
4226 	    PCICFG_HIADDR(mem_answer),
4227 	    PCICFG_LOADDR(mem_answer),
4228 	    mem_alen);
4229 
4230 	/*
4231 	 * Put available memory into the pool.
4232 	 */
4233 	(void) ndi_ra_free(new_child, mem_answer, mem_alen, NDI_RA_TYPE_MEM,
4234 	    NDI_RA_PASS);
4235 
4236 	mem_base = mem_answer;
4237 
4238 	/*
4239 	 * Allocate I/O Space for Bridge
4240 	 */
4241 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4242 	req.ra_align_mask = PCICFG_IOGRAN - 1; /* 4k alignment */
4243 	req.ra_boundbase = 0;
4244 	req.ra_boundlen = PCICFG_4GIG_LIMIT;
4245 	req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4246 	req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
4247 
4248 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req, &io_answer,
4249 	    &io_alen, NDI_RA_TYPE_IO, NDI_RA_PASS);
4250 
4251 	if (rval != NDI_SUCCESS) {
4252 		if (rval == NDI_RA_PARTIAL_REQ) {
4253 			/*EMPTY*/
4254 			DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
4255 		} else {
4256 			DEBUG0("Failed to allocate io space for bridge\n");
4257 			/* i/o space is an optional requirement so continue */
4258 		}
4259 	}
4260 
4261 	DEBUG3("Bridge IO Space Allocated [0x%x.%x] len [0x%x]\n",
4262 	    PCICFG_HIADDR(io_answer), PCICFG_LOADDR(io_answer), io_alen);
4263 
4264 	/*
4265 	 * Put available I/O into the pool.
4266 	 */
4267 	(void) ndi_ra_free(new_child, io_answer, io_alen, NDI_RA_TYPE_IO,
4268 	    NDI_RA_PASS);
4269 
4270 	io_base = io_answer;
4271 
4272 	/*
4273 	 * Check if the bridge supports Prefetchable memory range.
4274 	 * If it does, then we setup PF memory range for the bridge.
4275 	 * Otherwise, we skip the step of setting up PF memory
4276 	 * range for it. This could cause config operation to
4277 	 * fail if any devices under the bridge need PF memory.
4278 	 */
4279 	/* write a non zero value to the PF BASE register */
4280 	pci_config_put16(h, PCI_BCNF_PF_BASE_LOW, 0xfff0);
4281 	/* if the read returns zero then PF range is not supported */
4282 	if (pci_config_get16(h, PCI_BCNF_PF_BASE_LOW) == 0) {
4283 		/* bridge doesn't support PF memory range */
4284 		goto pf_setup_end;
4285 	} else {
4286 		pf_mem_supported = 1;
4287 		/* reset the PF BASE register */
4288 		pci_config_put16(h, PCI_BCNF_PF_BASE_LOW, 0);
4289 	}
4290 
4291 	/*
4292 	 * Bridge supports PF mem range; Allocate PF Memory Space for it.
4293 	 *
4294 	 * Note: Both non-prefetchable and prefetchable memory space
4295 	 * allocations are made within 32bit space. Currently, BIOSs
4296 	 * allocate device memory for PCI devices within the 32bit space
4297 	 * so this will not be a problem.
4298 	 */
4299 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4300 	req.ra_flags = NDI_RA_ALLOC_PARTIAL_OK | NDI_RA_ALLOC_BOUNDED;
4301 	req.ra_boundbase = 0;
4302 	req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
4303 	req.ra_align_mask =
4304 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
4305 
4306 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4307 	    &pf_mem_answer, &pf_mem_alen,  NDI_RA_TYPE_PCI_PREFETCH_MEM,
4308 	    NDI_RA_PASS);
4309 
4310 	if (rval != NDI_SUCCESS) {
4311 		if (rval == NDI_RA_PARTIAL_REQ) {
4312 			/*EMPTY*/
4313 			DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
4314 		} else {
4315 			DEBUG0(
4316 			    "Failed to allocate PF memory for bridge\n");
4317 			/* PF mem is an optional requirement so continue */
4318 		}
4319 	}
4320 
4321 	DEBUG3("Bridge PF Memory Allocated [0x%x.%x] len [0x%x]\n",
4322 	    PCICFG_HIADDR(pf_mem_answer),
4323 	    PCICFG_LOADDR(pf_mem_answer),
4324 	    pf_mem_alen);
4325 
4326 	/*
4327 	 * Put available PF memory into the pool.
4328 	 */
4329 	(void) ndi_ra_free(new_child, pf_mem_answer, pf_mem_alen,
4330 	    NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
4331 
4332 	pf_mem_base = pf_mem_answer;
4333 
4334 	/*
4335 	 * Program the PF memory base register with the
4336 	 * start of the memory range
4337 	 */
4338 	pci_config_put16(h, PCI_BCNF_PF_BASE_LOW,
4339 	    PCICFG_HIWORD(PCICFG_LOADDR(pf_mem_answer)));
4340 	pci_config_put32(h, PCI_BCNF_PF_BASE_HIGH,
4341 	    PCICFG_HIADDR(pf_mem_answer));
4342 
4343 	/*
4344 	 * Program the PF memory limit register with the
4345 	 * end of the memory range.
4346 	 */
4347 	pci_config_put16(h, PCI_BCNF_PF_LIMIT_LOW,
4348 	    PCICFG_HIWORD(PCICFG_LOADDR(
4349 	    PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4350 	    PCICFG_MEMGRAN) - 1)));
4351 	pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH,
4352 	    PCICFG_HIADDR(PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4353 	    PCICFG_MEMGRAN) - 1));
4354 
4355 	/*
4356 	 * Allocate the chunk of PF memory (if any) not programmed into the
4357 	 * bridge because of the round down.
4358 	 */
4359 	if (PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen), PCICFG_MEMGRAN)
4360 	    != (pf_mem_answer + pf_mem_alen)) {
4361 		DEBUG0("Need to allocate Memory round off chunk\n");
4362 		bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4363 		req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
4364 		req.ra_addr = PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4365 		    PCICFG_MEMGRAN);
4366 		req.ra_len =  (pf_mem_answer + pf_mem_alen) -
4367 		    (PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4368 		    PCICFG_MEMGRAN));
4369 
4370 		(void) ndi_ra_alloc(new_child, &req,
4371 		    &round_answer, &round_len,  NDI_RA_TYPE_PCI_PREFETCH_MEM,
4372 		    NDI_RA_PASS);
4373 	}
4374 
4375 pf_setup_end:
4376 
4377 	/*
4378 	 * Program the memory base register with the
4379 	 * start of the memory range
4380 	 */
4381 	pci_config_put16(h, PCI_BCNF_MEM_BASE,
4382 	    PCICFG_HIWORD(PCICFG_LOADDR(mem_answer)));
4383 
4384 	/*
4385 	 * Program the memory limit register with the
4386 	 * end of the memory range.
4387 	 */
4388 
4389 	pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
4390 	    PCICFG_HIWORD(PCICFG_LOADDR(
4391 	    PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN) - 1)));
4392 
4393 	/*
4394 	 * Allocate the chunk of memory (if any) not programmed into the
4395 	 * bridge because of the round down.
4396 	 */
4397 	if (PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN)
4398 	    != (mem_answer + mem_alen)) {
4399 		DEBUG0("Need to allocate Memory round off chunk\n");
4400 		bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4401 		req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
4402 		req.ra_addr = PCICFG_ROUND_DOWN((mem_answer + mem_alen),
4403 		    PCICFG_MEMGRAN);
4404 		req.ra_len =  (mem_answer + mem_alen) -
4405 		    (PCICFG_ROUND_DOWN((mem_answer + mem_alen),
4406 		    PCICFG_MEMGRAN));
4407 
4408 		(void) ndi_ra_alloc(new_child, &req,
4409 		    &round_answer, &round_len,  NDI_RA_TYPE_MEM, NDI_RA_PASS);
4410 	}
4411 
4412 	/*
4413 	 * Program the I/O Space Base
4414 	 */
4415 	pci_config_put8(h, PCI_BCNF_IO_BASE_LOW,
4416 	    PCICFG_HIBYTE(PCICFG_LOWORD(
4417 	    PCICFG_LOADDR(io_answer))));
4418 
4419 	pci_config_put16(h, PCI_BCNF_IO_BASE_HI,
4420 	    PCICFG_HIWORD(PCICFG_LOADDR(io_answer)));
4421 
4422 	/*
4423 	 * Program the I/O Space Limit
4424 	 */
4425 	pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
4426 	    PCICFG_HIBYTE(PCICFG_LOWORD(
4427 	    PCICFG_LOADDR(PCICFG_ROUND_DOWN(io_answer + io_alen,
4428 	    PCICFG_IOGRAN)))) - 1);
4429 
4430 	pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
4431 	    PCICFG_HIWORD(PCICFG_LOADDR(
4432 	    PCICFG_ROUND_DOWN(io_answer + io_alen, PCICFG_IOGRAN)))
4433 	    - 1);
4434 
4435 	/*
4436 	 * Allocate the chunk of I/O (if any) not programmed into the
4437 	 * bridge because of the round down.
4438 	 */
4439 	if (PCICFG_ROUND_DOWN((io_answer + io_alen), PCICFG_IOGRAN)
4440 	    != (io_answer + io_alen)) {
4441 		DEBUG0("Need to allocate I/O round off chunk\n");
4442 		bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4443 		req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
4444 		req.ra_addr = PCICFG_ROUND_DOWN((io_answer + io_alen),
4445 		    PCICFG_IOGRAN);
4446 		req.ra_len =  (io_answer + io_alen) -
4447 		    (PCICFG_ROUND_DOWN((io_answer + io_alen),
4448 		    PCICFG_IOGRAN));
4449 
4450 		(void) ndi_ra_alloc(new_child, &req,
4451 		    &round_answer, &round_len,  NDI_RA_TYPE_IO, NDI_RA_PASS);
4452 	}
4453 
4454 	(void) pcicfg_set_bus_numbers(h, bus, new_bus, max_bus);
4455 
4456 	/*
4457 	 * Setup "ranges" and "bus-range" properties before onlining
4458 	 * the bridge.
4459 	 */
4460 	bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
4461 
4462 	range[0].child_high = range[0].parent_high |= (PCI_REG_REL_M |
4463 	    PCI_ADDR_IO);
4464 	range[0].child_low = range[0].parent_low = io_base;
4465 	range[1].child_high = range[1].parent_high |=
4466 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
4467 	range[1].child_low = range[1].parent_low = mem_base;
4468 	range[2].child_high = range[2].parent_high |=
4469 	    (PCI_REG_REL_M | PCI_ADDR_MEM64 | PCI_REG_PF_M);
4470 	range[2].child_low = range[2].parent_low = pf_mem_base;
4471 
4472 	range[0].size_low = io_alen;
4473 	(void) pcicfg_update_ranges_prop(new_child, &range[0]);
4474 	range[1].size_low = mem_alen;
4475 	(void) pcicfg_update_ranges_prop(new_child, &range[1]);
4476 	range[2].size_low = pf_mem_alen;
4477 	(void) pcicfg_update_ranges_prop(new_child, &range[2]);
4478 
4479 	bus_range[0] = new_bus;
4480 	bus_range[1] = max_bus;
4481 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
4482 	    "bus-range", bus_range, 2);
4483 
4484 	/*
4485 	 * Reset the secondary bus
4486 	 */
4487 	pci_config_put16(h, PCI_BCNF_BCNTRL,
4488 	    pci_config_get16(h, PCI_BCNF_BCNTRL) | 0x40);
4489 
4490 	drv_usecwait(100);
4491 
4492 	pci_config_put16(h, PCI_BCNF_BCNTRL,
4493 	    pci_config_get16(h, PCI_BCNF_BCNTRL) & ~0x40);
4494 
4495 	/*
4496 	 * Clear status bits
4497 	 */
4498 	pci_config_put16(h, PCI_BCNF_SEC_STATUS, 0xffff);
4499 
4500 	/*
4501 	 * Needs to be set to this value
4502 	 */
4503 	pci_config_put8(h, PCI_CONF_ILINE, 0xf);
4504 
4505 	/* check our device_type as defined by Open Firmware */
4506 	if (pcicfg_pcie_device_type(new_child, h) == DDI_SUCCESS)
4507 		pcie_device_type = 1;
4508 
4509 	/*
4510 	 * Set bus properties
4511 	 */
4512 	if (pcicfg_set_busnode_props(new_child, pcie_device_type)
4513 	    != PCICFG_SUCCESS) {
4514 		DEBUG0("Failed to set busnode props\n");
4515 		rval = PCICFG_FAILURE;
4516 		goto cleanup;
4517 	}
4518 
4519 	(void) pcicfg_device_on(h);
4520 
4521 	if (is_pcie)
4522 		(void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
4523 	if (ndi_devi_online(new_child, NDI_NO_EVENT|NDI_CONFIG)
4524 	    != NDI_SUCCESS) {
4525 		DEBUG0("Unable to online bridge\n");
4526 		rval = PCICFG_FAILURE;
4527 		goto cleanup;
4528 	}
4529 
4530 	DEBUG0("Bridge is ONLINE\n");
4531 
4532 	/*
4533 	 * After a Reset, we need to wait 2^25 clock cycles before the
4534 	 * first Configuration access.  The worst case is 33MHz, which
4535 	 * is a 1 second wait.
4536 	 */
4537 	drv_usecwait(pcicfg_sec_reset_delay);
4538 
4539 	/*
4540 	 * Probe all children devices
4541 	 */
4542 	DEBUG0("Bridge Programming Complete - probe children\n");
4543 	ndi_devi_enter(new_child, &count);
4544 	for (i = 0; ((i < PCI_MAX_DEVICES) && (ari_mode == B_FALSE));
4545 	    i++) {
4546 		for (j = 0; j < max_function; ) {
4547 			if (ari_mode)
4548 				trans_device = j >> 3;
4549 			else
4550 				trans_device = i;
4551 
4552 			if ((rval = pcicfg_probe_children(new_child,
4553 			    new_bus, trans_device, j & 7, highest_bus,
4554 			    0, is_pcie)) != PCICFG_SUCCESS) {
4555 				if (rval == PCICFG_NODEVICE) {
4556 					DEBUG3("No Device at bus [0x%x]"
4557 					    "device [0x%x] "
4558 					    "func [0x%x]\n", new_bus,
4559 					    trans_device, j & 7);
4560 
4561 					if (j)
4562 						goto next;
4563 				} else
4564 					/*EMPTY*/
4565 					DEBUG3("Failed to configure bus "
4566 					    "[0x%x] device [0x%x] "
4567 					    "func [0x%x]\n", new_bus,
4568 					    trans_device, j & 7);
4569 				break;
4570 			}
4571 next:
4572 			new_device = pcicfg_devi_find(new_child, trans_device,
4573 			    (j & 7));
4574 
4575 			/*
4576 			 * Determine if ARI Forwarding should be enabled.
4577 			 */
4578 			if (j == 0) {
4579 				if (new_device == NULL)
4580 					break;
4581 
4582 				if ((pcie_ari_supported(new_child) ==
4583 				    PCIE_ARI_FORW_SUPPORTED) &&
4584 				    (pcie_ari_device(new_device) ==
4585 				    PCIE_ARI_DEVICE)) {
4586 					if (pcie_ari_enable(new_child) ==
4587 					    DDI_SUCCESS) {
4588 						(void) ddi_prop_create(
4589 						    DDI_DEV_T_NONE,
4590 						    new_child,
4591 						    DDI_PROP_CANSLEEP,
4592 						    "ari-enabled", NULL, 0);
4593 						ari_mode = B_TRUE;
4594 						max_function =
4595 						    PCICFG_MAX_ARI_FUNCTION;
4596 					}
4597 				}
4598 			}
4599 			if (ari_mode == B_TRUE) {
4600 				int next_function;
4601 
4602 				if (new_device == NULL)
4603 					break;
4604 
4605 				if (pcie_ari_get_next_function(new_device,
4606 				    &next_function) != DDI_SUCCESS)
4607 					break;
4608 
4609 				j = next_function;
4610 
4611 				if (next_function == 0)
4612 					break;
4613 			} else
4614 				j++;
4615 
4616 		}
4617 		/* if any function fails to be configured, no need to proceed */
4618 		if (rval != PCICFG_NODEVICE)
4619 			break;
4620 	}
4621 	ndi_devi_exit(new_child, count);
4622 
4623 	/*
4624 	 * Offline the bridge to allow reprogramming of resources.
4625 	 *
4626 	 * This should always succeed since nobody else has started to
4627 	 * use it yet, failing to detach the driver would indicate a bug.
4628 	 * Also in that case it's better just panic than allowing the
4629 	 * configurator to proceed with BAR reprogramming without bridge
4630 	 * driver detached.
4631 	 */
4632 	VERIFY(ndi_devi_offline(new_child, NDI_NO_EVENT|NDI_UNCONFIG)
4633 	    == NDI_SUCCESS);
4634 	if (is_pcie)
4635 		pcie_fini_bus(new_child, PCIE_BUS_INITIAL);
4636 
4637 	phdl.dip = new_child;
4638 	phdl.memory_base = mem_answer;
4639 	phdl.io_base = io_answer;
4640 	phdl.pf_memory_base = pf_mem_answer;
4641 	phdl.error = PCICFG_SUCCESS;	/* in case of empty child tree */
4642 
4643 	ndi_devi_enter(ddi_get_parent(new_child), &count);
4644 	ddi_walk_devs(new_child, pcicfg_find_resource_end, (void *)&phdl);
4645 	ndi_devi_exit(ddi_get_parent(new_child), count);
4646 
4647 	num_slots = pcicfg_get_nslots(new_child, h);
4648 	mem_end = PCICFG_ROUND_UP(phdl.memory_base, PCICFG_MEMGRAN);
4649 	io_end = PCICFG_ROUND_UP(phdl.io_base, PCICFG_IOGRAN);
4650 	pf_mem_end = PCICFG_ROUND_UP(phdl.pf_memory_base, PCICFG_MEMGRAN);
4651 
4652 	DEBUG4("Start of Unallocated Bridge(%d slots) Resources Mem=0x%lx "
4653 	    "I/O=0x%lx PF_mem=%x%lx\n", num_slots, mem_end, io_end, pf_mem_end);
4654 
4655 	/*
4656 	 * Before probing the children we've allocated maximum MEM/IO
4657 	 * resources from parent, and updated "available" property
4658 	 * accordingly. Later we'll be giving up unused resources to
4659 	 * the parent, thus we need to destroy "available" property
4660 	 * here otherwise it will be out-of-sync with the actual free
4661 	 * resources this bridge has. This property will be rebuilt below
4662 	 * with the actual free resources reserved for hotplug slots
4663 	 * (if any).
4664 	 */
4665 	(void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "available");
4666 	/*
4667 	 * if the bridge a slots, then preallocate. If not, assume static
4668 	 * configuration. Also check for preallocation limits and spit
4669 	 * warning messages appropriately (perhaps some can be in debug mode).
4670 	 */
4671 	if (num_slots) {
4672 		uint64_t mem_reqd = mem_answer +
4673 		    (num_slots * pcicfg_slot_memsize);
4674 		uint64_t io_reqd = io_answer +
4675 		    (num_slots * pcicfg_slot_iosize);
4676 		uint64_t pf_mem_reqd = pf_mem_answer +
4677 		    (num_slots * pcicfg_slot_pf_memsize);
4678 		uint8_t highest_bus_reqd = new_bus +
4679 		    (num_slots * pcicfg_slot_busnums);
4680 #ifdef DEBUG
4681 		if (mem_end > mem_reqd)
4682 			DEBUG3("Memory space consumed by bridge more "
4683 			    "than planned for %d slot(s)(%" PRIx64 ",%"
4684 			    PRIx64 ")", num_slots, mem_answer, mem_end);
4685 		if (io_end > io_reqd)
4686 			DEBUG3("IO space consumed by bridge more than"
4687 			    " planned for %d slot(s)(%" PRIx64 ",%" PRIx64 ")",
4688 			    num_slots, io_answer, io_end);
4689 		if (pf_mem_end > pf_mem_reqd)
4690 			DEBUG3("PF Memory space consumed by bridge"
4691 			    " more than planned for %d slot(s)(%" PRIx64 ",%"
4692 			    PRIx64 ")", num_slots, pf_mem_answer, pf_mem_end);
4693 		if (*highest_bus > highest_bus_reqd)
4694 			DEBUG3("Buses consumed by bridge more "
4695 			    "than planned for %d slot(s)(%x, %x)",
4696 			    num_slots, new_bus, *highest_bus);
4697 
4698 		if (mem_reqd > (mem_answer + mem_alen))
4699 			DEBUG3("Memory space required by bridge more "
4700 			    "than available for %d slot(s)(%" PRIx64 ",%"
4701 			    PRIx64 ")", num_slots, mem_answer, mem_end);
4702 		if (io_reqd > (io_answer + io_alen))
4703 			DEBUG3("IO space required by bridge more than"
4704 			    "available for %d slot(s)(%" PRIx64 ",%" PRIx64 ")",
4705 			    num_slots, io_answer, io_end);
4706 		if (pf_mem_reqd > (pf_mem_answer + pf_mem_alen))
4707 			DEBUG3("PF Memory space required by bridge"
4708 			    " more than available for %d slot(s)(%" PRIx64 ",%"
4709 			    PRIx64 ")", num_slots, pf_mem_answer, pf_mem_end);
4710 		if (highest_bus_reqd > max_bus)
4711 			DEBUG3("Bus numbers required by bridge more "
4712 			    "than available for %d slot(s)(%x, %x)",
4713 			    num_slots, new_bus, *highest_bus);
4714 #endif
4715 		mem_end = MAX((MIN(mem_reqd, (mem_answer + mem_alen))),
4716 		    mem_end);
4717 		io_end = MAX((MIN(io_reqd, (io_answer + io_alen))), io_end);
4718 		pf_mem_end = MAX((MIN(pf_mem_reqd, (pf_mem_answer +
4719 		    pf_mem_alen))), pf_mem_end);
4720 		*highest_bus = MAX((MIN(highest_bus_reqd, max_bus)),
4721 		    *highest_bus);
4722 		DEBUG4("mem_end %lx, io_end %lx, pf_mem_end %lx"
4723 		    " highest_bus %x\n", mem_end, io_end, pf_mem_end,
4724 		    *highest_bus);
4725 	}
4726 
4727 	/*
4728 	 * Give back unused memory space to parent.
4729 	 */
4730 	(void) ndi_ra_free(ddi_get_parent(new_child), mem_end,
4731 	    (mem_answer + mem_alen) - mem_end, NDI_RA_TYPE_MEM, NDI_RA_PASS);
4732 
4733 	if (mem_end == mem_answer) {
4734 		DEBUG0("No memory resources used\n");
4735 		/*
4736 		 * To prevent the bridge from forwarding any Memory
4737 		 * transactions, the Memory Limit will be programmed
4738 		 * with a smaller value than the Memory Base.
4739 		 */
4740 		pci_config_put16(h, PCI_BCNF_MEM_BASE, 0xffff);
4741 		pci_config_put16(h, PCI_BCNF_MEM_LIMIT, 0);
4742 
4743 		mem_size = 0;
4744 	} else {
4745 		/*
4746 		 * Reprogram the end of the memory.
4747 		 */
4748 		pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
4749 		    PCICFG_HIWORD(mem_end) - 1);
4750 		mem_size = mem_end - mem_base;
4751 	}
4752 
4753 	/*
4754 	 * Give back unused io space to parent.
4755 	 */
4756 	(void) ndi_ra_free(ddi_get_parent(new_child),
4757 	    io_end, (io_answer + io_alen) - io_end,
4758 	    NDI_RA_TYPE_IO, NDI_RA_PASS);
4759 
4760 	if (io_end == io_answer) {
4761 		DEBUG0("No IO Space resources used\n");
4762 
4763 		/*
4764 		 * To prevent the bridge from forwarding any I/O
4765 		 * transactions, the I/O Limit will be programmed
4766 		 * with a smaller value than the I/O Base.
4767 		 */
4768 		pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW, 0);
4769 		pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI, 0);
4770 		pci_config_put8(h, PCI_BCNF_IO_BASE_LOW, 0xff);
4771 		pci_config_put16(h, PCI_BCNF_IO_BASE_HI, 0);
4772 
4773 		io_size = 0;
4774 	} else {
4775 		/*
4776 		 * Reprogram the end of the io space.
4777 		 */
4778 		pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
4779 		    PCICFG_HIBYTE(PCICFG_LOWORD(
4780 		    PCICFG_LOADDR(io_end) - 1)));
4781 
4782 		pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
4783 		    PCICFG_HIWORD(PCICFG_LOADDR(io_end - 1)));
4784 
4785 		io_size = io_end - io_base;
4786 	}
4787 
4788 	/*
4789 	 * Give back unused PF memory space to parent.
4790 	 */
4791 	if (pf_mem_supported) {
4792 		(void) ndi_ra_free(ddi_get_parent(new_child),
4793 		    pf_mem_end, (pf_mem_answer + pf_mem_alen) - pf_mem_end,
4794 		    NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
4795 
4796 		if (pf_mem_end == pf_mem_answer) {
4797 			DEBUG0("No PF memory resources used\n");
4798 			/*
4799 			 * To prevent the bridge from forwarding any PF Memory
4800 			 * transactions, the PF Memory Limit will be programmed
4801 			 * with a smaller value than the Memory Base.
4802 			 */
4803 			pci_config_put16(h, PCI_BCNF_PF_BASE_LOW, 0xfff0);
4804 			pci_config_put32(h, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
4805 			pci_config_put16(h, PCI_BCNF_PF_LIMIT_LOW, 0);
4806 			pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH, 0);
4807 
4808 			pf_mem_size = 0;
4809 		} else {
4810 			/*
4811 			 * Reprogram the end of the PF memory range.
4812 			 */
4813 			pci_config_put16(h, PCI_BCNF_PF_LIMIT_LOW,
4814 			    PCICFG_HIWORD(PCICFG_LOADDR(pf_mem_end - 1)));
4815 			pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH,
4816 			    PCICFG_HIADDR(pf_mem_end - 1));
4817 			pf_mem_size = pf_mem_end - pf_mem_base;
4818 		}
4819 	}
4820 
4821 	if ((max_bus - *highest_bus) > 0) {
4822 		/*
4823 		 * Give back unused bus numbers
4824 		 */
4825 		(void) ndi_ra_free(ddi_get_parent(new_child),
4826 		    *highest_bus+1, max_bus - *highest_bus,
4827 		    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4828 	}
4829 
4830 	/*
4831 	 * Set bus numbers to ranges encountered during scan
4832 	 */
4833 	(void) pcicfg_set_bus_numbers(h, bus, new_bus, *highest_bus);
4834 
4835 	/*
4836 	 * Remove the ranges property if it exists since we will create
4837 	 * a new one.
4838 	 */
4839 	(void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "ranges");
4840 
4841 	DEBUG2("Creating Ranges property - Mem Address %lx Mem Size %x\n",
4842 	    mem_base, mem_size);
4843 	DEBUG2("                         - I/O Address %lx I/O Size %x\n",
4844 	    io_base, io_size);
4845 	DEBUG2("                         - PF Mem address %lx PF Mem Size %x\n",
4846 	    pf_mem_base, pf_mem_size);
4847 
4848 	bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
4849 
4850 	range[0].child_high = range[0].parent_high |= (PCI_REG_REL_M |
4851 	    PCI_ADDR_IO);
4852 	range[0].child_low = range[0].parent_low = io_base;
4853 	range[1].child_high = range[1].parent_high |=
4854 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
4855 	range[1].child_low = range[1].parent_low = mem_base;
4856 	range[2].child_high = range[2].parent_high |=
4857 	    (PCI_REG_REL_M | PCI_ADDR_MEM64 | PCI_REG_PF_M);
4858 	range[2].child_low = range[2].parent_low = pf_mem_base;
4859 
4860 	if (io_size > 0) {
4861 		range[0].size_low = io_size;
4862 		(void) pcicfg_update_ranges_prop(new_child, &range[0]);
4863 	}
4864 	if (mem_size > 0) {
4865 		range[1].size_low = mem_size;
4866 		(void) pcicfg_update_ranges_prop(new_child, &range[1]);
4867 	}
4868 	if (pf_mem_size > 0) {
4869 		range[2].size_low = pf_mem_size;
4870 		(void) pcicfg_update_ranges_prop(new_child, &range[2]);
4871 	}
4872 
4873 	bus_range[0] = pci_config_get8(h, PCI_BCNF_SECBUS);
4874 	bus_range[1] = pci_config_get8(h, PCI_BCNF_SUBBUS);
4875 	DEBUG1("End of bridge probe: bus_range[0] =  %d\n", bus_range[0]);
4876 	DEBUG1("End of bridge probe: bus_range[1] =  %d\n", bus_range[1]);
4877 
4878 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
4879 	    "bus-range", bus_range, 2);
4880 
4881 	rval = PCICFG_SUCCESS;
4882 
4883 	PCICFG_DUMP_BRIDGE_CONFIG(h);
4884 
4885 cleanup:
4886 	/* free up resources (for error return case only) */
4887 	if (rval != PCICFG_SUCCESS) {
4888 		if (mem_alen)
4889 			(void) ndi_ra_free(ddi_get_parent(new_child), mem_base,
4890 			    mem_alen, NDI_RA_TYPE_MEM, NDI_RA_PASS);
4891 		if (io_alen)
4892 			(void) ndi_ra_free(ddi_get_parent(new_child), io_base,
4893 			    io_alen, NDI_RA_TYPE_IO, NDI_RA_PASS);
4894 		if (pf_mem_alen)
4895 			(void) ndi_ra_free(ddi_get_parent(new_child),
4896 			    pf_mem_base, pf_mem_alen,
4897 			    NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
4898 		if (pcibus_alen)
4899 			(void) ndi_ra_free(ddi_get_parent(new_child),
4900 			    pcibus_base, pcibus_alen, NDI_RA_TYPE_PCI_BUSNUM,
4901 			    NDI_RA_PASS);
4902 	}
4903 
4904 	/* free up any resource maps setup for the bridge node */
4905 	(void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_PCI_BUSNUM);
4906 	(void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_IO);
4907 	(void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_MEM);
4908 	(void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_PCI_PREFETCH_MEM);
4909 
4910 	return (rval);
4911 }
4912 
4913 static int
4914 pcicfg_find_resource_end(dev_info_t *dip, void *hdl)
4915 {
4916 	pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
4917 	pci_regspec_t *pci_ap;
4918 	int length;
4919 	int rcount;
4920 	int i;
4921 
4922 	entry->error = PCICFG_SUCCESS;
4923 
4924 	if (dip == entry->dip) {
4925 		DEBUG0("Don't include parent bridge node\n");
4926 		return (DDI_WALK_CONTINUE);
4927 	} else {
4928 		if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
4929 		    DDI_PROP_DONTPASS, "assigned-addresses",
4930 		    (caddr_t)&pci_ap,  &length) != DDI_PROP_SUCCESS) {
4931 			DEBUG0("Node doesn't have assigned-addresses\n");
4932 			return (DDI_WALK_CONTINUE);
4933 		}
4934 
4935 		rcount = length / sizeof (pci_regspec_t);
4936 
4937 		for (i = 0; i < rcount; i++) {
4938 
4939 			switch (PCI_REG_ADDR_G(pci_ap[i].pci_phys_hi)) {
4940 
4941 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
4942 				if (pci_ap[i].pci_phys_hi & PCI_REG_PF_M) {
4943 					if ((pci_ap[i].pci_phys_low +
4944 					    pci_ap[i].pci_size_low) >
4945 					    entry->pf_memory_base) {
4946 						entry->pf_memory_base =
4947 						    pci_ap[i].pci_phys_low +
4948 						    pci_ap[i].pci_size_low;
4949 					}
4950 				} else {
4951 					if ((pci_ap[i].pci_phys_low +
4952 					    pci_ap[i].pci_size_low) >
4953 					    entry->memory_base) {
4954 						entry->memory_base =
4955 						    pci_ap[i].pci_phys_low +
4956 						    pci_ap[i].pci_size_low;
4957 					}
4958 				}
4959 				break;
4960 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
4961 				if (pci_ap[i].pci_phys_hi & PCI_REG_PF_M) {
4962 					if ((PCICFG_LADDR(
4963 					    pci_ap[i].pci_phys_low,
4964 					    pci_ap[i].pci_phys_mid) +
4965 					    pci_ap[i].pci_size_low) >
4966 					    entry->pf_memory_base) {
4967 						entry->pf_memory_base =
4968 						    PCICFG_LADDR(
4969 						    pci_ap[i].pci_phys_low,
4970 						    pci_ap[i].pci_phys_mid) +
4971 						    pci_ap[i].pci_size_low;
4972 					}
4973 				} else {
4974 					if ((PCICFG_LADDR(
4975 					    pci_ap[i].pci_phys_low,
4976 					    pci_ap[i].pci_phys_mid) +
4977 					    pci_ap[i].pci_size_low) >
4978 					    entry->memory_base) {
4979 						entry->memory_base =
4980 						    PCICFG_LADDR(
4981 						    pci_ap[i].pci_phys_low,
4982 						    pci_ap[i].pci_phys_mid) +
4983 						    pci_ap[i].pci_size_low;
4984 					}
4985 				}
4986 				break;
4987 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
4988 				if ((pci_ap[i].pci_phys_low +
4989 				    pci_ap[i].pci_size_low) >
4990 				    entry->io_base) {
4991 					entry->io_base =
4992 					    pci_ap[i].pci_phys_low +
4993 					    pci_ap[i].pci_size_low;
4994 				}
4995 				break;
4996 			}
4997 		}
4998 
4999 		/*
5000 		 * free the memory allocated by ddi_getlongprop
5001 		 */
5002 		kmem_free(pci_ap, length);
5003 
5004 		/*
5005 		 * continue the walk to the next sibling to sum memory
5006 		 */
5007 		return (DDI_WALK_CONTINUE);
5008 	}
5009 }
5010 
5011 /*
5012  * Make "parent" be the parent of the "child" dip
5013  */
5014 static void
5015 pcicfg_reparent_node(dev_info_t *child, dev_info_t *parent)
5016 {
5017 	int circ;
5018 	dev_info_t *opdip;
5019 
5020 	ASSERT(i_ddi_node_state(child) <= DS_LINKED);
5021 	/*
5022 	 * Unlink node from tree before reparenting
5023 	 */
5024 	opdip = ddi_get_parent(child);
5025 	ndi_devi_enter(opdip, &circ);
5026 	(void) i_ndi_unconfig_node(child, DS_PROTO, 0);
5027 	ndi_devi_exit(opdip, circ);
5028 
5029 	DEVI(child)->devi_parent = DEVI(parent);
5030 	DEVI(child)->devi_bus_ctl = DEVI(parent);
5031 	(void) ndi_devi_bind_driver(child, 0);
5032 }
5033 
5034 /*
5035  * Return PCICFG_SUCCESS if device exists at the specified address.
5036  * Return PCICFG_NODEVICE is no device exists at the specified address.
5037  */
5038 int
5039 pcicfg_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
5040 {
5041 	caddr_t	cfgaddr;
5042 	ddi_device_acc_attr_t attr;
5043 	dev_info_t *anode;
5044 	int status;
5045 	int		rlen;
5046 	pci_regspec_t	*reg;
5047 	int		ret = DDI_SUCCESS;
5048 	int16_t		tmp;
5049 
5050 	/*
5051 	 * Get the pci register spec from the node
5052 	 */
5053 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
5054 	    (caddr_t)&reg, &rlen);
5055 
5056 	switch (status) {
5057 		case DDI_PROP_SUCCESS:
5058 			break;
5059 		case DDI_PROP_NO_MEMORY:
5060 			DEBUG0("reg present, but unable to get memory\n");
5061 			return (PCICFG_FAILURE);
5062 		default:
5063 			DEBUG0("no reg property\n");
5064 			return (PCICFG_FAILURE);
5065 	}
5066 
5067 	anode = dip;
5068 	DEBUG2("conf_map: dip=%p, anode=%p\n", dip, anode);
5069 
5070 	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
5071 	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
5072 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
5073 
5074 	if (ddi_regs_map_setup(anode, 0, &cfgaddr, 0, 0, &attr, handle)
5075 	    != DDI_SUCCESS) {
5076 		DEBUG0("Failed to setup registers\n");
5077 		kmem_free((caddr_t)reg, rlen);
5078 		return (PCICFG_FAILURE);
5079 	}
5080 
5081 	/*
5082 	 * need to use DDI interfaces as the conf space is
5083 	 * cannot be directly accessed by the host.
5084 	 */
5085 	tmp = (int16_t)ddi_get16(*handle, (uint16_t *)cfgaddr);
5086 	if ((tmp == (int16_t)0xffff) || (tmp == -1)) {
5087 		DEBUG1("NO DEVICEFOUND, read %x\n", tmp);
5088 		ret = PCICFG_NODEVICE;
5089 	} else {
5090 		if (tmp == 0) {
5091 			DEBUG0("Device Not Ready yet ?");
5092 			ret = PCICFG_NODEVICE;
5093 		} else {
5094 			DEBUG1("DEVICEFOUND, read %x\n", tmp);
5095 			ret = PCICFG_SUCCESS;
5096 		}
5097 	}
5098 
5099 	if (ret == PCICFG_NODEVICE)
5100 		ddi_regs_map_free(handle);
5101 	kmem_free((caddr_t)reg, rlen);
5102 
5103 	return (ret);
5104 
5105 }
5106 
5107 static void
5108 pcicfg_config_teardown(ddi_acc_handle_t *handle)
5109 {
5110 	(void) ddi_regs_map_free(handle);
5111 }
5112 
5113 static int
5114 pcicfg_add_config_reg(dev_info_t *dip,
5115     uint_t bus, uint_t device, uint_t func)
5116 {
5117 	int reg[10] = { PCI_ADDR_CONFIG, 0, 0, 0, 0};
5118 
5119 	reg[0] = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
5120 
5121 	return (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg", reg, 5));
5122 }
5123 
5124 static int
5125 pcicfg_ari_configure(dev_info_t *dip)
5126 {
5127 	if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
5128 		return (DDI_FAILURE);
5129 
5130 	/*
5131 	 * Until we have resource balancing, dynamically configure
5132 	 * ARI functions without firmware assistamce.
5133 	 */
5134 	return (DDI_FAILURE);
5135 }
5136 
5137 
5138 #ifdef DEBUG
5139 static void
5140 debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
5141     uintptr_t a5)
5142 {
5143 	if (pcicfg_debug > 1) {
5144 		prom_printf("pcicfg: ");
5145 		prom_printf(fmt, a1, a2, a3, a4, a5);
5146 	}
5147 }
5148 #endif
5149 
5150 /*ARGSUSED*/
5151 static uint8_t
5152 pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle)
5153 {
5154 	uint16_t cap_id_loc, slot_id_loc;
5155 	uint8_t num_slots = 0;
5156 
5157 	/* just depend on the pcie_cap for now. */
5158 	(void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
5159 	(void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &slot_id_loc);
5160 	if (cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
5161 		if (pci_config_get8(handle, cap_id_loc + PCI_CAP_ID_REGS_OFF) &
5162 		    PCIE_PCIECAP_SLOT_IMPL)
5163 			num_slots = 1;
5164 	} else /* not a PCIe switch/bridge. Must be a PCI-PCI[-X] bridge */
5165 	if (slot_id_loc != PCI_CAP_NEXT_PTR_NULL) {
5166 		uint8_t esr_reg = pci_config_get8(handle, slot_id_loc + 2);
5167 		num_slots = PCI_CAPSLOT_NSLOTS(esr_reg);
5168 	}
5169 	/* XXX - need to cover PCI-PCIe bridge with n slots */
5170 	return (num_slots);
5171 }
5172 
5173 /*ARGSUSED*/
5174 static int
5175 pcicfg_pcie_dev(dev_info_t *dip, ddi_acc_handle_t handle)
5176 {
5177 	/* get parent device's device_type property */
5178 	char *device_type;
5179 	int val;
5180 	dev_info_t *pdip = ddi_get_parent(dip);
5181 
5182 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
5183 	    "device_type", &device_type) != DDI_PROP_SUCCESS) {
5184 		DEBUG2("device_type property missing for %s#%d",
5185 		    ddi_get_name(pdip), ddi_get_instance(pdip));
5186 		return (DDI_FAILURE);
5187 	}
5188 	DEBUG1("device_type=<%s>\n", device_type);
5189 
5190 	val = DDI_FAILURE;
5191 	if (strcmp(device_type, "pciex") == 0)
5192 		val = DDI_SUCCESS;
5193 	ddi_prop_free(device_type);
5194 	return (val);
5195 }
5196 
5197 static int
5198 pcicfg_pcie_device_type(dev_info_t *dip, ddi_acc_handle_t handle)
5199 {
5200 	int port_type = pcicfg_pcie_port_type(dip, handle);
5201 
5202 	DEBUG1("device port_type = %x\n", port_type);
5203 	/* No PCIe CAP regs, we are not PCIe device_type */
5204 	if (port_type < 0)
5205 		return (DDI_FAILURE);
5206 
5207 	/* check for all PCIe device_types */
5208 	if ((port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
5209 	    (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) ||
5210 	    (port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
5211 	    (port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE))
5212 		return (DDI_SUCCESS);
5213 
5214 	return (DDI_FAILURE);
5215 
5216 }
5217 
5218 /*ARGSUSED*/
5219 static int
5220 pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
5221 {
5222 	int port_type = -1;
5223 	uint16_t cap_loc;
5224 
5225 	/* Note: need to look at the port type information here */
5226 	(void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_loc);
5227 	if (cap_loc != PCI_CAP_NEXT_PTR_NULL)
5228 		port_type = pci_config_get16(handle,
5229 		    cap_loc + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
5230 
5231 	return (port_type);
5232 }
5233 
5234 /*
5235  * Return true if the devinfo node is in a PCI Express hierarchy.
5236  */
5237 static boolean_t
5238 is_pcie_fabric(dev_info_t *dip)
5239 {
5240 	dev_info_t *root = ddi_root_node();
5241 	dev_info_t *pdip;
5242 	boolean_t found = B_FALSE;
5243 	char *bus;
5244 
5245 	/*
5246 	 * Does this device reside in a pcie fabric ?
5247 	 */
5248 	for (pdip = dip; pdip && (pdip != root) && !found;
5249 	    pdip = ddi_get_parent(pdip)) {
5250 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
5251 		    DDI_PROP_DONTPASS, "device_type", &bus) !=
5252 		    DDI_PROP_SUCCESS)
5253 			break;
5254 
5255 		if (strcmp(bus, "pciex") == 0)
5256 			found = B_TRUE;
5257 
5258 		ddi_prop_free(bus);
5259 	}
5260 
5261 	return (found);
5262 }
5263