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