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