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