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