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