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