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