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