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