xref: /illumos-gate/usr/src/uts/sun4/io/pcicfg.c (revision 698f4ab6008be205f4362675967638572eef4f21)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2019 Joyent, Inc.
24  */
25 
26 /*
27  *     PCI configurator (pcicfg)
28  */
29 
30 #include <sys/isa_defs.h>
31 
32 #include <sys/conf.h>
33 #include <sys/kmem.h>
34 #include <sys/debug.h>
35 #include <sys/modctl.h>
36 #include <sys/autoconf.h>
37 #include <sys/hwconf.h>
38 #include <sys/ddi_impldefs.h>
39 #include <sys/fcode.h>
40 #include <sys/pci.h>
41 #include <sys/pcie.h>
42 #include <sys/pcie_impl.h>
43 #include <sys/ddi.h>
44 #include <sys/sunddi.h>
45 #include <sys/sunndi.h>
46 #include <sys/pci_cap.h>
47 #include <sys/hotplug/pci/pcicfg.h>
48 #include <sys/ndi_impldefs.h>
49 #include <sys/pci_cfgacc.h>
50 
51 #define	PCICFG_DEVICE_TYPE_PCI	1
52 #define	PCICFG_DEVICE_TYPE_PCIE	2
53 
54 #define	EFCODE21554	/* changes for supporting 21554 */
55 
56 static int pcicfg_alloc_resource(dev_info_t *, pci_regspec_t);
57 static int pcicfg_free_resource(dev_info_t *, pci_regspec_t, pcicfg_flags_t);
58 static int pcicfg_remove_assigned_prop(dev_info_t *, pci_regspec_t *);
59 
60 #ifdef	PCICFG_INTERPRET_FCODE
61 static int pcicfg_fcode_assign_bars(ddi_acc_handle_t, dev_info_t *,
62     uint_t, uint_t, uint_t, int32_t, pci_regspec_t *);
63 #endif	/* PCICFG_INTERPRET_FCODE */
64 
65 /*
66  * ************************************************************************
67  * *** Implementation specific local data structures/definitions.	***
68  * ************************************************************************
69  */
70 
71 static	int	pcicfg_start_devno = 0;	/* for Debug only */
72 
73 #define	PCICFG_MAX_DEVICE 32
74 #define	PCICFG_MAX_FUNCTION 8
75 #define	PCICFG_MAX_ARI_FUNCTION 256
76 #define	PCICFG_MAX_REGISTER 64
77 #define	PCICFG_MAX_BUS_DEPTH 255
78 
79 #define	PCICFG_NODEVICE 42
80 #define	PCICFG_NOMEMORY 43
81 #define	PCICFG_NOMULTI	44
82 
83 #define	PCICFG_HIADDR(n) ((uint32_t)(((uint64_t)(n) & 0xFFFFFFFF00000000)>> 32))
84 #define	PCICFG_LOADDR(n) ((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
85 #define	PCICFG_LADDR(lo, hi)	(((uint64_t)(hi) << 32) | (uint32_t)(lo))
86 
87 #define	PCICFG_HIWORD(n) ((uint16_t)(((uint32_t)(n) & 0xFFFF0000)>> 16))
88 #define	PCICFG_LOWORD(n) ((uint16_t)((uint32_t)(n) & 0x0000FFFF))
89 #define	PCICFG_HIBYTE(n) ((uint8_t)(((uint16_t)(n) & 0xFF00)>> 8))
90 #define	PCICFG_LOBYTE(n) ((uint8_t)((uint16_t)(n) & 0x00FF))
91 
92 #define	PCICFG_ROUND_UP(addr, gran) ((uintptr_t)((gran+addr-1)&(~(gran-1))))
93 #define	PCICFG_ROUND_DOWN(addr, gran) ((uintptr_t)((addr) & ~(gran-1)))
94 
95 #define	PCICFG_MEMGRAN 0x100000
96 #define	PCICFG_IOGRAN 0x1000
97 #define	PCICFG_4GIG_LIMIT 0xFFFFFFFFUL
98 
99 #define	PCICFG_MEM_MULT 4
100 #define	PCICFG_IO_MULT 4
101 #define	PCICFG_RANGE_LEN 2 /* Number of range entries */
102 
103 static int pcicfg_slot_busnums = 8;
104 static int pcicfg_slot_memsize = 32 * PCICFG_MEMGRAN; /* 32MB per slot */
105 static int pcicfg_slot_iosize = 16 * PCICFG_IOGRAN; /* 64K per slot */
106 static int pcicfg_chassis_per_tree = 1;
107 static int pcicfg_sec_reset_delay = 1000000;
108 
109 /*
110  * The following typedef is used to represent a
111  * 1275 "bus-range" property of a PCI Bus node.
112  * DAF - should be in generic include file...
113  */
114 
115 typedef struct pcicfg_bus_range {
116 	uint32_t lo;
117 	uint32_t hi;
118 } pcicfg_bus_range_t;
119 
120 typedef struct pcicfg_range {
121 
122 	uint32_t child_hi;
123 	uint32_t child_mid;
124 	uint32_t child_lo;
125 	uint32_t parent_hi;
126 	uint32_t parent_mid;
127 	uint32_t parent_lo;
128 	uint32_t size_hi;
129 	uint32_t size_lo;
130 
131 } pcicfg_range_t;
132 
133 typedef struct hole hole_t;
134 
135 struct hole {
136 	uint64_t	start;
137 	uint64_t	len;
138 	hole_t		*next;
139 };
140 
141 typedef struct pcicfg_phdl pcicfg_phdl_t;
142 
143 struct pcicfg_phdl {
144 
145 	dev_info_t	*dip;		/* Associated with the attach point */
146 	pcicfg_phdl_t	*next;
147 
148 	uint64_t	memory_base;	/* Memory base for this attach point */
149 	uint64_t	memory_last;
150 	uint64_t	memory_len;
151 	uint32_t	io_base;	/* I/O base for this attach point */
152 	uint32_t	io_last;
153 	uint32_t	io_len;
154 
155 	int		error;
156 	uint_t		highest_bus;	/* Highest bus seen on the probe */
157 
158 	hole_t		mem_hole;	/* Memory hole linked list. */
159 	hole_t		io_hole;	/* IO hole linked list */
160 
161 	ndi_ra_request_t mem_req;	/* allocator request for memory */
162 	ndi_ra_request_t io_req;	/* allocator request for I/O */
163 };
164 
165 struct pcicfg_standard_prop_entry {
166     uchar_t *name;
167     uint_t  config_offset;
168     uint_t  size;
169 };
170 
171 
172 struct pcicfg_name_entry {
173     uint32_t class_code;
174     char  *name;
175 };
176 
177 struct pcicfg_find_ctrl {
178 	uint_t		device;
179 	uint_t		function;
180 	dev_info_t	*dip;
181 };
182 
183 typedef struct pcicfg_err_regs {
184 	uint16_t cmd;
185 	uint16_t bcntl;
186 	uint16_t pcie_dev;
187 	uint16_t devctl;
188 	uint16_t pcie_cap_off;
189 } pcicfg_err_regs_t;
190 
191 /*
192  * List of Indirect Config Map Devices. At least the intent of the
193  * design is to look for a device in this list during the configure
194  * operation, and if the device is listed here, then it is a nontransparent
195  * bridge, hence load the driver and avail the config map services from
196  * the driver. Class and Subclass should be as defined in the PCI specs
197  * ie. class is 0x6, and subclass is 0x9.
198  */
199 static struct {
200 	uint8_t		mem_range_bar_offset;
201 	uint8_t		io_range_bar_offset;
202 	uint8_t		prefetch_mem_range_bar_offset;
203 } pcicfg_indirect_map_devs[] = {
204 	PCI_CONF_BASE3, PCI_CONF_BASE2, PCI_CONF_BASE3,
205 	0,	0,	0,
206 };
207 
208 #define	PCICFG_MAKE_REG_HIGH(busnum, devnum, funcnum, register)\
209 	(\
210 	((ulong_t)(busnum & 0xff) << 16)    |\
211 	((ulong_t)(devnum & 0x1f) << 11)    |\
212 	((ulong_t)(funcnum & 0x7) <<  8)    |\
213 	((ulong_t)(register & 0x3f)))
214 
215 /*
216  * debug macros:
217  */
218 #if	defined(DEBUG)
219 extern void prom_printf(const char *, ...);
220 
221 /*
222  * Following values are defined for this debug flag.
223  *
224  * 1 = dump configuration header only.
225  * 2 = dump generic debug data only (no config header dumped)
226  * 3 = dump everything (both 1 and 2)
227  */
228 int pcicfg_debug = 0;
229 int pcicfg_dump_fcode = 0;
230 
231 static void debug(char *, uintptr_t, uintptr_t,
232 	uintptr_t, uintptr_t, uintptr_t);
233 
234 #define	DEBUG0(fmt)\
235 	debug(fmt, 0, 0, 0, 0, 0);
236 #define	DEBUG1(fmt, a1)\
237 	debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
238 #define	DEBUG2(fmt, a1, a2)\
239 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
240 #define	DEBUG3(fmt, a1, a2, a3)\
241 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
242 		(uintptr_t)(a3), 0, 0);
243 #define	DEBUG4(fmt, a1, a2, a3, a4)\
244 	debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
245 		(uintptr_t)(a3), (uintptr_t)(a4), 0);
246 #else
247 #define	DEBUG0(fmt)
248 #define	DEBUG1(fmt, a1)
249 #define	DEBUG2(fmt, a1, a2)
250 #define	DEBUG3(fmt, a1, a2, a3)
251 #define	DEBUG4(fmt, a1, a2, a3, a4)
252 #endif
253 
254 #ifdef PCICFG_INTERPRET_FCODE
255 int pcicfg_dont_interpret = 0;
256 #else
257 int pcicfg_dont_interpret = 1;
258 #endif
259 
260 /*
261  * forward declarations for routines defined in this module (called here)
262  */
263 
264 static int pcicfg_add_config_reg(dev_info_t *,
265     uint_t, uint_t, uint_t);
266 static int pcicfg_probe_children(dev_info_t *, uint_t, uint_t, uint_t,
267     uint_t *, pcicfg_flags_t, boolean_t);
268 
269 #ifdef PCICFG_INTERPRET_FCODE
270 static int pcicfg_load_fcode(dev_info_t *, uint_t, uint_t, uint_t,
271 	uint16_t, uint16_t, uchar_t **, int *, int, int);
272 #endif
273 
274 static int pcicfg_fcode_probe(dev_info_t *, uint_t, uint_t, uint_t,
275     uint_t *, pcicfg_flags_t, boolean_t);
276 static int pcicfg_probe_bridge(dev_info_t *, ddi_acc_handle_t, uint_t,
277     uint_t *, boolean_t);
278 static int pcicfg_free_all_resources(dev_info_t *);
279 static int pcicfg_alloc_new_resources(dev_info_t *);
280 static int pcicfg_match_dev(dev_info_t *, void *);
281 static dev_info_t *pcicfg_devi_find(dev_info_t *, uint_t, uint_t);
282 static pcicfg_phdl_t *pcicfg_find_phdl(dev_info_t *);
283 static pcicfg_phdl_t *pcicfg_create_phdl(dev_info_t *);
284 static int pcicfg_destroy_phdl(dev_info_t *);
285 static int pcicfg_sum_resources(dev_info_t *, void *);
286 static int pcicfg_find_resource_end(dev_info_t *, void *);
287 static int pcicfg_allocate_chunk(dev_info_t *);
288 static int pcicfg_program_ap(dev_info_t *);
289 static int pcicfg_device_assign(dev_info_t *);
290 static int pcicfg_bridge_assign(dev_info_t *, void *);
291 static int pcicfg_device_assign_readonly(dev_info_t *);
292 static int pcicfg_free_resources(dev_info_t *, pcicfg_flags_t);
293 static void pcicfg_setup_bridge(pcicfg_phdl_t *, ddi_acc_handle_t,
294     dev_info_t *);
295 static void pcicfg_update_bridge(pcicfg_phdl_t *, ddi_acc_handle_t);
296 static void pcicfg_enable_bridge_probe_err(dev_info_t *dip,
297 				ddi_acc_handle_t h, pcicfg_err_regs_t *regs);
298 static void pcicfg_disable_bridge_probe_err(dev_info_t *dip,
299 				ddi_acc_handle_t h, pcicfg_err_regs_t *regs);
300 static int pcicfg_update_assigned_prop(dev_info_t *, pci_regspec_t *);
301 static void pcicfg_device_on(ddi_acc_handle_t);
302 static void pcicfg_device_off(ddi_acc_handle_t);
303 static int pcicfg_set_busnode_props(dev_info_t *, uint8_t, int, int);
304 static int pcicfg_free_bridge_resources(dev_info_t *);
305 static int pcicfg_free_device_resources(dev_info_t *, pcicfg_flags_t);
306 static int pcicfg_teardown_device(dev_info_t *, pcicfg_flags_t, boolean_t);
307 static int pcicfg_config_setup(dev_info_t *, ddi_acc_handle_t *);
308 static void pcicfg_config_teardown(ddi_acc_handle_t *);
309 static void pcicfg_get_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
310 static void pcicfg_get_io(pcicfg_phdl_t *, uint32_t, uint32_t *);
311 static int pcicfg_update_ranges_prop(dev_info_t *, pcicfg_range_t *);
312 static int pcicfg_map_phys(dev_info_t *, pci_regspec_t *, caddr_t *,
313     ddi_device_acc_attr_t *, ddi_acc_handle_t *);
314 static void pcicfg_unmap_phys(ddi_acc_handle_t *, pci_regspec_t *);
315 static int pcicfg_dump_assigned(dev_info_t *);
316 static uint_t pcicfg_configure_ntbridge(dev_info_t *, uint_t, uint_t);
317 static int pcicfg_indirect_map(dev_info_t *dip);
318 static uint_t pcicfg_get_ntbridge_child_range(dev_info_t *, uint64_t *,
319 				uint64_t *, uint_t);
320 static int pcicfg_is_ntbridge(dev_info_t *);
321 static int pcicfg_ntbridge_allocate_resources(dev_info_t *);
322 static int pcicfg_ntbridge_configure_done(dev_info_t *);
323 static int pcicfg_ntbridge_unconfigure(dev_info_t *);
324 static int pcicfg_ntbridge_unconfigure_child(dev_info_t *, uint_t);
325 static void pcicfg_free_hole(hole_t *);
326 static uint64_t pcicfg_alloc_hole(hole_t *, uint64_t *, uint32_t);
327 static int pcicfg_update_available_prop(dev_info_t *, pci_regspec_t *);
328 static int pcicfg_ari_configure(dev_info_t *);
329 static int pcicfg_populate_reg_props(dev_info_t *, ddi_acc_handle_t);
330 static int pcicfg_populate_props_from_bar(dev_info_t *, ddi_acc_handle_t);
331 static int pcicfg_update_assigned_prop_value(dev_info_t *, uint32_t,
332     uint32_t, uint32_t, uint_t);
333 static boolean_t is_pcie_fabric(dev_info_t *dip);
334 
335 #ifdef DEBUG
336 static void pcicfg_dump_common_config(ddi_acc_handle_t config_handle);
337 static void pcicfg_dump_device_config(ddi_acc_handle_t);
338 
339 static void pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle);
340 static uint64_t pcicfg_unused_space(hole_t *, uint32_t *);
341 
342 #define	PCICFG_DUMP_COMMON_CONFIG(hdl) (void)pcicfg_dump_common_config(hdl)
343 #define	PCICFG_DUMP_DEVICE_CONFIG(hdl) (void)pcicfg_dump_device_config(hdl)
344 #define	PCICFG_DUMP_BRIDGE_CONFIG(hdl) (void)pcicfg_dump_bridge_config(hdl)
345 #else
346 #define	PCICFG_DUMP_COMMON_CONFIG(handle)
347 #define	PCICFG_DUMP_DEVICE_CONFIG(handle)
348 #define	PCICFG_DUMP_BRIDGE_CONFIG(handle)
349 #endif
350 
351 static kmutex_t pcicfg_list_mutex; /* Protects the probe handle list */
352 static pcicfg_phdl_t *pcicfg_phdl_list = NULL;
353 
354 #ifndef _DONT_USE_1275_GENERIC_NAMES
355 /*
356  * Class code table
357  */
358 static struct pcicfg_name_entry pcicfg_class_lookup [] = {
359 
360 	{ 0x001, "display" },
361 	{ 0x100, "scsi" },
362 	{ 0x101, "ide" },
363 	{ 0x102, "fdc" },
364 	{ 0x103, "ipi" },
365 	{ 0x104, "raid" },
366 	{ 0x200, "ethernet" },
367 	{ 0x201, "token-ring" },
368 	{ 0x202, "fddi" },
369 	{ 0x203, "atm" },
370 	{ 0x300, "display" },
371 	{ 0x400, "video" },
372 	{ 0x401, "sound" },
373 	{ 0x500, "memory" },
374 	{ 0x501, "flash" },
375 	{ 0x600, "host" },
376 	{ 0x601, "isa" },
377 	{ 0x602, "eisa" },
378 	{ 0x603, "mca" },
379 	{ 0x604, "pci" },
380 	{ 0x605, "pcmcia" },
381 	{ 0x606, "nubus" },
382 	{ 0x607, "cardbus" },
383 	{ 0x609, "pci" },
384 	{ 0x700, "serial" },
385 	{ 0x701, "parallel" },
386 	{ 0x800, "interrupt-controller" },
387 	{ 0x801, "dma-controller" },
388 	{ 0x802, "timer" },
389 	{ 0x803, "rtc" },
390 	{ 0x900, "keyboard" },
391 	{ 0x901, "pen" },
392 	{ 0x902, "mouse" },
393 	{ 0xa00, "dock" },
394 	{ 0xb00, "cpu" },
395 	{ 0xc00, "firewire" },
396 	{ 0xc01, "access-bus" },
397 	{ 0xc02, "ssa" },
398 	{ 0xc03, "usb" },
399 	{ 0xc04, "fibre-channel" },
400 	{ 0, 0 }
401 };
402 #endif /* _DONT_USE_1275_GENERIC_NAMES */
403 
404 /*
405  * Module control operations
406  */
407 
408 extern struct mod_ops mod_miscops;
409 
410 static struct modlmisc modlmisc = {
411 	&mod_miscops, /* Type of module */
412 	"PCIe/PCI Config (EFCode Enabled)"
413 };
414 
415 static struct modlinkage modlinkage = {
416 	MODREV_1, (void *)&modlmisc, NULL
417 };
418 
419 #ifdef DEBUG
420 
421 static void
422 pcicfg_dump_common_config(ddi_acc_handle_t config_handle)
423 {
424 	if ((pcicfg_debug & 1) == 0)
425 		return;
426 	cmn_err(CE_CONT, " Vendor ID   = [0x%x]\n",
427 	    pci_config_get16(config_handle, PCI_CONF_VENID));
428 	cmn_err(CE_CONT, " Device ID   = [0x%x]\n",
429 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
430 	cmn_err(CE_CONT, " Command REG = [0x%x]\n",
431 	    pci_config_get16(config_handle, PCI_CONF_COMM));
432 	cmn_err(CE_CONT, " Status  REG = [0x%x]\n",
433 	    pci_config_get16(config_handle, PCI_CONF_STAT));
434 	cmn_err(CE_CONT, " Revision ID = [0x%x]\n",
435 	    pci_config_get8(config_handle, PCI_CONF_REVID));
436 	cmn_err(CE_CONT, " Prog Class  = [0x%x]\n",
437 	    pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
438 	cmn_err(CE_CONT, " Dev Class   = [0x%x]\n",
439 	    pci_config_get8(config_handle, PCI_CONF_SUBCLASS));
440 	cmn_err(CE_CONT, " Base Class  = [0x%x]\n",
441 	    pci_config_get8(config_handle, PCI_CONF_BASCLASS));
442 	cmn_err(CE_CONT, " Device ID   = [0x%x]\n",
443 	    pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ));
444 	cmn_err(CE_CONT, " Header Type = [0x%x]\n",
445 	    pci_config_get8(config_handle, PCI_CONF_HEADER));
446 	cmn_err(CE_CONT, " BIST        = [0x%x]\n",
447 	    pci_config_get8(config_handle, PCI_CONF_BIST));
448 	cmn_err(CE_CONT, " BASE 0      = [0x%x]\n",
449 	    pci_config_get32(config_handle, PCI_CONF_BASE0));
450 	cmn_err(CE_CONT, " BASE 1      = [0x%x]\n",
451 	    pci_config_get32(config_handle, PCI_CONF_BASE1));
452 
453 }
454 
455 static void
456 pcicfg_dump_device_config(ddi_acc_handle_t config_handle)
457 {
458 	if ((pcicfg_debug & 1) == 0)
459 		return;
460 	pcicfg_dump_common_config(config_handle);
461 
462 	cmn_err(CE_CONT, " BASE 2      = [0x%x]\n",
463 	    pci_config_get32(config_handle, PCI_CONF_BASE2));
464 	cmn_err(CE_CONT, " BASE 3      = [0x%x]\n",
465 	    pci_config_get32(config_handle, PCI_CONF_BASE3));
466 	cmn_err(CE_CONT, " BASE 4      = [0x%x]\n",
467 	    pci_config_get32(config_handle, PCI_CONF_BASE4));
468 	cmn_err(CE_CONT, " BASE 5      = [0x%x]\n",
469 	    pci_config_get32(config_handle, PCI_CONF_BASE5));
470 	cmn_err(CE_CONT, " Cardbus CIS = [0x%x]\n",
471 	    pci_config_get32(config_handle, PCI_CONF_CIS));
472 	cmn_err(CE_CONT, " Sub VID     = [0x%x]\n",
473 	    pci_config_get16(config_handle, PCI_CONF_SUBVENID));
474 	cmn_err(CE_CONT, " Sub SID     = [0x%x]\n",
475 	    pci_config_get16(config_handle, PCI_CONF_SUBSYSID));
476 	cmn_err(CE_CONT, " ROM         = [0x%x]\n",
477 	    pci_config_get32(config_handle, PCI_CONF_ROM));
478 	cmn_err(CE_CONT, " I Line      = [0x%x]\n",
479 	    pci_config_get8(config_handle, PCI_CONF_ILINE));
480 	cmn_err(CE_CONT, " I Pin       = [0x%x]\n",
481 	    pci_config_get8(config_handle, PCI_CONF_IPIN));
482 	cmn_err(CE_CONT, " Max Grant   = [0x%x]\n",
483 	    pci_config_get8(config_handle, PCI_CONF_MIN_G));
484 	cmn_err(CE_CONT, " Max Latent  = [0x%x]\n",
485 	    pci_config_get8(config_handle, PCI_CONF_MAX_L));
486 }
487 
488 static void
489 pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle)
490 {
491 	if ((pcicfg_debug & 1) == 0)
492 		return;
493 
494 	pcicfg_dump_common_config(config_handle);
495 
496 	cmn_err(CE_CONT, "........................................\n");
497 
498 	cmn_err(CE_CONT, " Pri Bus     = [0x%x]\n",
499 	    pci_config_get8(config_handle, PCI_BCNF_PRIBUS));
500 	cmn_err(CE_CONT, " Sec Bus     = [0x%x]\n",
501 	    pci_config_get8(config_handle, PCI_BCNF_SECBUS));
502 	cmn_err(CE_CONT, " Sub Bus     = [0x%x]\n",
503 	    pci_config_get8(config_handle, PCI_BCNF_SUBBUS));
504 	cmn_err(CE_CONT, " Latency     = [0x%x]\n",
505 	    pci_config_get8(config_handle, PCI_BCNF_LATENCY_TIMER));
506 	cmn_err(CE_CONT, " I/O Base LO = [0x%x]\n",
507 	    pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW));
508 	cmn_err(CE_CONT, " I/O Lim LO  = [0x%x]\n",
509 	    pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW));
510 	cmn_err(CE_CONT, " Sec. Status = [0x%x]\n",
511 	    pci_config_get16(config_handle, PCI_BCNF_SEC_STATUS));
512 	cmn_err(CE_CONT, " Mem Base    = [0x%x]\n",
513 	    pci_config_get16(config_handle, PCI_BCNF_MEM_BASE));
514 	cmn_err(CE_CONT, " Mem Limit   = [0x%x]\n",
515 	    pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT));
516 	cmn_err(CE_CONT, " PF Mem Base = [0x%x]\n",
517 	    pci_config_get16(config_handle, PCI_BCNF_PF_BASE_LOW));
518 	cmn_err(CE_CONT, " PF Mem Lim  = [0x%x]\n",
519 	    pci_config_get16(config_handle, PCI_BCNF_PF_LIMIT_LOW));
520 	cmn_err(CE_CONT, " PF Base HI  = [0x%x]\n",
521 	    pci_config_get32(config_handle, PCI_BCNF_PF_BASE_HIGH));
522 	cmn_err(CE_CONT, " PF Lim  HI  = [0x%x]\n",
523 	    pci_config_get32(config_handle, PCI_BCNF_PF_LIMIT_HIGH));
524 	cmn_err(CE_CONT, " I/O Base HI = [0x%x]\n",
525 	    pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI));
526 	cmn_err(CE_CONT, " I/O Lim HI  = [0x%x]\n",
527 	    pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI));
528 	cmn_err(CE_CONT, " ROM addr    = [0x%x]\n",
529 	    pci_config_get32(config_handle, PCI_BCNF_ROM));
530 	cmn_err(CE_CONT, " Intr Line   = [0x%x]\n",
531 	    pci_config_get8(config_handle, PCI_BCNF_ILINE));
532 	cmn_err(CE_CONT, " Intr Pin    = [0x%x]\n",
533 	    pci_config_get8(config_handle, PCI_BCNF_IPIN));
534 	cmn_err(CE_CONT, " Bridge Ctrl = [0x%x]\n",
535 	    pci_config_get16(config_handle, PCI_BCNF_BCNTRL));
536 }
537 
538 #endif
539 
540 
541 int
542 _init()
543 {
544 	DEBUG0("PCI configurator installed - Fcode Interpretation/21554\n");
545 
546 	mutex_init(&pcicfg_list_mutex, NULL, MUTEX_DRIVER, NULL);
547 	return (mod_install(&modlinkage));
548 }
549 
550 int
551 _fini(void)
552 {
553 	int error;
554 
555 	error = mod_remove(&modlinkage);
556 	if (error != 0) {
557 		return (error);
558 	}
559 	mutex_destroy(&pcicfg_list_mutex);
560 	return (0);
561 }
562 
563 int
564 _info(struct modinfo *modinfop)
565 {
566 	return (mod_info(&modlinkage, modinfop));
567 }
568 
569 /*ARGSUSED*/
570 static uint8_t
571 pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle)
572 {
573 	uint8_t num_slots = 0;
574 	uint16_t cap_ptr;
575 
576 	if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_HOTPLUG,
577 	    &cap_ptr)) == DDI_SUCCESS) {
578 		uint32_t config;
579 
580 		PCI_CAP_PUT8(handle, NULL, cap_ptr, PCI_HP_DWORD_SELECT_OFF,
581 		    PCI_HP_SLOT_CONFIGURATION_REG);
582 		config = PCI_CAP_GET32(handle, NULL, cap_ptr,
583 		    PCI_HP_DWORD_DATA_OFF);
584 		num_slots = config & 0x1F;
585 	} else if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &cap_ptr))
586 	    == DDI_SUCCESS) {
587 		uint8_t esr_reg = PCI_CAP_GET8(handle, NULL,
588 		    cap_ptr, PCI_CAP_ID_REGS_OFF);
589 
590 		num_slots = PCI_CAPSLOT_NSLOTS(esr_reg);
591 	} else if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_ptr))
592 	    == DDI_SUCCESS) {
593 		int port_type = PCI_CAP_GET16(handle, NULL, cap_ptr,
594 		    PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
595 
596 		if ((port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) &&
597 		    (PCI_CAP_GET16(handle, NULL, cap_ptr, PCIE_PCIECAP)
598 		    & PCIE_PCIECAP_SLOT_IMPL))
599 				num_slots = 1;
600 	}
601 
602 	DEBUG3("%s#%d has %d slots",
603 	    ddi_get_name(dip), ddi_get_instance(dip), num_slots);
604 
605 	return (num_slots);
606 }
607 
608 /*ARGSUSED*/
609 static uint8_t
610 pcicfg_is_chassis(dev_info_t *dip, ddi_acc_handle_t handle)
611 {
612 	uint16_t cap_ptr;
613 
614 	if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &cap_ptr)) !=
615 	    DDI_FAILURE) {
616 
617 		uint8_t esr_reg = PCI_CAP_GET8(handle, NULL, cap_ptr, 2);
618 		if (PCI_CAPSLOT_FIC(esr_reg))
619 			return (B_TRUE);
620 	}
621 	return (B_FALSE);
622 }
623 
624 /*ARGSUSED*/
625 static int
626 pcicfg_pcie_dev(dev_info_t *dip, int bus_type, pcicfg_err_regs_t *regs)
627 {
628 	/* get parent device's device_type property */
629 	char *device_type;
630 	int rc = DDI_FAILURE;
631 	dev_info_t *pdip = ddi_get_parent(dip);
632 
633 	regs->pcie_dev = 0;
634 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
635 	    DDI_PROP_DONTPASS, "device_type", &device_type)
636 	    != DDI_PROP_SUCCESS) {
637 		DEBUG2("device_type property missing for %s#%d",
638 		    ddi_get_name(pdip), ddi_get_instance(pdip));
639 		return (DDI_FAILURE);
640 	}
641 	switch (bus_type) {
642 		case PCICFG_DEVICE_TYPE_PCIE:
643 			if (strcmp(device_type, "pciex") == 0) {
644 				rc = DDI_SUCCESS;
645 				regs->pcie_dev = 1;
646 			}
647 			break;
648 		case PCICFG_DEVICE_TYPE_PCI:
649 			if (strcmp(device_type, "pci") == 0)
650 				rc = DDI_SUCCESS;
651 			break;
652 		default:
653 			break;
654 	}
655 	ddi_prop_free(device_type);
656 	return (rc);
657 }
658 
659 /*ARGSUSED*/
660 static int
661 pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
662 {
663 	int port_type = -1;
664 	uint16_t cap_ptr;
665 
666 	if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_ptr)) !=
667 	    DDI_FAILURE)
668 		port_type = PCI_CAP_GET16(handle, NULL,
669 		    cap_ptr, PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
670 
671 	return (port_type);
672 }
673 
674 static int
675 pcicfg_pcie_device_type(dev_info_t *dip, ddi_acc_handle_t handle)
676 {
677 	int port_type = pcicfg_pcie_port_type(dip, handle);
678 
679 	DEBUG1("device port_type = %x\n", port_type);
680 	/* No PCIe CAP regs, we are not PCIe device_type */
681 	if (port_type < 0)
682 		return (DDI_FAILURE);
683 
684 	/* check for all PCIe device_types */
685 	if ((port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
686 	    (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) ||
687 	    (port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
688 	    (port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE))
689 		return (DDI_SUCCESS);
690 
691 	return (DDI_FAILURE);
692 
693 }
694 
695 /*
696  * In the following functions ndi_devi_enter() without holding the
697  * parent dip is sufficient. This is because  pci dr is driven through
698  * opens on the nexus which is in the device tree path above the node
699  * being operated on, and implicitly held due to the open.
700  */
701 
702 /*
703  * This entry point is called to configure a device (and
704  * all its children) on the given bus. It is called when
705  * a new device is added to the PCI domain.  This routine
706  * will create the device tree and program the devices
707  * registers.
708  */
709 
710 int
711 pcicfg_configure(dev_info_t *devi, uint_t device, uint_t function,
712     pcicfg_flags_t flags)
713 {
714 	uint_t bus;
715 	int len;
716 	int func;
717 	int trans_device;
718 	dev_info_t *new_device;
719 	pcicfg_bus_range_t pci_bus_range;
720 	int rv;
721 	int circ;
722 	uint_t highest_bus = 0;
723 	int ari_mode = B_FALSE;
724 	int max_function = PCICFG_MAX_FUNCTION;
725 	boolean_t is_pcie;
726 
727 	if (flags == PCICFG_FLAG_ENABLE_ARI)
728 		return (pcicfg_ari_configure(devi));
729 
730 	/*
731 	 * Start probing at the device specified in "device" on the
732 	 * "bus" specified.
733 	 */
734 	len = sizeof (pcicfg_bus_range_t);
735 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
736 	    "bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
737 		DEBUG0("no bus-range property\n");
738 		return (PCICFG_FAILURE);
739 	}
740 
741 	bus = pci_bus_range.lo; /* primary bus number of this bus node */
742 
743 	is_pcie = is_pcie_fabric(devi);
744 
745 	ndi_devi_enter(devi, &circ);
746 	for (func = 0; func < max_function; ) {
747 		if ((function != PCICFG_ALL_FUNC) && (function != func))
748 			goto next;
749 
750 		if (ari_mode)
751 			trans_device = func >> 3;
752 		else
753 			trans_device = device;
754 
755 		DEBUG3("Configuring [0x%x][0x%x][0x%x]\n",
756 		    bus, trans_device, func & 7);
757 
758 		/*
759 		 * Try executing fcode if available.
760 		 */
761 		switch (rv = pcicfg_fcode_probe(devi, bus, trans_device,
762 		    func & 7, &highest_bus, flags, is_pcie)) {
763 			case PCICFG_FAILURE:
764 				DEBUG2("configure failed: "
765 				    "bus [0x%x] device [0x%x]\n",
766 				    bus, trans_device);
767 				break;
768 			case PCICFG_NODEVICE:
769 				DEBUG3("no device : bus "
770 				    "[0x%x] slot [0x%x] func [0x%x]\n",
771 				    bus, trans_device, func & 7);
772 
773 				/*
774 				 * When walking the list of ARI functions
775 				 * we don't expect to see a non-present
776 				 * function, so we will stop walking
777 				 * the function list.
778 				 */
779 				if (ari_mode == B_TRUE)
780 					break;
781 
782 				if (func)
783 					goto next;
784 				break;
785 			default:
786 				DEBUG3("configure: bus => [%d] "
787 				    "slot => [%d] func => [%d]\n",
788 				    bus, trans_device, func & 7);
789 				break;
790 		}
791 
792 		if (rv != PCICFG_SUCCESS)
793 			break;
794 
795 		if ((new_device = pcicfg_devi_find(devi,
796 		    trans_device, (func & 7))) == NULL) {
797 			DEBUG0("Did'nt find device node just created\n");
798 			goto cleanup;
799 		}
800 
801 next:
802 		/*
803 		 * Determine if ARI Forwarding should be enabled.
804 		 */
805 		if (func == 0) {
806 			if ((pcie_ari_supported(devi)
807 			    == PCIE_ARI_FORW_SUPPORTED) &&
808 			    (pcie_ari_device(new_device) == PCIE_ARI_DEVICE)) {
809 				if (pcie_ari_enable(devi) == DDI_SUCCESS) {
810 					(void) ddi_prop_create(DDI_DEV_T_NONE,
811 					    devi,  DDI_PROP_CANSLEEP,
812 					    "ari-enabled", NULL, 0);
813 
814 					ari_mode = B_TRUE;
815 					max_function = PCICFG_MAX_ARI_FUNCTION;
816 				}
817 			}
818 		}
819 
820 		if (ari_mode == B_TRUE) {
821 			int next_function;
822 
823 			DEBUG0("Next Function - ARI Device\n");
824 			if (pcie_ari_get_next_function(new_device,
825 			    &next_function) != DDI_SUCCESS)
826 				goto cleanup;
827 
828 			/*
829 			 * Check if there are more fucntions to probe.
830 			 */
831 			if (next_function == 0) {
832 				DEBUG0("Next Function - "
833 				    "No more ARI Functions\n");
834 				break;
835 			}
836 			func = next_function;
837 		} else {
838 			func++;
839 		}
840 
841 		DEBUG1("Next Function - %x\n", func);
842 	}
843 
844 	ndi_devi_exit(devi, circ);
845 
846 	if (func == 0)
847 		return (PCICFG_FAILURE);	/* probe failed */
848 	else
849 		return (PCICFG_SUCCESS);
850 
851 cleanup:
852 	/*
853 	 * Clean up a partially created "probe state" tree.
854 	 * There are no resources allocated to the in the
855 	 * probe state.
856 	 */
857 	if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED)
858 		max_function = PCICFG_MAX_ARI_FUNCTION;
859 	else
860 		max_function = PCICFG_MAX_FUNCTION;
861 
862 	for (func = 0; func < max_function; func++) {
863 
864 		if (max_function == PCICFG_MAX_ARI_FUNCTION)
865 			trans_device = func >> 3; /* ARI Device */
866 		else
867 			trans_device = device;
868 
869 		if ((new_device = pcicfg_devi_find(devi,
870 		    trans_device, (func & 0x7))) == NULL) {
871 			DEBUG0("No more devices to clean up\n");
872 			continue;
873 		}
874 
875 		DEBUG2("Cleaning up device [0x%x] function [0x%x]\n",
876 		    trans_device, func & 7);
877 		/*
878 		 * If this was a bridge device it will have a
879 		 * probe handle - if not, no harm in calling this.
880 		 */
881 		(void) pcicfg_destroy_phdl(new_device);
882 
883 		if (is_pcie) {
884 			/*
885 			 * Free bus_t structure
886 			 */
887 			if (ddi_get_child(new_device) != NULL)
888 				pcie_fab_fini_bus(new_device, PCIE_BUS_ALL);
889 
890 			pcie_fini_bus(new_device, PCIE_BUS_ALL);
891 		}
892 		/*
893 		 * This will free up the node
894 		 */
895 		(void) ndi_devi_offline(new_device, NDI_DEVI_REMOVE);
896 	}
897 	ndi_devi_exit(devi, circ);
898 
899 	return (PCICFG_FAILURE);
900 }
901 
902 /*
903  * configure the child nodes of ntbridge. new_device points to ntbridge itself
904  */
905 /*ARGSUSED*/
906 static uint_t
907 pcicfg_configure_ntbridge(dev_info_t *new_device, uint_t bus, uint_t device)
908 {
909 	int bus_range[2], rc = PCICFG_FAILURE, rc1, max_devs = 0;
910 	int			devno;
911 	dev_info_t		*new_ntbridgechild;
912 	ddi_acc_handle_t	config_handle;
913 	uint16_t		vid;
914 	uint64_t		next_bus;
915 	uint64_t		blen;
916 	ndi_ra_request_t	req;
917 	uint8_t			pcie_device_type = 0;
918 
919 	/*
920 	 * If we need to do indirect config, lets create a property here
921 	 * to let the child conf map routine know that it has to
922 	 * go through the DDI calls, and not assume the devices are
923 	 * mapped directly under the host.
924 	 */
925 	if ((rc = ndi_prop_update_int(DDI_DEV_T_NONE, new_device,
926 	    PCI_DEV_CONF_MAP_PROP, (int)DDI_SUCCESS))
927 	    != DDI_SUCCESS) {
928 
929 		DEBUG0("Cannot create indirect conf map property.\n");
930 		return ((uint_t)PCICFG_FAILURE);
931 	}
932 	if (pci_config_setup(new_device, &config_handle) != DDI_SUCCESS)
933 		return ((uint_t)PCICFG_FAILURE);
934 	/* check if we are PCIe device */
935 	if (pcicfg_pcie_device_type(new_device, config_handle) == DDI_SUCCESS)
936 		pcie_device_type = 1;
937 	pci_config_teardown(&config_handle);
938 
939 	/* create Bus node properties for ntbridge. */
940 	if (pcicfg_set_busnode_props(new_device, pcie_device_type, -1, -1) !=
941 	    PCICFG_SUCCESS) {
942 		DEBUG0("Failed to set busnode props\n");
943 		return (rc);
944 	}
945 
946 	/* For now: Lets only support one layer of child */
947 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
948 	req.ra_len = 1;
949 	if (ndi_ra_alloc(ddi_get_parent(new_device), &req,
950 	    &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
951 	    NDI_RA_PASS) != NDI_SUCCESS) {
952 		DEBUG0("ntbridge: Failed to get a bus number\n");
953 		return (rc);
954 	}
955 
956 	DEBUG1("ntbridge bus range start  ->[%d]\n", next_bus);
957 
958 	/*
959 	 * Following will change, as we detect more bridges
960 	 * on the way.
961 	 */
962 	bus_range[0] = (int)next_bus;
963 	bus_range[1] = (int)next_bus;
964 
965 	if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_device,
966 	    "bus-range", bus_range, 2) != DDI_SUCCESS) {
967 		DEBUG0("Cannot set ntbridge bus-range property");
968 		return (rc);
969 	}
970 
971 	/*
972 	 * The other interface (away from the host) will be
973 	 * initialized by the nexus driver when it loads.
974 	 * We just have to set the registers and the nexus driver
975 	 * figures out the rest.
976 	 */
977 
978 	/*
979 	 * finally, lets load and attach the driver
980 	 * before configuring children of ntbridge.
981 	 */
982 	rc = ndi_devi_online(new_device, NDI_NO_EVENT|NDI_CONFIG);
983 	if (rc != NDI_SUCCESS) {
984 		cmn_err(CE_WARN,
985 		    "pcicfg: Fail: can\'t load non-transparent bridge \
986 		    driver.\n");
987 		rc = PCICFG_FAILURE;
988 		return (rc);
989 	}
990 	DEBUG0("pcicfg: Success loading nontransparent bridge nexus driver..");
991 
992 	/* Now set aside pci resources for our children. */
993 	if (pcicfg_ntbridge_allocate_resources(new_device) !=
994 	    PCICFG_SUCCESS) {
995 		max_devs = 0;
996 		rc = PCICFG_FAILURE;
997 	} else
998 		max_devs = PCICFG_MAX_DEVICE;
999 
1000 	/* Probe devices on 2nd bus */
1001 	for (devno = pcicfg_start_devno; devno < max_devs; devno++) {
1002 
1003 		if (ndi_devi_alloc(new_device, DEVI_PSEUDO_NEXNAME,
1004 		    (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild)
1005 		    != NDI_SUCCESS) {
1006 
1007 			DEBUG0("pcicfg: Failed to alloc test node\n");
1008 			rc = PCICFG_FAILURE;
1009 			break;
1010 		}
1011 
1012 		if (pcicfg_add_config_reg(new_ntbridgechild, next_bus, devno, 0)
1013 		    != DDI_PROP_SUCCESS) {
1014 			cmn_err(CE_WARN,
1015 			    "Failed to add conf reg for ntbridge child.\n");
1016 			(void) ndi_devi_free(new_ntbridgechild);
1017 			rc = PCICFG_FAILURE;
1018 			break;
1019 		}
1020 
1021 		if ((rc = pci_config_setup(new_ntbridgechild,
1022 		    &config_handle)) != PCICFG_SUCCESS) {
1023 			cmn_err(CE_WARN,
1024 			    "Cannot map ntbridge child %x\n", devno);
1025 			(void) ndi_devi_free(new_ntbridgechild);
1026 			rc = PCICFG_FAILURE;
1027 			break;
1028 		}
1029 
1030 		/*
1031 		 * See if there is any PCI HW at this location
1032 		 * by reading the Vendor ID.  If it returns with 0xffff
1033 		 * then there is no hardware at this location.
1034 		 */
1035 		vid = pci_config_get16(config_handle, PCI_CONF_VENID);
1036 
1037 		pci_config_teardown(&config_handle);
1038 		(void) ndi_devi_free(new_ntbridgechild);
1039 		if (vid	== 0xffff)
1040 			continue;
1041 
1042 		/* Lets fake attachments points for each child, */
1043 		if (pcicfg_configure(new_device, devno, PCICFG_ALL_FUNC, 0)
1044 		    != PCICFG_SUCCESS) {
1045 			int old_dev = pcicfg_start_devno;
1046 
1047 			cmn_err(CE_WARN,
1048 			"Error configuring ntbridge child dev=%d\n", devno);
1049 
1050 			rc = PCICFG_FAILURE;
1051 			while (old_dev != devno) {
1052 				if (pcicfg_ntbridge_unconfigure_child(
1053 				    new_device, old_dev) == PCICFG_FAILURE)
1054 
1055 					cmn_err(CE_WARN,
1056 					    "Unconfig Error ntbridge child "
1057 					    "dev=%d\n", old_dev);
1058 				old_dev++;
1059 			}
1060 			break;
1061 		}
1062 	} /* devno loop */
1063 	DEBUG1("ntbridge: finish probing 2nd bus, rc=%d\n", rc);
1064 
1065 	if (rc != PCICFG_FAILURE)
1066 		rc = pcicfg_ntbridge_configure_done(new_device);
1067 	else {
1068 		pcicfg_phdl_t *entry = pcicfg_find_phdl(new_device);
1069 		uint_t			*bus;
1070 		int			k;
1071 
1072 		if (ddi_getlongprop(DDI_DEV_T_ANY, new_device,
1073 		    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
1074 		    &k) != DDI_PROP_SUCCESS) {
1075 			DEBUG0("Failed to read bus-range property\n");
1076 			rc = PCICFG_FAILURE;
1077 			return (rc);
1078 		}
1079 
1080 		DEBUG2("Need to free bus [%d] range [%d]\n",
1081 		    bus[0], bus[1] - bus[0] + 1);
1082 
1083 		if (ndi_ra_free(ddi_get_parent(new_device),
1084 		    (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
1085 		    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1086 			DEBUG0("Failed to free a bus number\n");
1087 			rc = PCICFG_FAILURE;
1088 			/*
1089 			 * Don't forget to free up memory from ddi_getlongprop
1090 			 */
1091 			kmem_free((caddr_t)bus, k);
1092 
1093 			return (rc);
1094 		}
1095 
1096 		/*
1097 		 * Since no memory allocations are done for non transparent
1098 		 * bridges (but instead we just set the handle with the
1099 		 * already allocated memory, we just need to reset the
1100 		 * following values before calling the destroy_phdl()
1101 		 * function next, otherwise the it will try to free
1102 		 * memory allocated as in case of a transparent bridge.
1103 		 */
1104 		entry->memory_len = 0;
1105 		entry->io_len = 0;
1106 		/* the following will free hole data. */
1107 		(void) pcicfg_destroy_phdl(new_device);
1108 		/*
1109 		 * Don't forget to free up memory from ddi_getlongprop
1110 		 */
1111 		kmem_free((caddr_t)bus, k);
1112 	}
1113 
1114 	/*
1115 	 * Unload driver just in case child configure failed!
1116 	 */
1117 	rc1 = ndi_devi_offline(new_device, NDI_NO_EVENT);
1118 	DEBUG1("pcicfg: now unloading the ntbridge driver. rc1=%d\n", rc1);
1119 	if (rc1 != NDI_SUCCESS) {
1120 		cmn_err(CE_WARN,
1121 		    "pcicfg: can\'t unload ntbridge driver children.\n");
1122 		rc = PCICFG_FAILURE;
1123 	}
1124 
1125 	return (rc);
1126 }
1127 
1128 static int
1129 pcicfg_ntbridge_allocate_resources(dev_info_t *dip)
1130 {
1131 	pcicfg_phdl_t		*phdl;
1132 	ndi_ra_request_t	*mem_request;
1133 	ndi_ra_request_t	*io_request;
1134 	uint64_t		boundbase, boundlen;
1135 
1136 	phdl = pcicfg_find_phdl(dip);
1137 	ASSERT(phdl);
1138 
1139 	mem_request = &phdl->mem_req;
1140 	io_request  = &phdl->io_req;
1141 
1142 	phdl->error = PCICFG_SUCCESS;
1143 
1144 	/* Set Memory space handle for ntbridge */
1145 	if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1146 	    PCI_BASE_SPACE_MEM) != DDI_SUCCESS) {
1147 		cmn_err(CE_WARN,
1148 		    "ntbridge: Mem resource information failure\n");
1149 		phdl->memory_len  = 0;
1150 		return (PCICFG_FAILURE);
1151 	}
1152 	mem_request->ra_boundbase = boundbase;
1153 	mem_request->ra_boundlen = boundbase + boundlen;
1154 	mem_request->ra_len = boundlen;
1155 	mem_request->ra_align_mask =
1156 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
1157 	mem_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1158 
1159 	/*
1160 	 * mem_request->ra_len =
1161 	 * PCICFG_ROUND_UP(mem_request->ra_len, PCICFG_MEMGRAN);
1162 	 */
1163 
1164 	phdl->memory_base = phdl->memory_last = boundbase;
1165 	phdl->memory_len  = boundlen;
1166 	phdl->mem_hole.start = phdl->memory_base;
1167 	phdl->mem_hole.len = mem_request->ra_len;
1168 	phdl->mem_hole.next = (hole_t *)NULL;
1169 
1170 	DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of memory\n",
1171 	    boundlen, mem_request->ra_len);
1172 
1173 	/* set up a memory resource map for NT bridge */
1174 	if (ndi_ra_map_setup(dip, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
1175 		DEBUG0("Can not setup ntbridge memory resource map\n");
1176 		return (PCICFG_FAILURE);
1177 	}
1178 	/* initialize the memory map */
1179 	if (ndi_ra_free(dip, boundbase, boundlen, NDI_RA_TYPE_MEM,
1180 	    NDI_RA_PASS) != NDI_SUCCESS) {
1181 		DEBUG0("Can not initalize ntbridge memory resource map\n");
1182 		return (PCICFG_FAILURE);
1183 	}
1184 	/* Set IO space handle for ntbridge */
1185 	if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1186 	    PCI_BASE_SPACE_IO) != DDI_SUCCESS) {
1187 		cmn_err(CE_WARN, "ntbridge: IO resource information failure\n");
1188 		phdl->io_len  = 0;
1189 		return (PCICFG_FAILURE);
1190 	}
1191 	io_request->ra_len = boundlen;
1192 	io_request->ra_align_mask =
1193 	    PCICFG_IOGRAN - 1;   /* 4K alignment on I/O space */
1194 	io_request->ra_boundbase = boundbase;
1195 	io_request->ra_boundlen = boundbase + boundlen;
1196 	io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1197 
1198 	/*
1199 	 * io_request->ra_len =
1200 	 * PCICFG_ROUND_UP(io_request->ra_len, PCICFG_IOGRAN);
1201 	 */
1202 
1203 	phdl->io_base = phdl->io_last = (uint32_t)boundbase;
1204 	phdl->io_len  = (uint32_t)boundlen;
1205 	phdl->io_hole.start = phdl->io_base;
1206 	phdl->io_hole.len = io_request->ra_len;
1207 	phdl->io_hole.next = (hole_t *)NULL;
1208 
1209 	DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of IO\n",
1210 	    boundlen, io_request->ra_len);
1211 
1212 	DEBUG2("MEMORY BASE = [0x%x] length [0x%x]\n",
1213 	    phdl->memory_base, phdl->memory_len);
1214 	DEBUG2("IO     BASE = [0x%x] length [0x%x]\n",
1215 	    phdl->io_base, phdl->io_len);
1216 
1217 	/* set up a IO resource map for NT bridge */
1218 	if (ndi_ra_map_setup(dip, NDI_RA_TYPE_IO) == NDI_FAILURE) {
1219 		DEBUG0("Can not setup ntbridge memory resource map\n");
1220 		return (PCICFG_FAILURE);
1221 	}
1222 	/* initialize the IO map */
1223 	if (ndi_ra_free(dip, boundbase, boundlen, NDI_RA_TYPE_IO,
1224 	    NDI_RA_PASS) != NDI_SUCCESS) {
1225 		DEBUG0("Can not initalize ntbridge memory resource map\n");
1226 		return (PCICFG_FAILURE);
1227 	}
1228 
1229 	return (PCICFG_SUCCESS);
1230 }
1231 
1232 static int
1233 pcicfg_ntbridge_configure_done(dev_info_t *dip)
1234 {
1235 	pcicfg_range_t range[PCICFG_RANGE_LEN];
1236 	pcicfg_phdl_t		*entry;
1237 	uint_t			len;
1238 	pcicfg_bus_range_t	bus_range;
1239 	int			new_bus_range[2];
1240 
1241 	DEBUG1("Configuring children for %llx\n", dip);
1242 
1243 	entry = pcicfg_find_phdl(dip);
1244 	ASSERT(entry);
1245 
1246 	bzero((caddr_t)range,
1247 	    sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
1248 	range[1].child_hi = range[1].parent_hi |=
1249 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
1250 	range[1].child_lo = range[1].parent_lo = (uint32_t)entry->memory_base;
1251 
1252 	range[0].child_hi = range[0].parent_hi |=
1253 	    (PCI_REG_REL_M | PCI_ADDR_IO);
1254 	range[0].child_lo = range[0].parent_lo = (uint32_t)entry->io_base;
1255 
1256 	len = sizeof (pcicfg_bus_range_t);
1257 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1258 	    "bus-range", (caddr_t)&bus_range, (int *)&len) != DDI_SUCCESS) {
1259 		DEBUG0("no bus-range property\n");
1260 		return (PCICFG_FAILURE);
1261 	}
1262 
1263 	new_bus_range[0] = bus_range.lo;	/* primary bus number */
1264 	if (entry->highest_bus) {	/* secondary bus number */
1265 		if (entry->highest_bus < bus_range.lo) {
1266 			cmn_err(CE_WARN,
1267 			    "ntbridge bus range invalid !(%d,%d)\n",
1268 			    bus_range.lo, entry->highest_bus);
1269 			new_bus_range[1] = bus_range.lo + entry->highest_bus;
1270 		}
1271 		else
1272 			new_bus_range[1] = entry->highest_bus;
1273 	}
1274 	else
1275 		new_bus_range[1] = bus_range.hi;
1276 
1277 	DEBUG2("ntbridge: bus range lo=%x, hi=%x\n",
1278 	    new_bus_range[0], new_bus_range[1]);
1279 
1280 	if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1281 	    "bus-range", new_bus_range, 2) != DDI_SUCCESS) {
1282 		DEBUG0("Failed to set bus-range property");
1283 		entry->error = PCICFG_FAILURE;
1284 		return (PCICFG_FAILURE);
1285 	}
1286 
1287 #ifdef DEBUG
1288 	{
1289 		uint64_t	unused;
1290 		unused = pcicfg_unused_space(&entry->io_hole, &len);
1291 		DEBUG2("ntbridge: Unused IO space %llx bytes over %d holes\n",
1292 		    unused, len);
1293 	}
1294 #endif
1295 
1296 	range[0].size_lo = entry->io_len;
1297 	if (pcicfg_update_ranges_prop(dip, &range[0])) {
1298 		DEBUG0("Failed to update ranges (i/o)\n");
1299 		entry->error = PCICFG_FAILURE;
1300 		return (PCICFG_FAILURE);
1301 	}
1302 
1303 #ifdef DEBUG
1304 	{
1305 		uint64_t	unused;
1306 		unused = pcicfg_unused_space(&entry->mem_hole, &len);
1307 		DEBUG2("ntbridge: Unused Mem space %llx bytes over %d holes\n",
1308 		    unused, len);
1309 	}
1310 #endif
1311 
1312 	range[1].size_lo = entry->memory_len;
1313 	if (pcicfg_update_ranges_prop(dip, &range[1])) {
1314 		DEBUG0("Failed to update ranges (memory)\n");
1315 		entry->error = PCICFG_FAILURE;
1316 		return (PCICFG_FAILURE);
1317 	}
1318 
1319 	return (PCICFG_SUCCESS);
1320 }
1321 
1322 static int
1323 pcicfg_ntbridge_unconfigure_child(dev_info_t *new_device, uint_t devno)
1324 {
1325 
1326 	dev_info_t	*new_ntbridgechild;
1327 	int		len, bus;
1328 	uint16_t	vid;
1329 	ddi_acc_handle_t	config_handle;
1330 	pcicfg_bus_range_t pci_bus_range;
1331 
1332 	len = sizeof (pcicfg_bus_range_t);
1333 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, new_device, DDI_PROP_DONTPASS,
1334 	    "bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
1335 		DEBUG0("no bus-range property\n");
1336 		return (PCICFG_FAILURE);
1337 	}
1338 
1339 	bus = pci_bus_range.lo; /* primary bus number of this bus node */
1340 
1341 	if (ndi_devi_alloc(new_device, DEVI_PSEUDO_NEXNAME,
1342 	    (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild) != NDI_SUCCESS) {
1343 
1344 		DEBUG0("pcicfg: Failed to alloc test node\n");
1345 		return (PCICFG_FAILURE);
1346 	}
1347 
1348 	if (pcicfg_add_config_reg(new_ntbridgechild, bus, devno, 0)
1349 	    != DDI_PROP_SUCCESS) {
1350 		cmn_err(CE_WARN,
1351 		"Unconfigure: Failed to add conf reg prop for ntbridge "
1352 		    "child.\n");
1353 		(void) ndi_devi_free(new_ntbridgechild);
1354 		return (PCICFG_FAILURE);
1355 	}
1356 
1357 	if (pcicfg_config_setup(new_ntbridgechild, &config_handle)
1358 	    != DDI_SUCCESS) {
1359 		cmn_err(CE_WARN,
1360 		    "pcicfg: Cannot map ntbridge child %x\n", devno);
1361 		(void) ndi_devi_free(new_ntbridgechild);
1362 		return (PCICFG_FAILURE);
1363 	}
1364 
1365 	/*
1366 	 * See if there is any PCI HW at this location
1367 	 * by reading the Vendor ID.  If it returns with 0xffff
1368 	 * then there is no hardware at this location.
1369 	 */
1370 	vid = pci_config_get16(config_handle, PCI_CONF_VENID);
1371 
1372 	pci_config_teardown(&config_handle);
1373 	(void) ndi_devi_free(new_ntbridgechild);
1374 	if (vid	== 0xffff)
1375 		return (PCICFG_NODEVICE);
1376 
1377 	return (pcicfg_unconfigure(new_device, devno, PCICFG_ALL_FUNC, 0));
1378 }
1379 
1380 static int
1381 pcicfg_ntbridge_unconfigure(dev_info_t *dip)
1382 {
1383 	pcicfg_phdl_t *entry = pcicfg_find_phdl(dip);
1384 	uint_t			*bus;
1385 	int			k, rc = PCICFG_FAILURE;
1386 
1387 	if (entry->memory_len)
1388 		if (ndi_ra_map_destroy(dip, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
1389 			DEBUG1("cannot destroy ntbridge memory map size=%x\n",
1390 			    entry->memory_len);
1391 			return (PCICFG_FAILURE);
1392 		}
1393 	if (entry->io_len)
1394 		if (ndi_ra_map_destroy(dip, NDI_RA_TYPE_IO) == NDI_FAILURE) {
1395 			DEBUG1("cannot destroy ntbridge io map size=%x\n",
1396 			    entry->io_len);
1397 			return (PCICFG_FAILURE);
1398 		}
1399 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1400 	    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
1401 	    &k) != DDI_PROP_SUCCESS) {
1402 		DEBUG0("ntbridge: Failed to read bus-range property\n");
1403 		return (rc);
1404 	}
1405 
1406 	DEBUG2("ntbridge: Need to free bus [%d] range [%d]\n",
1407 	    bus[0], bus[1] - bus[0] + 1);
1408 
1409 	if (ndi_ra_free(ddi_get_parent(dip),
1410 	    (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
1411 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1412 		DEBUG0("ntbridge: Failed to free a bus number\n");
1413 		/*
1414 		 * Don't forget to free up memory from ddi_getlongprop
1415 		 */
1416 		kmem_free((caddr_t)bus, k);
1417 
1418 		return (rc);
1419 	}
1420 
1421 	/*
1422 	 * Don't forget to free up memory from ddi_getlongprop
1423 	 */
1424 	kmem_free((caddr_t)bus, k);
1425 
1426 	/*
1427 	 * Since our resources will be freed at the parent level,
1428 	 * just reset these values.
1429 	 */
1430 	entry->memory_len = 0;
1431 	entry->io_len = 0;
1432 	/* the following will also free hole data. */
1433 	return (pcicfg_destroy_phdl(dip));
1434 
1435 }
1436 
1437 static int
1438 pcicfg_is_ntbridge(dev_info_t *dip)
1439 {
1440 	ddi_acc_handle_t	config_handle;
1441 	uint8_t		class, subclass;
1442 	int		rc = DDI_SUCCESS;
1443 
1444 	if (pcicfg_config_setup(dip, &config_handle) != DDI_SUCCESS) {
1445 		cmn_err(CE_WARN,
1446 		    "pcicfg: cannot map config space, to get map type\n");
1447 		return (DDI_FAILURE);
1448 	}
1449 	class = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
1450 	subclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
1451 
1452 	/* check for class=6, subclass=9, for non transparent bridges.  */
1453 	if ((class != PCI_CLASS_BRIDGE) || (subclass != PCI_BRIDGE_STBRIDGE))
1454 		rc = DDI_FAILURE;
1455 
1456 	DEBUG3("pcicfg: checking device %x,%x for indirect map. rc=%d\n",
1457 	    pci_config_get16(config_handle, PCI_CONF_VENID),
1458 	    pci_config_get16(config_handle, PCI_CONF_DEVID),
1459 	    rc);
1460 	pci_config_teardown(&config_handle);
1461 	return (rc);
1462 }
1463 
1464 /*
1465  * this function is called only for SPARC platforms, where we may have
1466  * a mix n' match of direct vs indirectly mapped configuration space.
1467  * On x86, this function does not get called. We always return TRUE
1468  * via a macro for x86.
1469  */
1470 /*ARGSUSED*/
1471 static int
1472 pcicfg_indirect_map(dev_info_t *dip)
1473 {
1474 #if defined(__sparc)
1475 	int rc = DDI_FAILURE;
1476 
1477 	if (ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 0,
1478 	    PCI_DEV_CONF_MAP_PROP, DDI_FAILURE) != DDI_FAILURE)
1479 		rc = DDI_SUCCESS;
1480 	else
1481 		if (ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
1482 		    0, PCI_BUS_CONF_MAP_PROP,
1483 		    DDI_FAILURE) != DDI_FAILURE)
1484 			rc = DDI_SUCCESS;
1485 	DEBUG1("pci conf map = %d", rc);
1486 	return (rc);
1487 #else
1488 	return (DDI_SUCCESS);
1489 #endif
1490 }
1491 
1492 static uint_t
1493 pcicfg_get_ntbridge_child_range(dev_info_t *dip, uint64_t *boundbase,
1494     uint64_t *boundlen, uint_t space_type)
1495 {
1496 	int		length, found = DDI_FAILURE, acount, i, ibridge;
1497 	pci_regspec_t	*assigned;
1498 
1499 	if ((ibridge = pcicfg_is_ntbridge(dip)) == DDI_FAILURE)
1500 		return (found);
1501 
1502 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1503 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
1504 	    &length) != DDI_PROP_SUCCESS) {
1505 		DEBUG1("Failed to get assigned-addresses property %llx\n", dip);
1506 		return (found);
1507 	}
1508 	DEBUG1("pcicfg: ntbridge child range: dip = %s\n",
1509 	    ddi_driver_name(dip));
1510 
1511 	acount = length / sizeof (pci_regspec_t);
1512 
1513 	for (i = 0; i < acount; i++) {
1514 		if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1515 		    pcicfg_indirect_map_devs[ibridge].mem_range_bar_offset) &&
1516 		    (space_type == PCI_BASE_SPACE_MEM)) {
1517 			found = DDI_SUCCESS;
1518 			break;
1519 		} else {
1520 			if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1521 			    pcicfg_indirect_map_devs[ibridge].\
1522 			    io_range_bar_offset) &&
1523 			    (space_type == PCI_BASE_SPACE_IO)) {
1524 				found = DDI_SUCCESS;
1525 				break;
1526 			}
1527 		}
1528 	}
1529 	DEBUG3("pcicfg: ntbridge child range: space=%x, base=%lx, len=%lx\n",
1530 	    space_type, assigned[i].pci_phys_low, assigned[i].pci_size_low);
1531 
1532 	if (found == DDI_SUCCESS)  {
1533 		*boundbase = assigned[i].pci_phys_low;
1534 		*boundlen = assigned[i].pci_size_low;
1535 	}
1536 
1537 	kmem_free(assigned, length);
1538 	return (found);
1539 }
1540 
1541 /*
1542  * This will turn  resources allocated by pcicfg_configure()
1543  * and remove the device tree from the Hotplug Connection (CN)
1544  * and below.  The routine assumes the devices have their
1545  * drivers detached.
1546  */
1547 int
1548 pcicfg_unconfigure(dev_info_t *devi, uint_t device, uint_t function,
1549     pcicfg_flags_t flags)
1550 {
1551 	dev_info_t *child_dip;
1552 	int func;
1553 	int i;
1554 	int max_function;
1555 	int trans_device;
1556 	int circ;
1557 	boolean_t is_pcie;
1558 
1559 	if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED)
1560 		max_function = PCICFG_MAX_ARI_FUNCTION;
1561 	else
1562 		max_function = PCICFG_MAX_FUNCTION;
1563 
1564 	/*
1565 	 * Cycle through devices to make sure none are busy.
1566 	 * If a single device is busy fail the whole unconfigure.
1567 	 */
1568 	is_pcie = is_pcie_fabric(devi);
1569 
1570 	ndi_devi_enter(devi, &circ);
1571 	for (func = 0; func < max_function; func++) {
1572 
1573 		if (max_function == PCICFG_MAX_ARI_FUNCTION)
1574 			trans_device = func >> 3; /* ARI Device */
1575 		else
1576 			trans_device = device;
1577 
1578 		if ((child_dip = pcicfg_devi_find(devi, trans_device,
1579 		    (func & 0x7))) == NULL)
1580 			continue;
1581 
1582 		if (ndi_devi_offline(child_dip, NDI_UNCONFIG) == NDI_SUCCESS)
1583 			continue;
1584 		/*
1585 		 * Device function is busy. Before returning we have to
1586 		 * put all functions back online which were taken
1587 		 * offline during the process.
1588 		 */
1589 		DEBUG2("Device [0x%x] function [%x] is busy\n", device, func);
1590 		/*
1591 		 * If we are only asked to offline one specific function,
1592 		 * and that fails, we just simply return.
1593 		 */
1594 		if (function != PCICFG_ALL_FUNC)
1595 			return (PCICFG_FAILURE);
1596 
1597 		for (i = 0; i < func; i++) {
1598 
1599 			if (max_function == PCICFG_MAX_ARI_FUNCTION)
1600 				trans_device = i >> 3;
1601 
1602 			if ((child_dip =
1603 			    pcicfg_devi_find(devi, trans_device, (i & 7)))
1604 			    == NULL) {
1605 				DEBUG0(
1606 				    "No more devices to put back on line!!\n");
1607 				/*
1608 				 * Made it through all functions
1609 				 */
1610 				continue;
1611 			}
1612 			if (ndi_devi_online(child_dip, NDI_CONFIG)
1613 			    != NDI_SUCCESS) {
1614 				DEBUG0("Failed to put back devices state\n");
1615 				goto fail;
1616 			}
1617 		}
1618 		goto fail;
1619 	}
1620 
1621 	/*
1622 	 * Now, tear down all devinfo nodes for this Connector.
1623 	 */
1624 	for (func = 0; func < max_function; func++) {
1625 
1626 		if (max_function == PCICFG_MAX_ARI_FUNCTION)
1627 			trans_device = func >> 3; /* ARI Device */
1628 		else
1629 			trans_device = device;
1630 
1631 		if ((child_dip = pcicfg_devi_find(devi,
1632 		    trans_device, (func & 7))) == NULL) {
1633 			DEBUG0("No more devices to tear down!\n");
1634 			continue;
1635 		}
1636 
1637 		DEBUG2("Tearing down device [0x%x] function [0x%x]\n",
1638 		    trans_device, (func & 7));
1639 
1640 		if (pcicfg_is_ntbridge(child_dip) != DDI_FAILURE)
1641 			if (pcicfg_ntbridge_unconfigure(child_dip) !=
1642 			    PCICFG_SUCCESS) {
1643 				cmn_err(CE_WARN,
1644 				    "ntbridge: unconfigure failed\n");
1645 				goto fail;
1646 			}
1647 
1648 		if (pcicfg_teardown_device(child_dip, flags, is_pcie)
1649 		    != PCICFG_SUCCESS) {
1650 			DEBUG2("Failed to tear down device [0x%x]"
1651 			    "function [0x%x]\n",
1652 			    trans_device, func & 7);
1653 			goto fail;
1654 		}
1655 	}
1656 
1657 	if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED) {
1658 		(void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "ari-enabled");
1659 		(void) pcie_ari_disable(devi);
1660 	}
1661 
1662 	ndi_devi_exit(devi, circ);
1663 	return (PCICFG_SUCCESS);
1664 
1665 fail:
1666 	ndi_devi_exit(devi, circ);
1667 	return (PCICFG_FAILURE);
1668 }
1669 
1670 static int
1671 pcicfg_teardown_device(dev_info_t *dip, pcicfg_flags_t flags, boolean_t is_pcie)
1672 {
1673 	ddi_acc_handle_t	config_handle;
1674 
1675 	/*
1676 	 * Free up resources associated with 'dip'
1677 	 */
1678 	if (pcicfg_free_resources(dip, flags) != PCICFG_SUCCESS) {
1679 		DEBUG0("Failed to free resources\n");
1680 		return (PCICFG_FAILURE);
1681 	}
1682 
1683 	/*
1684 	 * This will disable the device
1685 	 */
1686 	if (pci_config_setup(dip, &config_handle) != PCICFG_SUCCESS) {
1687 		return (PCICFG_FAILURE);
1688 	}
1689 
1690 	pcicfg_device_off(config_handle);
1691 	pci_config_teardown(&config_handle);
1692 
1693 	/*
1694 	 * free pcie_bus_t for the sub-tree
1695 	 */
1696 	if (is_pcie) {
1697 		if (ddi_get_child(dip) != NULL)
1698 			pcie_fab_fini_bus(dip, PCIE_BUS_ALL);
1699 
1700 		pcie_fini_bus(dip, PCIE_BUS_ALL);
1701 	}
1702 
1703 	/*
1704 	 * The framework provides this routine which can
1705 	 * tear down a sub-tree.
1706 	 */
1707 	if (ndi_devi_offline(dip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
1708 		DEBUG0("Failed to offline and remove node\n");
1709 		return (PCICFG_FAILURE);
1710 	}
1711 
1712 	return (PCICFG_SUCCESS);
1713 }
1714 
1715 /*
1716  * BEGIN GENERIC SUPPORT ROUTINES
1717  */
1718 static pcicfg_phdl_t *
1719 pcicfg_find_phdl(dev_info_t *dip)
1720 {
1721 	pcicfg_phdl_t *entry;
1722 	mutex_enter(&pcicfg_list_mutex);
1723 	for (entry = pcicfg_phdl_list; entry != NULL; entry = entry->next) {
1724 		if (entry->dip == dip) {
1725 			mutex_exit(&pcicfg_list_mutex);
1726 			return (entry);
1727 		}
1728 	}
1729 	mutex_exit(&pcicfg_list_mutex);
1730 
1731 	/*
1732 	 * Did'nt find entry - create one
1733 	 */
1734 	return (pcicfg_create_phdl(dip));
1735 }
1736 
1737 static pcicfg_phdl_t *
1738 pcicfg_create_phdl(dev_info_t *dip)
1739 {
1740 	pcicfg_phdl_t *new;
1741 
1742 	new = (pcicfg_phdl_t *)kmem_zalloc(sizeof (pcicfg_phdl_t),
1743 	    KM_SLEEP);
1744 
1745 	new->dip = dip;
1746 	mutex_enter(&pcicfg_list_mutex);
1747 	new->next = pcicfg_phdl_list;
1748 	pcicfg_phdl_list = new;
1749 	mutex_exit(&pcicfg_list_mutex);
1750 
1751 	return (new);
1752 }
1753 
1754 static int
1755 pcicfg_destroy_phdl(dev_info_t *dip)
1756 {
1757 	pcicfg_phdl_t *entry;
1758 	pcicfg_phdl_t *follow = NULL;
1759 
1760 	mutex_enter(&pcicfg_list_mutex);
1761 	for (entry = pcicfg_phdl_list; entry != NULL; follow = entry,
1762 	    entry = entry->next) {
1763 		if (entry->dip == dip) {
1764 			if (entry == pcicfg_phdl_list) {
1765 				pcicfg_phdl_list = entry->next;
1766 			} else {
1767 				follow->next = entry->next;
1768 			}
1769 			/*
1770 			 * If this entry has any allocated memory
1771 			 * or IO space associated with it, that
1772 			 * must be freed up.
1773 			 */
1774 			if (entry->memory_len > 0) {
1775 				(void) ndi_ra_free(ddi_get_parent(dip),
1776 				    entry->memory_base,
1777 				    entry->memory_len,
1778 				    NDI_RA_TYPE_MEM, NDI_RA_PASS);
1779 			}
1780 			pcicfg_free_hole(&entry->mem_hole);
1781 
1782 			if (entry->io_len > 0) {
1783 				(void) ndi_ra_free(ddi_get_parent(dip),
1784 				    entry->io_base,
1785 				    entry->io_len,
1786 				    NDI_RA_TYPE_IO, NDI_RA_PASS);
1787 			}
1788 			pcicfg_free_hole(&entry->io_hole);
1789 
1790 			/*
1791 			 * Destroy this entry
1792 			 */
1793 			kmem_free((caddr_t)entry, sizeof (pcicfg_phdl_t));
1794 			mutex_exit(&pcicfg_list_mutex);
1795 			return (PCICFG_SUCCESS);
1796 		}
1797 	}
1798 	mutex_exit(&pcicfg_list_mutex);
1799 	/*
1800 	 * Did'nt find the entry
1801 	 */
1802 	return (PCICFG_FAILURE);
1803 }
1804 
1805 static int
1806 pcicfg_program_ap(dev_info_t *dip)
1807 {
1808 	pcicfg_phdl_t *phdl;
1809 	uint8_t header_type;
1810 	ddi_acc_handle_t handle;
1811 	pcicfg_phdl_t *entry;
1812 
1813 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
1814 		DEBUG0("Failed to map config space!\n");
1815 		return (PCICFG_FAILURE);
1816 
1817 	}
1818 
1819 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1820 
1821 	(void) pcicfg_config_teardown(&handle);
1822 
1823 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1824 
1825 		if (pcicfg_allocate_chunk(dip) != PCICFG_SUCCESS) {
1826 			DEBUG0("Not enough memory to hotplug\n");
1827 			(void) pcicfg_destroy_phdl(dip);
1828 			return (PCICFG_FAILURE);
1829 		}
1830 
1831 		phdl = pcicfg_find_phdl(dip);
1832 		ASSERT(phdl);
1833 
1834 		(void) pcicfg_bridge_assign(dip, (void *)phdl);
1835 
1836 		if (phdl->error != PCICFG_SUCCESS) {
1837 			DEBUG0("Problem assigning bridge\n");
1838 			(void) pcicfg_destroy_phdl(dip);
1839 			return (phdl->error);
1840 		}
1841 
1842 		/*
1843 		 * Successfully allocated and assigned
1844 		 * memory.  Set the memory and IO length
1845 		 * to zero so when the handle is freed up
1846 		 * it will not de-allocate assigned resources.
1847 		 */
1848 		entry = (pcicfg_phdl_t *)phdl;
1849 
1850 		entry->memory_len = entry->io_len = 0;
1851 
1852 		/*
1853 		 * Free up the "entry" structure.
1854 		 */
1855 		(void) pcicfg_destroy_phdl(dip);
1856 	} else {
1857 		if (pcicfg_device_assign(dip) != PCICFG_SUCCESS) {
1858 			return (PCICFG_FAILURE);
1859 		}
1860 	}
1861 	return (PCICFG_SUCCESS);
1862 }
1863 
1864 static int
1865 pcicfg_bridge_assign(dev_info_t *dip, void *hdl)
1866 {
1867 	ddi_acc_handle_t handle;
1868 	pci_regspec_t *reg;
1869 	int length;
1870 	int rcount;
1871 	int i;
1872 	int offset;
1873 	uint64_t mem_answer;
1874 	uint32_t io_answer;
1875 	int count;
1876 	uint8_t header_type;
1877 	pcicfg_range_t range[PCICFG_RANGE_LEN];
1878 	int bus_range[2];
1879 
1880 	pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
1881 
1882 	DEBUG1("bridge assign: assigning addresses to %s\n", ddi_get_name(dip));
1883 
1884 	if (entry == NULL) {
1885 		DEBUG0("Failed to get entry\n");
1886 		return (DDI_WALK_TERMINATE);
1887 	}
1888 
1889 	entry->error = PCICFG_SUCCESS;
1890 
1891 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
1892 		DEBUG0("Failed to map config space!\n");
1893 		entry->error = PCICFG_FAILURE;
1894 		return (DDI_WALK_TERMINATE);
1895 	}
1896 
1897 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1898 
1899 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1900 
1901 		bzero((caddr_t)range,
1902 		    sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
1903 
1904 		(void) pcicfg_setup_bridge(entry, handle, dip);
1905 
1906 		range[0].child_hi = range[0].parent_hi |=
1907 		    (PCI_REG_REL_M | PCI_ADDR_IO);
1908 		range[0].child_lo = range[0].parent_lo =
1909 		    entry->io_last;
1910 		range[1].child_hi = range[1].parent_hi |=
1911 		    (PCI_REG_REL_M | PCI_ADDR_MEM32);
1912 		range[1].child_lo = range[1].parent_lo =
1913 		    entry->memory_last;
1914 
1915 		ndi_devi_enter(dip, &count);
1916 		ddi_walk_devs(ddi_get_child(dip),
1917 		    pcicfg_bridge_assign, (void *)entry);
1918 		ndi_devi_exit(dip, count);
1919 
1920 		(void) pcicfg_update_bridge(entry, handle);
1921 
1922 		bus_range[0] = pci_config_get8(handle, PCI_BCNF_SECBUS);
1923 		bus_range[1] = pci_config_get8(handle, PCI_BCNF_SUBBUS);
1924 
1925 		if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1926 		    "bus-range", bus_range, 2) != DDI_SUCCESS) {
1927 			DEBUG0("Failed to set bus-range property");
1928 			entry->error = PCICFG_FAILURE;
1929 			return (DDI_WALK_TERMINATE);
1930 		}
1931 
1932 		if (entry->io_len > 0) {
1933 			range[0].size_lo = entry->io_last - entry->io_base;
1934 			if (pcicfg_update_ranges_prop(dip, &range[0])) {
1935 				DEBUG0("Failed to update ranges (i/o)\n");
1936 				entry->error = PCICFG_FAILURE;
1937 				return (DDI_WALK_TERMINATE);
1938 			}
1939 		}
1940 		if (entry->memory_len > 0) {
1941 			range[1].size_lo =
1942 			    entry->memory_last - entry->memory_base;
1943 			if (pcicfg_update_ranges_prop(dip, &range[1])) {
1944 				DEBUG0("Failed to update ranges (memory)\n");
1945 				entry->error = PCICFG_FAILURE;
1946 				return (DDI_WALK_TERMINATE);
1947 			}
1948 		}
1949 
1950 		(void) pcicfg_device_on(handle);
1951 
1952 		PCICFG_DUMP_BRIDGE_CONFIG(handle);
1953 
1954 		return (DDI_WALK_PRUNECHILD);
1955 	}
1956 
1957 	/*
1958 	 * If there is an interrupt pin set program
1959 	 * interrupt line with default values.
1960 	 */
1961 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1962 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1963 	}
1964 
1965 	/*
1966 	 * A single device (under a bridge).
1967 	 * For each "reg" property with a length, allocate memory
1968 	 * and program the base registers.
1969 	 */
1970 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1971 	    DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
1972 	    &length) != DDI_PROP_SUCCESS) {
1973 		DEBUG0("Failed to read reg property\n");
1974 		entry->error = PCICFG_FAILURE;
1975 		return (DDI_WALK_TERMINATE);
1976 	}
1977 
1978 	rcount = length / sizeof (pci_regspec_t);
1979 	offset = PCI_CONF_BASE0;
1980 	for (i = 0; i < rcount; i++) {
1981 		if ((reg[i].pci_size_low != 0)||
1982 		    (reg[i].pci_size_hi != 0)) {
1983 
1984 			offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
1985 
1986 			switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
1987 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
1988 
1989 				(void) pcicfg_get_mem(entry,
1990 				    reg[i].pci_size_low, &mem_answer);
1991 				pci_config_put64(handle, offset, mem_answer);
1992 				DEBUG2("REGISTER off %x (64)LO ----> [0x%x]\n",
1993 				    offset,
1994 				    pci_config_get32(handle, offset));
1995 				DEBUG2("REGISTER off %x (64)HI ----> [0x%x]\n",
1996 				    offset + 4,
1997 				    pci_config_get32(handle, offset + 4));
1998 
1999 				reg[i].pci_phys_low = PCICFG_HIADDR(mem_answer);
2000 				reg[i].pci_phys_mid  =
2001 				    PCICFG_LOADDR(mem_answer);
2002 
2003 				break;
2004 
2005 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2006 				/* allocate memory space from the allocator */
2007 
2008 				(void) pcicfg_get_mem(entry,
2009 				    reg[i].pci_size_low, &mem_answer);
2010 				pci_config_put32(handle,
2011 				    offset, (uint32_t)mem_answer);
2012 
2013 				DEBUG2("REGISTER off %x(32)LO ----> [0x%x]\n",
2014 				    offset,
2015 				    pci_config_get32(handle, offset));
2016 
2017 				reg[i].pci_phys_low = (uint32_t)mem_answer;
2018 
2019 				break;
2020 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2021 				/* allocate I/O space from the allocator */
2022 
2023 				(void) pcicfg_get_io(entry,
2024 				    reg[i].pci_size_low, &io_answer);
2025 				pci_config_put32(handle, offset, io_answer);
2026 
2027 				DEBUG2("REGISTER off %x (I/O)LO ----> [0x%x]\n",
2028 				    offset,
2029 				    pci_config_get32(handle, offset));
2030 
2031 				reg[i].pci_phys_low = io_answer;
2032 
2033 				break;
2034 			default:
2035 				DEBUG0("Unknown register type\n");
2036 				kmem_free(reg, length);
2037 				(void) pcicfg_config_teardown(&handle);
2038 				entry->error = PCICFG_FAILURE;
2039 				return (DDI_WALK_TERMINATE);
2040 			} /* switch */
2041 
2042 			/*
2043 			 * Now that memory locations are assigned,
2044 			 * update the assigned address property.
2045 			 */
2046 			if (pcicfg_update_assigned_prop(dip,
2047 			    &reg[i]) != PCICFG_SUCCESS) {
2048 				kmem_free(reg, length);
2049 				(void) pcicfg_config_teardown(&handle);
2050 				entry->error = PCICFG_FAILURE;
2051 				return (DDI_WALK_TERMINATE);
2052 			}
2053 		}
2054 	}
2055 	(void) pcicfg_device_on(handle);
2056 
2057 	PCICFG_DUMP_DEVICE_CONFIG(handle);
2058 
2059 	(void) pcicfg_config_teardown(&handle);
2060 	/*
2061 	 * Don't forget to free up memory from ddi_getlongprop
2062 	 */
2063 	kmem_free((caddr_t)reg, length);
2064 
2065 	return (DDI_WALK_CONTINUE);
2066 }
2067 
2068 static int
2069 pcicfg_device_assign(dev_info_t *dip)
2070 {
2071 	ddi_acc_handle_t	handle;
2072 	pci_regspec_t		*reg;
2073 	int			length;
2074 	int			rcount;
2075 	int			i;
2076 	int			offset;
2077 	ndi_ra_request_t	request;
2078 	uint64_t		answer;
2079 	uint64_t		alen;
2080 
2081 	DEBUG1("%llx now under configuration\n", dip);
2082 
2083 	/*
2084 	 * XXX Failure here should be noted
2085 	 */
2086 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2087 	    DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
2088 	    &length) != DDI_PROP_SUCCESS) {
2089 		DEBUG0("Failed to read reg property\n");
2090 		return (PCICFG_FAILURE);
2091 	}
2092 
2093 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2094 		DEBUG0("Failed to map config space!\n");
2095 		/*
2096 		 * Don't forget to free up memory from ddi_getlongprop
2097 		 */
2098 		kmem_free((caddr_t)reg, length);
2099 
2100 		return (PCICFG_FAILURE);
2101 	}
2102 
2103 	/*
2104 	 * A single device
2105 	 *
2106 	 * For each "reg" property with a length, allocate memory
2107 	 * and program the base registers.
2108 	 */
2109 
2110 	/*
2111 	 * If there is an interrupt pin set program
2112 	 * interrupt line with default values.
2113 	 */
2114 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2115 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2116 	}
2117 
2118 	bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2119 
2120 	request.ra_flags = NDI_RA_ALIGN_SIZE;
2121 	request.ra_boundbase = 0;
2122 	request.ra_boundlen = PCICFG_4GIG_LIMIT;
2123 
2124 	rcount = length / sizeof (pci_regspec_t);
2125 	for (i = 0; i < rcount; i++) {
2126 		if ((reg[i].pci_size_low != 0)||
2127 		    (reg[i].pci_size_hi != 0)) {
2128 
2129 			offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
2130 			request.ra_len = reg[i].pci_size_low;
2131 
2132 			switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
2133 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2134 				request.ra_flags &= ~NDI_RA_ALLOC_BOUNDED;
2135 				/* allocate memory space from the allocator */
2136 				if (ndi_ra_alloc(ddi_get_parent(dip),
2137 				    &request, &answer, &alen,
2138 				    NDI_RA_TYPE_MEM, NDI_RA_PASS)
2139 				    != NDI_SUCCESS) {
2140 					DEBUG0("Failed to allocate 64b mem\n");
2141 					kmem_free(reg, length);
2142 					(void) pcicfg_config_teardown(&handle);
2143 					return (PCICFG_FAILURE);
2144 				}
2145 				DEBUG3("64 addr = [0x%x.%x] len [0x%x]\n",
2146 				    PCICFG_HIADDR(answer),
2147 				    PCICFG_LOADDR(answer),
2148 				    alen);
2149 				/* program the low word */
2150 				pci_config_put32(handle,
2151 				    offset, PCICFG_LOADDR(answer));
2152 
2153 				/* program the high word */
2154 				pci_config_put32(handle, offset + 4,
2155 				    PCICFG_HIADDR(answer));
2156 
2157 				reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2158 				reg[i].pci_phys_mid = PCICFG_HIADDR(answer);
2159 
2160 				/* adjust to 32b address space when possible */
2161 				if ((answer + alen) <= PCICFG_4GIG_LIMIT)
2162 					reg[i].pci_phys_hi ^=
2163 					    PCI_ADDR_MEM64 ^ PCI_ADDR_MEM32;
2164 				break;
2165 
2166 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2167 				request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
2168 				/* allocate memory space from the allocator */
2169 				if (ndi_ra_alloc(ddi_get_parent(dip),
2170 				    &request, &answer, &alen,
2171 				    NDI_RA_TYPE_MEM, NDI_RA_PASS)
2172 				    != NDI_SUCCESS) {
2173 					DEBUG0("Failed to allocate 32b mem\n");
2174 					kmem_free(reg, length);
2175 					(void) pcicfg_config_teardown(&handle);
2176 					return (PCICFG_FAILURE);
2177 				}
2178 				DEBUG3("32 addr = [0x%x.%x] len [0x%x]\n",
2179 				    PCICFG_HIADDR(answer),
2180 				    PCICFG_LOADDR(answer),
2181 				    alen);
2182 				/* program the low word */
2183 				pci_config_put32(handle,
2184 				    offset, PCICFG_LOADDR(answer));
2185 
2186 				reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2187 				break;
2188 
2189 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2190 				/* allocate I/O space from the allocator */
2191 				request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
2192 				if (ndi_ra_alloc(ddi_get_parent(dip),
2193 				    &request, &answer, &alen,
2194 				    NDI_RA_TYPE_IO, NDI_RA_PASS)
2195 				    != NDI_SUCCESS) {
2196 					DEBUG0("Failed to allocate I/O\n");
2197 					kmem_free(reg, length);
2198 					(void) pcicfg_config_teardown(&handle);
2199 					return (PCICFG_FAILURE);
2200 				}
2201 				DEBUG3("I/O addr = [0x%x.%x] len [0x%x]\n",
2202 				    PCICFG_HIADDR(answer),
2203 				    PCICFG_LOADDR(answer),
2204 				    alen);
2205 				pci_config_put32(handle,
2206 				    offset, PCICFG_LOADDR(answer));
2207 
2208 				reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2209 				break;
2210 
2211 			default:
2212 				DEBUG0("Unknown register type\n");
2213 				kmem_free(reg, length);
2214 				(void) pcicfg_config_teardown(&handle);
2215 				return (PCICFG_FAILURE);
2216 			} /* switch */
2217 
2218 			/*
2219 			 * Now that memory locations are assigned,
2220 			 * update the assigned address property.
2221 			 */
2222 
2223 			if (pcicfg_update_assigned_prop(dip,
2224 			    &reg[i]) != PCICFG_SUCCESS) {
2225 				kmem_free(reg, length);
2226 				(void) pcicfg_config_teardown(&handle);
2227 				return (PCICFG_FAILURE);
2228 			}
2229 		}
2230 	}
2231 
2232 	(void) pcicfg_device_on(handle);
2233 	kmem_free(reg, length);
2234 
2235 	PCICFG_DUMP_DEVICE_CONFIG(handle);
2236 
2237 	(void) pcicfg_config_teardown(&handle);
2238 	return (PCICFG_SUCCESS);
2239 }
2240 
2241 static int
2242 pcicfg_device_assign_readonly(dev_info_t *dip)
2243 {
2244 	ddi_acc_handle_t	handle;
2245 	pci_regspec_t		*assigned;
2246 	int			length;
2247 	int			acount;
2248 	int			i;
2249 	ndi_ra_request_t	request;
2250 	uint64_t		answer;
2251 	uint64_t		alen;
2252 
2253 
2254 	DEBUG1("%llx now under configuration\n", dip);
2255 
2256 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2257 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
2258 	    &length) != DDI_PROP_SUCCESS) {
2259 		DEBUG0("Failed to read assigned-addresses property\n");
2260 		return (PCICFG_FAILURE);
2261 	}
2262 
2263 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2264 		DEBUG0("Failed to map config space!\n");
2265 		/*
2266 		 * Don't forget to free up memory from ddi_getlongprop
2267 		 */
2268 		kmem_free((caddr_t)assigned, length);
2269 
2270 		return (PCICFG_FAILURE);
2271 	}
2272 
2273 	/*
2274 	 * For each "assigned-addresses" property entry with a length,
2275 	 * call the memory allocation routines to return the
2276 	 * resource.
2277 	 */
2278 	/*
2279 	 * If there is an interrupt pin set program
2280 	 * interrupt line with default values.
2281 	 */
2282 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2283 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2284 	}
2285 
2286 	bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2287 
2288 	request.ra_flags = NDI_RA_ALLOC_SPECIFIED; /* specified addr */
2289 	request.ra_boundbase = 0;
2290 	request.ra_boundlen = PCICFG_4GIG_LIMIT;
2291 
2292 	acount = length / sizeof (pci_regspec_t);
2293 	for (i = 0; i < acount; i++) {
2294 		if ((assigned[i].pci_size_low != 0)||
2295 		    (assigned[i].pci_size_hi != 0)) {
2296 
2297 			request.ra_len = assigned[i].pci_size_low;
2298 
2299 			switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2300 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2301 				request.ra_addr = (uint64_t)PCICFG_LADDR(
2302 				    assigned[i].pci_phys_low,
2303 				    assigned[i].pci_phys_mid);
2304 
2305 				/* allocate memory space from the allocator */
2306 				if (ndi_ra_alloc(ddi_get_parent(dip),
2307 				    &request, &answer, &alen,
2308 				    NDI_RA_TYPE_MEM, NDI_RA_PASS)
2309 				    != NDI_SUCCESS) {
2310 					DEBUG0("Failed to allocate 64b mem\n");
2311 					kmem_free(assigned, length);
2312 					return (PCICFG_FAILURE);
2313 				}
2314 
2315 				break;
2316 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2317 				request.ra_addr = (uint64_t)
2318 				    assigned[i].pci_phys_low;
2319 
2320 				/* allocate memory space from the allocator */
2321 				if (ndi_ra_alloc(ddi_get_parent(dip),
2322 				    &request, &answer, &alen,
2323 				    NDI_RA_TYPE_MEM, NDI_RA_PASS)
2324 				    != NDI_SUCCESS) {
2325 					DEBUG0("Failed to allocate 32b mem\n");
2326 					kmem_free(assigned, length);
2327 					return (PCICFG_FAILURE);
2328 				}
2329 
2330 				break;
2331 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2332 				request.ra_addr = (uint64_t)
2333 				    assigned[i].pci_phys_low;
2334 
2335 				/* allocate I/O space from the allocator */
2336 				if (ndi_ra_alloc(ddi_get_parent(dip),
2337 				    &request, &answer, &alen,
2338 				    NDI_RA_TYPE_IO, NDI_RA_PASS)
2339 				    != NDI_SUCCESS) {
2340 					DEBUG0("Failed to allocate I/O\n");
2341 					kmem_free(assigned, length);
2342 					return (PCICFG_FAILURE);
2343 				}
2344 
2345 				break;
2346 			default:
2347 				DEBUG0("Unknown register type\n");
2348 				kmem_free(assigned, length);
2349 				return (PCICFG_FAILURE);
2350 			} /* switch */
2351 		}
2352 	}
2353 
2354 	(void) pcicfg_device_on(handle);
2355 	kmem_free(assigned, length);
2356 
2357 	PCICFG_DUMP_DEVICE_CONFIG(handle);
2358 
2359 	(void) pcicfg_config_teardown(&handle);
2360 	return (PCICFG_SUCCESS);
2361 }
2362 
2363 /*
2364  * The "dip" passed to this routine is assumed to be
2365  * the device at the Hotplug Connection (CN). Currently it is
2366  * assumed to be a bridge.
2367  */
2368 static int
2369 pcicfg_allocate_chunk(dev_info_t *dip)
2370 {
2371 	pcicfg_phdl_t		*phdl;
2372 	ndi_ra_request_t	*mem_request;
2373 	ndi_ra_request_t	*io_request;
2374 	uint64_t		mem_answer;
2375 	uint64_t		io_answer;
2376 	int			count;
2377 	uint64_t		alen;
2378 
2379 	/*
2380 	 * This should not find an existing entry - so
2381 	 * it will create a new one.
2382 	 */
2383 	phdl = pcicfg_find_phdl(dip);
2384 	ASSERT(phdl);
2385 
2386 	mem_request = &phdl->mem_req;
2387 	io_request  = &phdl->io_req;
2388 
2389 	/*
2390 	 * From this point in the tree - walk the devices,
2391 	 * The function passed in will read and "sum" up
2392 	 * the memory and I/O requirements and put them in
2393 	 * structure "phdl".
2394 	 */
2395 	ndi_devi_enter(ddi_get_parent(dip), &count);
2396 	ddi_walk_devs(dip, pcicfg_sum_resources, (void *)phdl);
2397 	ndi_devi_exit(ddi_get_parent(dip), count);
2398 
2399 	if (phdl->error != PCICFG_SUCCESS) {
2400 		DEBUG0("Failure summing resources\n");
2401 		return (phdl->error);
2402 	}
2403 
2404 	/*
2405 	 * Call into the memory allocator with the request.
2406 	 * Record the addresses returned in the phdl
2407 	 */
2408 	DEBUG1("Connector requires [0x%x] bytes of memory space\n",
2409 	    mem_request->ra_len);
2410 	DEBUG1("Connector requires [0x%x] bytes of I/O space\n",
2411 	    io_request->ra_len);
2412 
2413 	mem_request->ra_align_mask =
2414 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
2415 	io_request->ra_align_mask =
2416 	    PCICFG_IOGRAN - 1;   /* 4K alignment on I/O space */
2417 	io_request->ra_boundbase = 0;
2418 	io_request->ra_boundlen = PCICFG_4GIG_LIMIT;
2419 	io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
2420 
2421 	mem_request->ra_len =
2422 	    PCICFG_ROUND_UP(mem_request->ra_len, PCICFG_MEMGRAN);
2423 
2424 	io_request->ra_len =
2425 	    PCICFG_ROUND_UP(io_request->ra_len, PCICFG_IOGRAN);
2426 
2427 	if (ndi_ra_alloc(ddi_get_parent(dip),
2428 	    mem_request, &mem_answer, &alen,
2429 	    NDI_RA_TYPE_MEM, NDI_RA_PASS) != NDI_SUCCESS) {
2430 		DEBUG0("Failed to allocate memory\n");
2431 		return (PCICFG_FAILURE);
2432 	}
2433 
2434 	phdl->memory_base = phdl->memory_last = mem_answer;
2435 	phdl->memory_len  = alen;
2436 
2437 	phdl->mem_hole.start = phdl->memory_base;
2438 	phdl->mem_hole.len = phdl->memory_len;
2439 	phdl->mem_hole.next = (hole_t *)NULL;
2440 
2441 	if (ndi_ra_alloc(ddi_get_parent(dip), io_request, &io_answer,
2442 	    &alen, NDI_RA_TYPE_IO, NDI_RA_PASS) != NDI_SUCCESS) {
2443 
2444 		DEBUG0("Failed to allocate I/O space\n");
2445 		(void) ndi_ra_free(ddi_get_parent(dip), mem_answer,
2446 		    alen, NDI_RA_TYPE_MEM, NDI_RA_PASS);
2447 		phdl->memory_len = phdl->io_len = 0;
2448 		return (PCICFG_FAILURE);
2449 	}
2450 
2451 	phdl->io_base = phdl->io_last = (uint32_t)io_answer;
2452 	phdl->io_len  = (uint32_t)alen;
2453 
2454 	phdl->io_hole.start = phdl->io_base;
2455 	phdl->io_hole.len = phdl->io_len;
2456 	phdl->io_hole.next = (hole_t *)NULL;
2457 
2458 	DEBUG2("MEMORY BASE = [0x%x] length [0x%x]\n",
2459 	    phdl->memory_base, phdl->memory_len);
2460 	DEBUG2("IO     BASE = [0x%x] length [0x%x]\n",
2461 	    phdl->io_base, phdl->io_len);
2462 
2463 	return (PCICFG_SUCCESS);
2464 }
2465 
2466 #ifdef	DEBUG
2467 /*
2468  * This function is useful in debug mode, where we can measure how
2469  * much memory was wasted/unallocated in bridge device's domain.
2470  */
2471 static uint64_t
2472 pcicfg_unused_space(hole_t *hole, uint32_t *hole_count)
2473 {
2474 	uint64_t len = 0;
2475 	uint32_t count = 0;
2476 
2477 	do {
2478 		len += hole->len;
2479 		hole = hole->next;
2480 		count++;
2481 	} while (hole);
2482 	*hole_count = count;
2483 	return (len);
2484 }
2485 #endif
2486 
2487 /*
2488  * This function frees data structures that hold the hole information
2489  * which are allocated in pcicfg_alloc_hole(). This is not freeing
2490  * any memory allocated through NDI calls.
2491  */
2492 static void
2493 pcicfg_free_hole(hole_t *addr_hole)
2494 {
2495 	hole_t *nhole, *hole = addr_hole->next;
2496 
2497 	while (hole) {
2498 		nhole = hole->next;
2499 		kmem_free(hole, sizeof (hole_t));
2500 		hole = nhole;
2501 	}
2502 }
2503 
2504 static uint64_t
2505 pcicfg_alloc_hole(hole_t *addr_hole, uint64_t *alast, uint32_t length)
2506 {
2507 	uint64_t actual_hole_start, ostart, olen;
2508 	hole_t	*hole = addr_hole, *thole, *nhole;
2509 
2510 	do {
2511 		actual_hole_start = PCICFG_ROUND_UP(hole->start, length);
2512 		if (((actual_hole_start - hole->start) + length) <= hole->len) {
2513 			DEBUG3("hole found. start %llx, len %llx, req=%x\n",
2514 			    hole->start, hole->len, length);
2515 			ostart = hole->start;
2516 			olen = hole->len;
2517 			/* current hole parameters adjust */
2518 			if ((actual_hole_start - hole->start) == 0) {
2519 				hole->start += length;
2520 				hole->len -= length;
2521 				if (hole->start > *alast)
2522 					*alast = hole->start;
2523 			} else {
2524 				hole->len = actual_hole_start - hole->start;
2525 				nhole = (hole_t *)kmem_zalloc(sizeof (hole_t),
2526 				    KM_SLEEP);
2527 				nhole->start = actual_hole_start + length;
2528 				nhole->len = (ostart + olen) - nhole->start;
2529 				nhole->next = NULL;
2530 				thole = hole->next;
2531 				hole->next = nhole;
2532 				nhole->next = thole;
2533 				if (nhole->start > *alast)
2534 					*alast = nhole->start;
2535 				DEBUG2("put new hole to %llx, %llx\n",
2536 				    nhole->start, nhole->len);
2537 			}
2538 			DEBUG2("adjust current hole to %llx, %llx\n",
2539 			    hole->start, hole->len);
2540 			break;
2541 		}
2542 		actual_hole_start = 0;
2543 		hole = hole->next;
2544 	} while (hole);
2545 
2546 	DEBUG1("return hole at %llx\n", actual_hole_start);
2547 	return (actual_hole_start);
2548 }
2549 
2550 static void
2551 pcicfg_get_mem(pcicfg_phdl_t *entry, uint32_t length, uint64_t *ans)
2552 {
2553 	uint64_t new_mem;
2554 
2555 	/* See if there is a hole, that can hold this request. */
2556 	new_mem = pcicfg_alloc_hole(&entry->mem_hole, &entry->memory_last,
2557 	    length);
2558 	if (new_mem) {	/* if non-zero, found a hole. */
2559 		if (ans != NULL)
2560 			*ans = new_mem;
2561 	} else
2562 		cmn_err(CE_WARN, "No %u bytes memory window for %s\n",
2563 		    length, ddi_get_name(entry->dip));
2564 }
2565 
2566 static void
2567 pcicfg_get_io(pcicfg_phdl_t *entry, uint32_t length, uint32_t *ans)
2568 {
2569 	uint32_t new_io;
2570 	uint64_t io_last;
2571 
2572 	/*
2573 	 * See if there is a hole, that can hold this request.
2574 	 * Pass 64 bit parameters and then truncate to 32 bit.
2575 	 */
2576 	io_last = entry->io_last;
2577 	new_io = (uint32_t)pcicfg_alloc_hole(&entry->io_hole, &io_last, length);
2578 	if (new_io) {	/* if non-zero, found a hole. */
2579 		entry->io_last = (uint32_t)io_last;
2580 		if (ans != NULL)
2581 			*ans = new_io;
2582 	} else
2583 		cmn_err(CE_WARN, "No %u bytes IO space window for %s\n",
2584 		    length, ddi_get_name(entry->dip));
2585 }
2586 
2587 static int
2588 pcicfg_sum_resources(dev_info_t *dip, void *hdl)
2589 {
2590 	pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
2591 	pci_regspec_t *pci_rp;
2592 	int length;
2593 	int rcount;
2594 	int i;
2595 	ndi_ra_request_t *mem_request;
2596 	ndi_ra_request_t *io_request;
2597 	uint8_t header_type;
2598 	ddi_acc_handle_t handle;
2599 
2600 	entry->error = PCICFG_SUCCESS;
2601 
2602 	mem_request = &entry->mem_req;
2603 	io_request =  &entry->io_req;
2604 
2605 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2606 		DEBUG0("Failed to map config space!\n");
2607 		entry->error = PCICFG_FAILURE;
2608 		return (DDI_WALK_TERMINATE);
2609 	}
2610 
2611 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2612 
2613 	/*
2614 	 * If its a bridge - just record the highest bus seen
2615 	 */
2616 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2617 
2618 		if (entry->highest_bus < pci_config_get8(handle,
2619 		    PCI_BCNF_SECBUS)) {
2620 			entry->highest_bus =
2621 			    pci_config_get8(handle, PCI_BCNF_SECBUS);
2622 		}
2623 
2624 		(void) pcicfg_config_teardown(&handle);
2625 		entry->error = PCICFG_FAILURE;
2626 		return (DDI_WALK_CONTINUE);
2627 	} else {
2628 		if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2629 		    DDI_PROP_DONTPASS, "reg", (caddr_t)&pci_rp,
2630 		    &length) != DDI_PROP_SUCCESS) {
2631 			/*
2632 			 * If one node in (the subtree of nodes)
2633 			 * does'nt have a "reg" property fail the
2634 			 * allocation.
2635 			 */
2636 			entry->memory_len = 0;
2637 			entry->io_len = 0;
2638 			entry->error = PCICFG_FAILURE;
2639 			return (DDI_WALK_TERMINATE);
2640 		}
2641 		/*
2642 		 * For each "reg" property with a length, add that to the
2643 		 * total memory (or I/O) to allocate.
2644 		 */
2645 		rcount = length / sizeof (pci_regspec_t);
2646 
2647 		for (i = 0; i < rcount; i++) {
2648 
2649 			switch (PCI_REG_ADDR_G(pci_rp[i].pci_phys_hi)) {
2650 
2651 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2652 				mem_request->ra_len =
2653 				    pci_rp[i].pci_size_low +
2654 				    PCICFG_ROUND_UP(mem_request->ra_len,
2655 				    pci_rp[i].pci_size_low);
2656 				DEBUG1("ADDING 32 --->0x%x\n",
2657 				    pci_rp[i].pci_size_low);
2658 
2659 			break;
2660 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2661 				mem_request->ra_len =
2662 				    pci_rp[i].pci_size_low +
2663 				    PCICFG_ROUND_UP(mem_request->ra_len,
2664 				    pci_rp[i].pci_size_low);
2665 				DEBUG1("ADDING 64 --->0x%x\n",
2666 				    pci_rp[i].pci_size_low);
2667 
2668 			break;
2669 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2670 				io_request->ra_len =
2671 				    pci_rp[i].pci_size_low +
2672 				    PCICFG_ROUND_UP(io_request->ra_len,
2673 				    pci_rp[i].pci_size_low);
2674 				DEBUG1("ADDING I/O --->0x%x\n",
2675 				    pci_rp[i].pci_size_low);
2676 			break;
2677 			default:
2678 			    /* Config space register - not included */
2679 			break;
2680 			}
2681 		}
2682 
2683 		/*
2684 		 * free the memory allocated by ddi_getlongprop
2685 		 */
2686 		kmem_free(pci_rp, length);
2687 
2688 		/*
2689 		 * continue the walk to the next sibling to sum memory
2690 		 */
2691 
2692 		(void) pcicfg_config_teardown(&handle);
2693 
2694 		return (DDI_WALK_CONTINUE);
2695 	}
2696 }
2697 
2698 static int
2699 pcicfg_find_resource_end(dev_info_t *dip, void *hdl)
2700 {
2701 	pcicfg_phdl_t *entry_p = (pcicfg_phdl_t *)hdl;
2702 	pci_regspec_t *pci_ap;
2703 	pcicfg_range_t *ranges;
2704 	int length;
2705 	int rcount;
2706 	int i;
2707 
2708 	entry_p->error = PCICFG_SUCCESS;
2709 
2710 	if (dip == entry_p->dip) {
2711 		DEBUG0("Don't include parent bridge node\n");
2712 		return (DDI_WALK_CONTINUE);
2713 	}
2714 
2715 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2716 	    DDI_PROP_DONTPASS, "ranges",
2717 	    (caddr_t)&ranges,  &length) != DDI_PROP_SUCCESS) {
2718 		DEBUG0("Node doesn't have ranges\n");
2719 		goto ap;
2720 	}
2721 
2722 	rcount = length / sizeof (pcicfg_range_t);
2723 
2724 	for (i = 0; i < rcount; i++) {
2725 		uint64_t base;
2726 		uint64_t mid = ranges[i].child_mid;
2727 		uint64_t lo = ranges[i].child_lo;
2728 		uint64_t size = ranges[i].size_lo;
2729 
2730 		switch (PCI_REG_ADDR_G(ranges[i].child_hi)) {
2731 
2732 		case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2733 			base = entry_p->memory_base;
2734 			entry_p->memory_base = MAX(base, lo + size);
2735 			break;
2736 		case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2737 			base = entry_p->memory_base;
2738 			entry_p->memory_base = MAX(base,
2739 			    PCICFG_LADDR(lo, mid) + size);
2740 			break;
2741 		case PCI_REG_ADDR_G(PCI_ADDR_IO):
2742 			base = entry_p->io_base;
2743 			entry_p->io_base = MAX(base, lo + size);
2744 			break;
2745 		}
2746 	}
2747 
2748 	kmem_free(ranges, length);
2749 	return (DDI_WALK_CONTINUE);
2750 
2751 ap:	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2752 	    DDI_PROP_DONTPASS, "assigned-addresses",
2753 	    (caddr_t)&pci_ap,  &length) != DDI_PROP_SUCCESS) {
2754 		DEBUG0("Node doesn't have assigned-addresses\n");
2755 		return (DDI_WALK_CONTINUE);
2756 	}
2757 
2758 	rcount = length / sizeof (pci_regspec_t);
2759 
2760 	for (i = 0; i < rcount; i++) {
2761 
2762 		switch (PCI_REG_ADDR_G(pci_ap[i].pci_phys_hi)) {
2763 
2764 		case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2765 			if ((pci_ap[i].pci_phys_low +
2766 			    pci_ap[i].pci_size_low) >
2767 			    entry_p->memory_base) {
2768 				entry_p->memory_base =
2769 				    pci_ap[i].pci_phys_low +
2770 				    pci_ap[i].pci_size_low;
2771 			}
2772 		break;
2773 		case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2774 			if ((PCICFG_LADDR(pci_ap[i].pci_phys_low,
2775 			    pci_ap[i].pci_phys_mid) +
2776 			    pci_ap[i].pci_size_low) >
2777 			    entry_p->memory_base) {
2778 				entry_p->memory_base = PCICFG_LADDR(
2779 				    pci_ap[i].pci_phys_low,
2780 				    pci_ap[i].pci_phys_mid) +
2781 				    pci_ap[i].pci_size_low;
2782 			}
2783 		break;
2784 		case PCI_REG_ADDR_G(PCI_ADDR_IO):
2785 			if ((pci_ap[i].pci_phys_low +
2786 			    pci_ap[i].pci_size_low) >
2787 			    entry_p->io_base) {
2788 				entry_p->io_base =
2789 				    pci_ap[i].pci_phys_low +
2790 				    pci_ap[i].pci_size_low;
2791 			}
2792 		break;
2793 		}
2794 	}
2795 
2796 	/*
2797 	 * free the memory allocated by ddi_getlongprop
2798 	 */
2799 	kmem_free(pci_ap, length);
2800 
2801 	/*
2802 	 * continue the walk to the next sibling to sum memory
2803 	 */
2804 	return (DDI_WALK_CONTINUE);
2805 }
2806 
2807 static int
2808 pcicfg_free_bridge_resources(dev_info_t *dip)
2809 {
2810 	pcicfg_range_t		*ranges;
2811 	uint_t			*bus;
2812 	int			k;
2813 	int			length;
2814 	int			i;
2815 
2816 
2817 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2818 	    DDI_PROP_DONTPASS, "ranges", (caddr_t)&ranges,
2819 	    &length) != DDI_PROP_SUCCESS) {
2820 		DEBUG0("Failed to read ranges property\n");
2821 		if (ddi_get_child(dip)) {
2822 			cmn_err(CE_WARN, "No ranges property found for %s",
2823 			    ddi_get_name(dip));
2824 			/*
2825 			 * strictly speaking, we can check for children with
2826 			 * assigned-addresses but for now it is better to
2827 			 * be conservative and assume that if there are child
2828 			 * nodes, then they do consume PCI memory or IO
2829 			 * resources, Hence return failure.
2830 			 */
2831 			return (PCICFG_FAILURE);
2832 		}
2833 		length = 0;
2834 
2835 	}
2836 
2837 	for (i = 0; i < length / sizeof (pcicfg_range_t); i++) {
2838 		if (ranges[i].size_lo != 0 ||
2839 		    ranges[i].size_hi != 0) {
2840 			switch (ranges[i].parent_hi & PCI_REG_ADDR_M) {
2841 				case PCI_ADDR_IO:
2842 					DEBUG2("Free I/O    "
2843 					    "base/length = [0x%x]/[0x%x]\n",
2844 					    ranges[i].child_lo,
2845 					    ranges[i].size_lo);
2846 					if (ndi_ra_free(ddi_get_parent(dip),
2847 					    (uint64_t)ranges[i].child_lo,
2848 					    (uint64_t)ranges[i].size_lo,
2849 					    NDI_RA_TYPE_IO, NDI_RA_PASS)
2850 					    != NDI_SUCCESS) {
2851 						DEBUG0("Trouble freeing "
2852 						    "PCI i/o space\n");
2853 						kmem_free(ranges, length);
2854 						return (PCICFG_FAILURE);
2855 					}
2856 				break;
2857 				case PCI_ADDR_MEM32:
2858 				case PCI_ADDR_MEM64:
2859 					DEBUG3("Free Memory base/length = "
2860 					    "[0x%x.%x]/[0x%x]\n",
2861 					    ranges[i].child_mid,
2862 					    ranges[i].child_lo,
2863 					    ranges[i].size_lo)
2864 					if (ndi_ra_free(ddi_get_parent(dip),
2865 					    PCICFG_LADDR(ranges[i].child_lo,
2866 					    ranges[i].child_mid),
2867 					    (uint64_t)ranges[i].size_lo,
2868 					    NDI_RA_TYPE_MEM, NDI_RA_PASS)
2869 					    != NDI_SUCCESS) {
2870 						DEBUG0("Trouble freeing "
2871 						    "PCI memory space\n");
2872 						kmem_free(ranges, length);
2873 						return (PCICFG_FAILURE);
2874 					}
2875 				break;
2876 				default:
2877 					DEBUG0("Unknown memory space\n");
2878 				break;
2879 			}
2880 		}
2881 	}
2882 
2883 	if (length)
2884 		kmem_free(ranges, length);
2885 
2886 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2887 	    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
2888 	    &k) != DDI_PROP_SUCCESS) {
2889 		DEBUG0("Failed to read bus-range property\n");
2890 		return (PCICFG_FAILURE);
2891 	}
2892 
2893 	DEBUG2("Need to free bus [%d] range [%d]\n",
2894 	    bus[0], bus[1] - bus[0] + 1);
2895 
2896 	if (ndi_ra_free(ddi_get_parent(dip),
2897 	    (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
2898 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
2899 		/*EMPTY*/
2900 		DEBUG0("Failed to free a bus number\n");
2901 	}
2902 	/*
2903 	 * Don't forget to free up memory from ddi_getlongprop
2904 	 */
2905 	kmem_free((caddr_t)bus, k);
2906 
2907 	return (PCICFG_SUCCESS);
2908 }
2909 
2910 static int
2911 pcicfg_free_device_resources(dev_info_t *dip, pcicfg_flags_t flags)
2912 {
2913 	pci_regspec_t *assigned;
2914 
2915 	int length;
2916 	int acount;
2917 	int i;
2918 
2919 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2920 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
2921 	    &length) != DDI_PROP_SUCCESS) {
2922 		DEBUG0("Failed to read assigned-addresses property\n");
2923 		return (PCICFG_FAILURE);
2924 	}
2925 
2926 	/*
2927 	 * For each "assigned-addresses" property entry with a length,
2928 	 * call the memory allocation routines to return the
2929 	 * resource.
2930 	 */
2931 	acount = length / sizeof (pci_regspec_t);
2932 	for (i = 0; i < acount; i++) {
2933 		/*
2934 		 * Workaround for Devconf (x86) bug to skip extra entries
2935 		 * beyond the PCI_CONF_BASE5 offset. But we want to free up
2936 		 * any memory for expansion roms if allocated.
2937 		 */
2938 		if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) > PCI_CONF_BASE5) &&
2939 		    (PCI_REG_REG_G(assigned[i].pci_phys_hi) != PCI_CONF_ROM))
2940 			break;
2941 
2942 		if (pcicfg_free_resource(dip, assigned[i], flags)) {
2943 			DEBUG1("pcicfg_free_device_resources - Trouble freeing "
2944 			    "%x\n", assigned[i].pci_phys_hi);
2945 			/*
2946 			 * Don't forget to free up memory from ddi_getlongprop
2947 			 */
2948 			kmem_free((caddr_t)assigned, length);
2949 
2950 			return (PCICFG_FAILURE);
2951 		}
2952 	}
2953 	kmem_free(assigned, length);
2954 	return (PCICFG_SUCCESS);
2955 }
2956 
2957 static int
2958 pcicfg_free_resources(dev_info_t *dip, pcicfg_flags_t flags)
2959 {
2960 	ddi_acc_handle_t handle;
2961 	uint8_t header_type;
2962 
2963 	if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2964 		DEBUG0("Failed to map config space!\n");
2965 		return (PCICFG_FAILURE);
2966 	}
2967 
2968 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2969 
2970 	(void) pci_config_teardown(&handle);
2971 
2972 	/*
2973 	 * A different algorithm is used for bridges and leaf devices.
2974 	 */
2975 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2976 		/*
2977 		 * We only support readonly probing for leaf devices.
2978 		 */
2979 		if (flags & PCICFG_FLAG_READ_ONLY)
2980 			return (PCICFG_FAILURE);
2981 
2982 		if (pcicfg_free_bridge_resources(dip) != PCICFG_SUCCESS) {
2983 			DEBUG0("Failed freeing up bridge resources\n");
2984 			return (PCICFG_FAILURE);
2985 		}
2986 	} else {
2987 		if (pcicfg_free_device_resources(dip, flags)
2988 		    != PCICFG_SUCCESS) {
2989 			DEBUG0("Failed freeing up device resources\n");
2990 			return (PCICFG_FAILURE);
2991 		}
2992 	}
2993 	return (PCICFG_SUCCESS);
2994 }
2995 
2996 #ifndef _DONT_USE_1275_GENERIC_NAMES
2997 static char *
2998 pcicfg_get_class_name(uint32_t classcode)
2999 {
3000 	struct pcicfg_name_entry *ptr;
3001 
3002 	for (ptr = &pcicfg_class_lookup[0]; ptr->name != NULL; ptr++) {
3003 		if (ptr->class_code == classcode) {
3004 			return (ptr->name);
3005 		}
3006 	}
3007 	return (NULL);
3008 }
3009 #endif /* _DONT_USE_1275_GENERIC_NAMES */
3010 
3011 static dev_info_t *
3012 pcicfg_devi_find(dev_info_t *dip, uint_t device, uint_t function)
3013 {
3014 	struct pcicfg_find_ctrl ctrl;
3015 	int count;
3016 
3017 	ctrl.device = device;
3018 	ctrl.function = function;
3019 	ctrl.dip = NULL;
3020 
3021 	ndi_devi_enter(dip, &count);
3022 	ddi_walk_devs(ddi_get_child(dip), pcicfg_match_dev, (void *)&ctrl);
3023 	ndi_devi_exit(dip, count);
3024 
3025 	return (ctrl.dip);
3026 }
3027 
3028 static int
3029 pcicfg_match_dev(dev_info_t *dip, void *hdl)
3030 {
3031 	struct pcicfg_find_ctrl *ctrl = (struct pcicfg_find_ctrl *)hdl;
3032 	pci_regspec_t *pci_rp;
3033 	int length;
3034 	int pci_dev;
3035 	int pci_func;
3036 
3037 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
3038 	    DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
3039 	    (uint_t *)&length) != DDI_PROP_SUCCESS) {
3040 		ctrl->dip = NULL;
3041 		return (DDI_WALK_TERMINATE);
3042 	}
3043 
3044 	/* get the PCI device address info */
3045 	pci_dev = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
3046 	pci_func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
3047 
3048 	/*
3049 	 * free the memory allocated by ddi_prop_lookup_int_array
3050 	 */
3051 	ddi_prop_free(pci_rp);
3052 
3053 
3054 	if ((pci_dev == ctrl->device) && (pci_func == ctrl->function)) {
3055 		/* found the match for the specified device address */
3056 		ctrl->dip = dip;
3057 		return (DDI_WALK_TERMINATE);
3058 	}
3059 
3060 	/*
3061 	 * continue the walk to the next sibling to look for a match.
3062 	 */
3063 	return (DDI_WALK_PRUNECHILD);
3064 }
3065 
3066 static int
3067 pcicfg_update_assigned_prop(dev_info_t *dip, pci_regspec_t *newone)
3068 {
3069 	int		alen;
3070 	pci_regspec_t	*assigned;
3071 	caddr_t		newreg;
3072 	uint_t		status;
3073 
3074 	DEBUG0("pcicfg_update_assigned_prop()\n");
3075 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3076 	    "assigned-addresses", (caddr_t)&assigned, &alen);
3077 	switch (status) {
3078 		case DDI_PROP_SUCCESS:
3079 		break;
3080 		case DDI_PROP_NO_MEMORY:
3081 			DEBUG0("no memory for assigned-addresses property\n");
3082 			return (PCICFG_FAILURE);
3083 		default:
3084 			(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3085 			    "assigned-addresses", (int *)newone,
3086 			    sizeof (*newone)/sizeof (int));
3087 
3088 			(void) pcicfg_dump_assigned(dip);
3089 
3090 			return (PCICFG_SUCCESS);
3091 	}
3092 
3093 	/*
3094 	 * Allocate memory for the existing
3095 	 * assigned-addresses(s) plus one and then
3096 	 * build it.
3097 	 */
3098 
3099 	newreg = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
3100 
3101 	bcopy(assigned, newreg, alen);
3102 	bcopy(newone, newreg + alen, sizeof (*newone));
3103 
3104 	/*
3105 	 * Write out the new "assigned-addresses" spec
3106 	 */
3107 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3108 	    "assigned-addresses", (int *)newreg,
3109 	    (alen + sizeof (*newone))/sizeof (int));
3110 
3111 	kmem_free((caddr_t)newreg, alen+sizeof (*newone));
3112 
3113 	/*
3114 	 * Don't forget to free up memory from ddi_getlongprop
3115 	 */
3116 	kmem_free((caddr_t)assigned, alen);
3117 
3118 	(void) pcicfg_dump_assigned(dip);
3119 
3120 	return (PCICFG_SUCCESS);
3121 }
3122 static int
3123 pcicfg_update_ranges_prop(dev_info_t *dip, pcicfg_range_t *addition)
3124 {
3125 	int		rlen;
3126 	pcicfg_range_t	*ranges;
3127 	caddr_t		newreg;
3128 	uint_t		status;
3129 
3130 	status = ddi_getlongprop(DDI_DEV_T_ANY,
3131 	    dip, DDI_PROP_DONTPASS, "ranges", (caddr_t)&ranges, &rlen);
3132 
3133 
3134 	switch (status) {
3135 		case DDI_PROP_SUCCESS:
3136 		break;
3137 		case DDI_PROP_NO_MEMORY:
3138 			DEBUG0("ranges present, but unable to get memory\n");
3139 			return (PCICFG_FAILURE);
3140 		default:
3141 			DEBUG0("no ranges property - creating one\n");
3142 			if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
3143 			    dip, "ranges", (int *)addition,
3144 			    sizeof (pcicfg_range_t)/sizeof (int))
3145 			    != DDI_SUCCESS) {
3146 				DEBUG0("Did'nt create ranges property\n");
3147 				return (PCICFG_FAILURE);
3148 			}
3149 			return (PCICFG_SUCCESS);
3150 	}
3151 
3152 	/*
3153 	 * Allocate memory for the existing reg(s) plus one and then
3154 	 * build it.
3155 	 */
3156 	newreg = kmem_zalloc(rlen + sizeof (pcicfg_range_t), KM_SLEEP);
3157 
3158 	bcopy(ranges, newreg, rlen);
3159 	bcopy(addition, newreg + rlen, sizeof (pcicfg_range_t));
3160 
3161 	/*
3162 	 * Write out the new "ranges" property
3163 	 */
3164 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3165 	    dip, "ranges", (int *)newreg,
3166 	    (rlen + sizeof (pcicfg_range_t))/sizeof (int));
3167 
3168 	kmem_free((caddr_t)newreg, rlen+sizeof (pcicfg_range_t));
3169 
3170 	kmem_free((caddr_t)ranges, rlen);
3171 
3172 	return (PCICFG_SUCCESS);
3173 }
3174 
3175 static int
3176 pcicfg_update_reg_prop(dev_info_t *dip, uint32_t regvalue, uint_t reg_offset)
3177 {
3178 	int		rlen;
3179 	pci_regspec_t	*reg;
3180 	caddr_t		newreg;
3181 	uint32_t	hiword;
3182 	pci_regspec_t	addition;
3183 	uint32_t	size;
3184 	uint_t		status;
3185 
3186 	status = ddi_getlongprop(DDI_DEV_T_ANY,
3187 	    dip, DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &rlen);
3188 
3189 	switch (status) {
3190 		case DDI_PROP_SUCCESS:
3191 		break;
3192 		case DDI_PROP_NO_MEMORY:
3193 			DEBUG0("reg present, but unable to get memory\n");
3194 			return (PCICFG_FAILURE);
3195 		default:
3196 			DEBUG0("no reg property\n");
3197 			return (PCICFG_FAILURE);
3198 	}
3199 
3200 	/*
3201 	 * Allocate memory for the existing reg(s) plus one and then
3202 	 * build it.
3203 	 */
3204 	newreg = kmem_zalloc(rlen+sizeof (pci_regspec_t), KM_SLEEP);
3205 
3206 	/*
3207 	 * Build the regspec, then add it to the existing one(s)
3208 	 */
3209 
3210 	hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3211 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3212 	    PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3213 
3214 	if (reg_offset == PCI_CONF_ROM) {
3215 		size = (~(PCI_BASE_ROM_ADDR_M & regvalue))+1;
3216 		hiword |= PCI_ADDR_MEM32;
3217 	} else {
3218 		size = (~(PCI_BASE_M_ADDR_M & regvalue))+1;
3219 
3220 		if ((PCI_BASE_SPACE_M & regvalue) == PCI_BASE_SPACE_MEM) {
3221 			if ((PCI_BASE_TYPE_M & regvalue) == PCI_BASE_TYPE_MEM) {
3222 				hiword |= PCI_ADDR_MEM32;
3223 			} else if ((PCI_BASE_TYPE_M & regvalue)
3224 			    == PCI_BASE_TYPE_ALL) {
3225 				hiword |= PCI_ADDR_MEM64;
3226 			}
3227 		} else {
3228 			hiword |= PCI_ADDR_IO;
3229 		}
3230 	}
3231 
3232 	addition.pci_phys_hi = hiword;
3233 	addition.pci_phys_mid = 0;
3234 	addition.pci_phys_low = 0;
3235 	addition.pci_size_hi = 0;
3236 	addition.pci_size_low = size;
3237 
3238 	bcopy(reg, newreg, rlen);
3239 	bcopy(&addition, newreg + rlen, sizeof (pci_regspec_t));
3240 
3241 	/*
3242 	 * Write out the new "reg" property
3243 	 */
3244 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3245 	    dip, "reg", (int *)newreg,
3246 	    (rlen + sizeof (pci_regspec_t))/sizeof (int));
3247 
3248 	kmem_free((caddr_t)newreg, rlen+sizeof (pci_regspec_t));
3249 	kmem_free((caddr_t)reg, rlen);
3250 
3251 	return (PCICFG_SUCCESS);
3252 }
3253 static int
3254 pcicfg_update_available_prop(dev_info_t *dip, pci_regspec_t *newone)
3255 {
3256 	int		alen;
3257 	pci_regspec_t	*avail_p;
3258 	caddr_t		new_avail;
3259 	uint_t		status;
3260 
3261 	DEBUG2("pcicfg_update_available_prop() - Address %lx Size %x\n",
3262 	    newone->pci_phys_low, newone->pci_size_low);
3263 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3264 	    "available", (caddr_t)&avail_p, &alen);
3265 	switch (status) {
3266 		case DDI_PROP_SUCCESS:
3267 			break;
3268 		case DDI_PROP_NO_MEMORY:
3269 			DEBUG0("no memory for available property\n");
3270 			return (PCICFG_FAILURE);
3271 		default:
3272 			(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3273 			    "available", (int *)newone,
3274 			    sizeof (*newone)/sizeof (int));
3275 
3276 			return (PCICFG_SUCCESS);
3277 	}
3278 
3279 	/*
3280 	 * Allocate memory for the existing available plus one and then
3281 	 * build it.
3282 	 */
3283 	new_avail = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
3284 
3285 	bcopy(avail_p, new_avail, alen);
3286 	bcopy(newone, new_avail + alen, sizeof (*newone));
3287 
3288 	/* Write out the new "available" spec */
3289 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3290 	    "available", (int *)new_avail,
3291 	    (alen + sizeof (*newone))/sizeof (int));
3292 
3293 	kmem_free((caddr_t)new_avail, alen+sizeof (*newone));
3294 
3295 	/* Don't forget to free up memory from ddi_getlongprop */
3296 	kmem_free((caddr_t)avail_p, alen);
3297 
3298 	return (PCICFG_SUCCESS);
3299 }
3300 
3301 static int
3302 pcicfg_update_assigned_prop_value(dev_info_t *dip, uint32_t size,
3303     uint32_t base, uint32_t base_hi, uint_t reg_offset)
3304 {
3305 	int		rlen;
3306 	pci_regspec_t	*reg;
3307 	uint32_t	hiword;
3308 	pci_regspec_t	addition;
3309 	uint_t		status;
3310 
3311 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3312 	    "reg", (caddr_t)&reg, &rlen);
3313 
3314 	switch (status) {
3315 		case DDI_PROP_SUCCESS:
3316 		break;
3317 		case DDI_PROP_NO_MEMORY:
3318 			DEBUG0("reg present, but unable to get memory\n");
3319 			return (PCICFG_FAILURE);
3320 		default:
3321 			/*
3322 			 * Since the config space "reg" entry should have been
3323 			 * created, we expect a "reg" property already
3324 			 * present here.
3325 			 */
3326 			DEBUG0("no reg property\n");
3327 			return (PCICFG_FAILURE);
3328 	}
3329 
3330 	/*
3331 	 * Build the regspec, then add it to the existing one(s)
3332 	 */
3333 
3334 	hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3335 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3336 	    PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3337 
3338 	hiword |= PCI_REG_REL_M;
3339 
3340 	if (reg_offset == PCI_CONF_ROM) {
3341 		hiword |= PCI_ADDR_MEM32;
3342 
3343 		base = PCI_BASE_ROM_ADDR_M & base;
3344 	} else {
3345 		if ((PCI_BASE_SPACE_M & base) == PCI_BASE_SPACE_MEM) {
3346 			if ((PCI_BASE_TYPE_M & base) == PCI_BASE_TYPE_MEM) {
3347 				hiword |= PCI_ADDR_MEM32;
3348 			} else if ((PCI_BASE_TYPE_M & base)
3349 			    == PCI_BASE_TYPE_ALL) {
3350 				hiword |= PCI_ADDR_MEM64;
3351 			}
3352 
3353 			if (base & PCI_BASE_PREF_M)
3354 				hiword |= PCI_REG_PF_M;
3355 
3356 			base = PCI_BASE_M_ADDR_M & base;
3357 		} else {
3358 			hiword |= PCI_ADDR_IO;
3359 
3360 			base = PCI_BASE_IO_ADDR_M & base;
3361 			base_hi = 0;
3362 		}
3363 	}
3364 
3365 	addition.pci_phys_hi = hiword;
3366 	addition.pci_phys_mid = base_hi;
3367 	addition.pci_phys_low = base;
3368 	addition.pci_size_hi = 0;
3369 	addition.pci_size_low = size;
3370 
3371 	DEBUG3("updating BAR@off %x with %x,%x\n", reg_offset, hiword, size);
3372 
3373 	kmem_free((caddr_t)reg, rlen);
3374 
3375 	return (pcicfg_update_assigned_prop(dip, &addition));
3376 }
3377 
3378 static void
3379 pcicfg_device_on(ddi_acc_handle_t config_handle)
3380 {
3381 	/*
3382 	 * Enable memory, IO, and bus mastership
3383 	 * XXX should we enable parity, SERR#,
3384 	 * fast back-to-back, and addr. stepping?
3385 	 */
3386 	pci_config_put16(config_handle, PCI_CONF_COMM,
3387 	    pci_config_get16(config_handle, PCI_CONF_COMM) | 0x7);
3388 }
3389 
3390 static void
3391 pcicfg_device_off(ddi_acc_handle_t config_handle)
3392 {
3393 	/*
3394 	 * Disable I/O and memory traffic through the bridge
3395 	 */
3396 	pci_config_put16(config_handle, PCI_CONF_COMM, 0x0);
3397 }
3398 
3399 /*
3400  * Setup the basic 1275 properties based on information found in the config
3401  * header of the PCI device
3402  */
3403 static int
3404 pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3405     uint8_t pcie_dev)
3406 {
3407 	int ret;
3408 	uint16_t val, cap_ptr;
3409 	uint32_t wordval;
3410 	uint8_t byteval;
3411 
3412 	/* These two exists only for non-bridges */
3413 	if (((pci_config_get8(config_handle, PCI_CONF_HEADER)
3414 	    & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) && !pcie_dev) {
3415 		byteval = pci_config_get8(config_handle, PCI_CONF_MIN_G);
3416 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3417 		    "min-grant", byteval)) != DDI_SUCCESS) {
3418 			return (ret);
3419 		}
3420 
3421 		byteval = pci_config_get8(config_handle, PCI_CONF_MAX_L);
3422 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3423 		    "max-latency", byteval)) != DDI_SUCCESS) {
3424 			return (ret);
3425 		}
3426 	}
3427 
3428 	/*
3429 	 * These should always exist and have the value of the
3430 	 * corresponding register value
3431 	 */
3432 	val = pci_config_get16(config_handle, PCI_CONF_VENID);
3433 
3434 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3435 	    "vendor-id", val)) != DDI_SUCCESS) {
3436 		return (ret);
3437 	}
3438 	val = pci_config_get16(config_handle, PCI_CONF_DEVID);
3439 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3440 	    "device-id", val)) != DDI_SUCCESS) {
3441 		return (ret);
3442 	}
3443 	byteval = pci_config_get8(config_handle, PCI_CONF_REVID);
3444 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3445 	    "revision-id", byteval)) != DDI_SUCCESS) {
3446 		return (ret);
3447 	}
3448 
3449 	wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3450 	    (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3451 
3452 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3453 	    "class-code", wordval)) != DDI_SUCCESS) {
3454 		return (ret);
3455 	}
3456 	/* devsel-speed starts at the 9th bit */
3457 	val = (pci_config_get16(config_handle,
3458 	    PCI_CONF_STAT) & PCI_STAT_DEVSELT) >> 9;
3459 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3460 	    "devsel-speed", val)) != DDI_SUCCESS) {
3461 		return (ret);
3462 	}
3463 
3464 	/*
3465 	 * The next three are bits set in the status register.  The property is
3466 	 * present (but with no value other than its own existence) if the bit
3467 	 * is set, non-existent otherwise
3468 	 */
3469 	if ((!pcie_dev) &&
3470 	    (pci_config_get16(config_handle, PCI_CONF_STAT) &
3471 	    PCI_STAT_FBBC)) {
3472 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3473 		    "fast-back-to-back", 0)) != DDI_SUCCESS) {
3474 			return (ret);
3475 		}
3476 	}
3477 	if ((!pcie_dev) &&
3478 	    (pci_config_get16(config_handle, PCI_CONF_STAT) &
3479 	    PCI_STAT_66MHZ)) {
3480 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3481 		    "66mhz-capable", 0)) != DDI_SUCCESS) {
3482 			return (ret);
3483 		}
3484 	}
3485 	if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_UDF) {
3486 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3487 		    "udf-supported", 0)) != DDI_SUCCESS) {
3488 			return (ret);
3489 		}
3490 	}
3491 
3492 	/*
3493 	 * These next three are optional and are not present
3494 	 * if the corresponding register is zero.  If the value
3495 	 * is non-zero then the property exists with the value
3496 	 * of the register.
3497 	 */
3498 	if ((val = pci_config_get16(config_handle,
3499 	    PCI_CONF_SUBVENID)) != 0) {
3500 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3501 		    "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3502 			return (ret);
3503 		}
3504 	}
3505 	if ((val = pci_config_get16(config_handle,
3506 	    PCI_CONF_SUBSYSID)) != 0) {
3507 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3508 		    "subsystem-id", val)) != DDI_SUCCESS) {
3509 			return (ret);
3510 		}
3511 	}
3512 	if ((val = pci_config_get16(config_handle,
3513 	    PCI_CONF_CACHE_LINESZ)) != 0) {
3514 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3515 		    "cache-line-size", val)) != DDI_SUCCESS) {
3516 			return (ret);
3517 		}
3518 	}
3519 
3520 	/*
3521 	 * If the Interrupt Pin register is non-zero then the
3522 	 * interrupts property exists
3523 	 */
3524 	if ((byteval = pci_config_get8(config_handle, PCI_CONF_IPIN)) != 0) {
3525 		/*
3526 		 * If interrupt pin is non-zero,
3527 		 * record the interrupt line used
3528 		 */
3529 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3530 		    "interrupts", byteval)) != DDI_SUCCESS) {
3531 			return (ret);
3532 		}
3533 	}
3534 
3535 	ret = PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_ptr);
3536 
3537 	if (pcie_dev && (ret == DDI_SUCCESS)) {
3538 		val = PCI_CAP_GET16(config_handle, NULL, cap_ptr,
3539 		    PCIE_PCIECAP) & PCIE_PCIECAP_SLOT_IMPL;
3540 		/* if slot implemented, get physical slot number */
3541 		if (val) {
3542 			wordval = (PCI_CAP_GET32(config_handle, NULL,
3543 			    cap_ptr, PCIE_SLOTCAP) >>
3544 			    PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT) &
3545 			    PCIE_SLOTCAP_PHY_SLOT_NUM_MASK;
3546 			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE,
3547 			    dip, "physical-slot#", wordval))
3548 			    != DDI_SUCCESS) {
3549 				return (ret);
3550 			}
3551 		}
3552 	}
3553 	return (PCICFG_SUCCESS);
3554 }
3555 static int
3556 pcicfg_set_busnode_props(dev_info_t *dip, uint8_t pcie_device_type,
3557     int pbus, int sbus)
3558 {
3559 	int ret;
3560 	char device_type[8];
3561 
3562 	if (pcie_device_type)
3563 		(void) strcpy(device_type, "pciex");
3564 	else
3565 		(void) strcpy(device_type, "pci");
3566 
3567 	if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
3568 	    "device_type", device_type)) != DDI_SUCCESS) {
3569 		return (ret);
3570 	}
3571 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3572 	    "#address-cells", 3)) != DDI_SUCCESS) {
3573 		return (ret);
3574 	}
3575 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3576 	    "#size-cells", 2)) != DDI_SUCCESS) {
3577 		return (ret);
3578 	}
3579 
3580 	/*
3581 	 * Create primary-bus and secondary-bus properties to be used
3582 	 * to restore bus numbers in the pcicfg_setup_bridge() routine.
3583 	 */
3584 	if (pbus != -1 && sbus != -1) {
3585 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3586 		    "primary-bus", pbus)) != DDI_SUCCESS) {
3587 				return (ret);
3588 		}
3589 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3590 		    "secondary-bus", sbus)) != DDI_SUCCESS) {
3591 				return (ret);
3592 		}
3593 	}
3594 	return (PCICFG_SUCCESS);
3595 }
3596 
3597 static int
3598 pcicfg_set_childnode_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3599     uint8_t pcie_dev)
3600 {
3601 
3602 	int		ret;
3603 	char		*name;
3604 	char		buffer[64], pprefix[8];
3605 	uint16_t	classcode;
3606 	uint8_t		revid, pif, pclass, psubclass;
3607 	char		*compat[24];
3608 	int		i;
3609 	int		n;
3610 	uint16_t		sub_vid, sub_sid, vid, did;
3611 
3612 	/* set the property prefix based on the device type */
3613 	if (pcie_dev)
3614 		(void) sprintf(pprefix, "pciex");
3615 	else
3616 		(void) sprintf(pprefix, "pci");
3617 	sub_vid = pci_config_get16(config_handle, PCI_CONF_SUBVENID);
3618 	sub_sid = pci_config_get16(config_handle, PCI_CONF_SUBSYSID);
3619 	vid = pci_config_get16(config_handle, PCI_CONF_VENID);
3620 	did = pci_config_get16(config_handle, PCI_CONF_DEVID);
3621 	revid = pci_config_get8(config_handle, PCI_CONF_REVID);
3622 	pif = pci_config_get8(config_handle, PCI_CONF_PROGCLASS);
3623 	classcode = pci_config_get16(config_handle, PCI_CONF_SUBCLASS);
3624 	pclass = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
3625 	psubclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
3626 
3627 	/*
3628 	 * NOTE: These are for both a child and PCI-PCI bridge node
3629 	 */
3630 
3631 	/*
3632 	 *	"name" property rule
3633 	 *	--------------------
3634 	 *
3635 	 *
3636 	 * |	  \svid |
3637 	 * |	   \    |
3638 	 * |	    \   |
3639 	 * |	ssid \  |	=0		|	!= 0		|
3640 	 * |------------|-----------------------|-----------------------|
3641 	 * |		|			|			|
3642 	 * |	=0	|	vid,did		|	svid,ssid	|
3643 	 * |		|			|			|
3644 	 * |------------|-----------------------|-----------------------|
3645 	 * |		|			|			|
3646 	 * |	!=0	|	svid,ssid	|	svid,ssid	|
3647 	 * |		|			|			|
3648 	 * |------------|-----------------------|-----------------------|
3649 	 *
3650 	 * where:
3651 	 *    vid = vendor id
3652 	 *    did = device id
3653 	 *   svid = subsystem vendor id
3654 	 *   ssid = subsystem id
3655 	 */
3656 
3657 	if ((sub_sid != 0) || (sub_vid != 0)) {
3658 		(void) sprintf(buffer, "%s%x,%x", pprefix, sub_vid, sub_sid);
3659 	} else {
3660 		(void) sprintf(buffer, "%s%x,%x", pprefix, vid, did);
3661 	}
3662 
3663 	/*
3664 	 * In some environments, trying to use "generic" 1275 names is
3665 	 * not the convention.  In those cases use the name as created
3666 	 * above.  In all the rest of the cases, check to see if there
3667 	 * is a generic name first.
3668 	 */
3669 #ifdef _DONT_USE_1275_GENERIC_NAMES
3670 	name = buffer;
3671 #else
3672 	if ((name = pcicfg_get_class_name(classcode)) == NULL) {
3673 		/*
3674 		 * Set name to the above fabricated name
3675 		 */
3676 		name = buffer;
3677 	}
3678 #endif
3679 
3680 	/*
3681 	 * The node name field needs to be filled in with the name
3682 	 */
3683 	if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3684 		DEBUG0("Failed to set nodename for node\n");
3685 		return (PCICFG_FAILURE);
3686 	}
3687 
3688 	/*
3689 	 * Create the compatible property as an array of pointers
3690 	 * to strings.  Start with the buffer created above.
3691 	 */
3692 	n = 0;
3693 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3694 	(void) strcpy(compat[n++], buffer);
3695 
3696 	/*
3697 	 * Setup 'compatible' as per the PCI2.1 bindings document.
3698 	 *	pci[ex]VVVV,DDDD.SSSS.ssss.RR
3699 	 *	pci[ex]VVVV,DDDD.SSSS.ssss
3700 	 *	pciSSSS.ssss  -> not created for PCIe as per PCIe bindings
3701 	 *	pci[ex]VVVV,DDDD.RR
3702 	 *	pci[ex]VVVV,DDDD
3703 	 *	pci[ex]class,CCSSPP
3704 	 *	pci[ex]class,CCSS
3705 	 */
3706 
3707 	/* pci[ex]VVVV,DDDD.SSSS.ssss.RR */
3708 	(void) sprintf(buffer, "%s%x,%x.%x.%x.%x", pprefix,  vid, did,
3709 	    sub_vid, sub_sid, revid);
3710 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3711 	(void) strcpy(compat[n++], buffer);
3712 
3713 	/* pci[ex]VVVV,DDDD.SSSS.ssss */
3714 	(void) sprintf(buffer, "%s%x,%x.%x.%x", pprefix,  vid, did,
3715 	    sub_vid, sub_sid);
3716 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3717 	(void) strcpy(compat[n++], buffer);
3718 
3719 	/* pciSSSS.ssss  -> not created for PCIe as per PCIe bindings */
3720 	if (!pcie_dev) {
3721 		(void) sprintf(buffer, "pci%x,%x,s", sub_vid, sub_sid);
3722 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3723 		(void) strcpy(compat[n++], buffer);
3724 
3725 		(void) sprintf(buffer, "pci%x,%x", sub_vid, sub_sid);
3726 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3727 		(void) strcpy(compat[n++], buffer);
3728 	}
3729 
3730 	/* pci[ex]VVVV,DDDD.RR */
3731 	(void) sprintf(buffer, "%s%x,%x.%x", pprefix,  vid, did, revid);
3732 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3733 	(void) strcpy(compat[n++], buffer);
3734 
3735 	/* pci[ex]VVVV,DDDD */
3736 	(void) sprintf(buffer, "%s%x,%x", pprefix, vid, did);
3737 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3738 	(void) strcpy(compat[n++], buffer);
3739 
3740 	if (!pcie_dev) {
3741 		(void) sprintf(buffer, "%s%x,%x,p", pprefix, vid, did);
3742 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3743 		(void) strcpy(compat[n++], buffer);
3744 	}
3745 
3746 	/* pci[ex]class,CCSSPP */
3747 	(void) sprintf(buffer, "%sclass,%02x%02x%02x", pprefix,
3748 	    pclass, psubclass, pif);
3749 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3750 	(void) strcpy(compat[n++], buffer);
3751 
3752 	/* pci[ex]class,CCSS */
3753 	(void) sprintf(buffer, "%sclass,%04x", pprefix, classcode);
3754 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3755 	(void) strcpy(compat[n++], buffer);
3756 
3757 	if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
3758 	    "compatible", (char **)compat, n)) != DDI_SUCCESS) {
3759 		return (ret);
3760 	}
3761 
3762 	for (i = 0; i < n; i++) {
3763 		kmem_free(compat[i], strlen(compat[i]) + 1);
3764 	}
3765 
3766 	DEBUG1("pcicfg_set_childnode_props - creating name=%s\n", name);
3767 	if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
3768 	    "name", name)) != DDI_SUCCESS) {
3769 
3770 		DEBUG0("pcicfg_set_childnode_props - Unable to create name "
3771 		    "property\n");
3772 
3773 		return (ret);
3774 	}
3775 
3776 	return (PCICFG_SUCCESS);
3777 }
3778 
3779 /*
3780  * Program the bus numbers into the bridge
3781  */
3782 
3783 static void
3784 pcicfg_set_bus_numbers(ddi_acc_handle_t config_handle,
3785     uint_t primary, uint_t secondary, uint_t subordinate)
3786 {
3787 	DEBUG3("Setting bridge bus-range %d,%d,%d\n", primary, secondary,
3788 	    subordinate);
3789 	/*
3790 	 * Primary bus#
3791 	 */
3792 	pci_config_put8(config_handle, PCI_BCNF_PRIBUS, primary);
3793 
3794 	/*
3795 	 * Secondary bus#
3796 	 */
3797 	pci_config_put8(config_handle, PCI_BCNF_SECBUS, secondary);
3798 
3799 	/*
3800 	 * Subordinate bus#
3801 	 */
3802 	pci_config_put8(config_handle, PCI_BCNF_SUBBUS, subordinate);
3803 }
3804 
3805 /*
3806  * Put bridge registers into initial state
3807  */
3808 static void
3809 pcicfg_setup_bridge(pcicfg_phdl_t *entry,
3810     ddi_acc_handle_t handle, dev_info_t *dip)
3811 {
3812 	int pbus, sbus;
3813 
3814 	/*
3815 	 * The highest bus seen during probing is the max-subordinate bus
3816 	 */
3817 	pci_config_put8(handle, PCI_BCNF_SUBBUS, entry->highest_bus);
3818 
3819 
3820 	/*
3821 	 * If there exists more than 1 downstream bridge, it
3822 	 * will be reset by the below secondary bus reset which
3823 	 * will clear the bus numbers assumed to be programmed in
3824 	 * the pcicfg_probe_children() routine.  We therefore restore
3825 	 * them here.
3826 	 */
3827 	if (pci_config_get8(handle, PCI_BCNF_SECBUS) == 0) {
3828 		pbus = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3829 		    DDI_PROP_DONTPASS, "primary-bus", -1);
3830 		sbus = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3831 		    DDI_PROP_DONTPASS, "secondary-bus", -1);
3832 		if (pbus != -1 && sbus != -1) {
3833 			pci_config_put8(handle, PCI_BCNF_PRIBUS, (uint_t)pbus);
3834 			pci_config_put8(handle, PCI_BCNF_SECBUS, (uint_t)sbus);
3835 		} else {
3836 			cmn_err(CE_WARN, "Invalid Bridge number detected: \
3837 			    %s%d: pbus = 0x%x, sbus = 0x%x",
3838 			    ddi_get_name(dip), ddi_get_instance(dip), pbus,
3839 			    sbus);
3840 		}
3841 	}
3842 
3843 	/*
3844 	 * Reset the secondary bus
3845 	 */
3846 	pci_config_put16(handle, PCI_BCNF_BCNTRL,
3847 	    pci_config_get16(handle, PCI_BCNF_BCNTRL) | 0x40);
3848 
3849 	drv_usecwait(100);
3850 
3851 	pci_config_put16(handle, PCI_BCNF_BCNTRL,
3852 	    pci_config_get16(handle, PCI_BCNF_BCNTRL) & ~0x40);
3853 
3854 	/*
3855 	 * Program the memory base register with the
3856 	 * start of the memory range
3857 	 */
3858 	pci_config_put16(handle, PCI_BCNF_MEM_BASE,
3859 	    PCICFG_HIWORD(PCICFG_LOADDR(entry->memory_last)));
3860 
3861 	/*
3862 	 * Program the I/O base register with the start of the I/O range
3863 	 */
3864 	pci_config_put8(handle, PCI_BCNF_IO_BASE_LOW,
3865 	    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(entry->io_last))));
3866 	pci_config_put16(handle, PCI_BCNF_IO_BASE_HI,
3867 	    PCICFG_HIWORD(PCICFG_LOADDR(entry->io_last)));
3868 
3869 	/*
3870 	 * Clear status bits
3871 	 */
3872 	pci_config_put16(handle, PCI_BCNF_SEC_STATUS, 0xffff);
3873 
3874 	/*
3875 	 * Turn off prefetchable range
3876 	 */
3877 	pci_config_put32(handle, PCI_BCNF_PF_BASE_LOW, 0x0000ffff);
3878 	pci_config_put32(handle, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
3879 	pci_config_put32(handle, PCI_BCNF_PF_LIMIT_HIGH, 0x0);
3880 
3881 	/*
3882 	 * Needs to be set to this value
3883 	 */
3884 	pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
3885 
3886 	/*
3887 	 * After a Reset, we need to wait 2^25 clock cycles before the
3888 	 * first Configuration access.  The worst case is 33MHz, which
3889 	 * is a 1 second wait.
3890 	 */
3891 	drv_usecwait(pcicfg_sec_reset_delay);
3892 
3893 }
3894 
3895 static void
3896 pcicfg_update_bridge(pcicfg_phdl_t *entry,
3897     ddi_acc_handle_t handle)
3898 {
3899 	uint_t length;
3900 
3901 	/*
3902 	 * Program the memory limit register with the end of the memory range
3903 	 */
3904 
3905 	DEBUG1("DOWN ROUNDED ===>[0x%x]\n",
3906 	    PCICFG_ROUND_DOWN(entry->memory_last,
3907 	    PCICFG_MEMGRAN));
3908 
3909 	pci_config_put16(handle, PCI_BCNF_MEM_LIMIT,
3910 	    PCICFG_HIWORD(PCICFG_LOADDR(
3911 	    PCICFG_ROUND_DOWN(entry->memory_last,
3912 	    PCICFG_MEMGRAN))));
3913 	/*
3914 	 * Since this is a bridge, the rest of this range will
3915 	 * be responded to by the bridge.  We have to round up
3916 	 * so no other device claims it.
3917 	 */
3918 	if ((length = (PCICFG_ROUND_UP(entry->memory_last,
3919 	    PCICFG_MEMGRAN) - entry->memory_last)) > 0) {
3920 		(void) pcicfg_get_mem(entry, length, NULL);
3921 		DEBUG1("Added [0x%x]at the top of "
3922 		    "the bridge (mem)\n", length);
3923 	}
3924 
3925 	/*
3926 	 * Program the I/O limit register with the end of the I/O range
3927 	 */
3928 	pci_config_put8(handle, PCI_BCNF_IO_LIMIT_LOW,
3929 	    PCICFG_HIBYTE(PCICFG_LOWORD(
3930 	    PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last,
3931 	    PCICFG_IOGRAN)))));
3932 
3933 	pci_config_put16(handle, PCI_BCNF_IO_LIMIT_HI,
3934 	    PCICFG_HIWORD(PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last,
3935 	    PCICFG_IOGRAN))));
3936 
3937 	/*
3938 	 * Same as above for I/O space. Since this is a
3939 	 * bridge, the rest of this range will be responded
3940 	 * to by the bridge.  We have to round up so no
3941 	 * other device claims it.
3942 	 */
3943 	if ((length = (PCICFG_ROUND_UP(entry->io_last,
3944 	    PCICFG_IOGRAN) - entry->io_last)) > 0) {
3945 		(void) pcicfg_get_io(entry, length, NULL);
3946 		DEBUG1("Added [0x%x]at the top of "
3947 		    "the bridge (I/O)\n",  length);
3948 	}
3949 }
3950 
3951 /*ARGSUSED*/
3952 static void
3953 pcicfg_disable_bridge_probe_err(dev_info_t *dip, ddi_acc_handle_t h,
3954     pcicfg_err_regs_t *regs)
3955 {
3956 	uint16_t val;
3957 
3958 	/* disable SERR generated in the context of Master Aborts. */
3959 	regs->cmd = val = pci_config_get16(h, PCI_CONF_COMM);
3960 	val &= ~PCI_COMM_SERR_ENABLE;
3961 	pci_config_put16(h, PCI_CONF_COMM, val);
3962 	regs->bcntl = val = pci_config_get16(h, PCI_BCNF_BCNTRL);
3963 	val &= ~PCI_BCNF_BCNTRL_SERR_ENABLE;
3964 	pci_config_put16(h, PCI_BCNF_BCNTRL, val);
3965 	/* clear any current pending errors */
3966 	pci_config_put16(h, PCI_CONF_STAT, PCI_STAT_S_TARG_AB|
3967 	    PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3968 	pci_config_put16(h, PCI_BCNF_SEC_STATUS, PCI_STAT_S_TARG_AB|
3969 	    PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3970 	/* if we are a PCIe device, disable the generation of UR, CE and NFE */
3971 	if (regs->pcie_dev) {
3972 		uint16_t devctl;
3973 		uint16_t cap_ptr;
3974 
3975 		if ((PCI_CAP_LOCATE(h, PCI_CAP_ID_PCI_E, &cap_ptr)) ==
3976 		    DDI_FAILURE)
3977 			return;
3978 
3979 		regs->pcie_cap_off = cap_ptr;
3980 		regs->devctl = devctl = PCI_CAP_GET16(h, NULL, cap_ptr,
3981 		    PCIE_DEVCTL);
3982 		devctl &= ~(PCIE_DEVCTL_UR_REPORTING_EN |
3983 		    PCIE_DEVCTL_CE_REPORTING_EN |
3984 		    PCIE_DEVCTL_NFE_REPORTING_EN |
3985 		    PCIE_DEVCTL_FE_REPORTING_EN);
3986 		PCI_CAP_PUT16(h, NULL, cap_ptr, PCIE_DEVCTL, devctl);
3987 	}
3988 }
3989 
3990 /*ARGSUSED*/
3991 static void
3992 pcicfg_enable_bridge_probe_err(dev_info_t *dip, ddi_acc_handle_t h,
3993     pcicfg_err_regs_t *regs)
3994 {
3995 	/* clear any pending errors */
3996 	pci_config_put16(h, PCI_CONF_STAT, PCI_STAT_S_TARG_AB|
3997 	    PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3998 	pci_config_put16(h, PCI_BCNF_SEC_STATUS, PCI_STAT_S_TARG_AB|
3999 	    PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
4000 
4001 	/* restore original settings */
4002 	if (regs->pcie_dev) {
4003 		pcie_clear_errors(dip);
4004 		pci_config_put16(h, regs->pcie_cap_off + PCIE_DEVCTL,
4005 		    regs->devctl);
4006 	}
4007 
4008 	pci_config_put16(h, PCI_BCNF_BCNTRL, regs->bcntl);
4009 	pci_config_put16(h, PCI_CONF_COMM, regs->cmd);
4010 
4011 }
4012 
4013 static int
4014 pcicfg_probe_children(dev_info_t *parent, uint_t bus, uint_t device,
4015     uint_t func, uint_t *highest_bus, pcicfg_flags_t flags, boolean_t is_pcie)
4016 {
4017 	dev_info_t		*new_child;
4018 	ddi_acc_handle_t	config_handle;
4019 	uint8_t			header_type, pcie_dev = 0;
4020 	int			ret;
4021 	pcicfg_err_regs_t	regs;
4022 
4023 	/*
4024 	 * This node will be put immediately below
4025 	 * "parent". Allocate a blank device node.  It will either
4026 	 * be filled in or freed up based on further probing.
4027 	 */
4028 	/*
4029 	 * Note: in usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c
4030 	 * ndi_devi_alloc() is called as ndi_devi_alloc_sleep()
4031 	 */
4032 	if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
4033 	    (pnode_t)DEVI_SID_NODEID, &new_child)
4034 	    != NDI_SUCCESS) {
4035 		DEBUG0("pcicfg_probe_children(): Failed to alloc child node\n");
4036 		return (PCICFG_FAILURE);
4037 	}
4038 
4039 	if (pcicfg_add_config_reg(new_child, bus,
4040 	    device, func) != DDI_SUCCESS) {
4041 		DEBUG0("pcicfg_probe_children():"
4042 		    "Failed to add candidate REG\n");
4043 		goto failedconfig;
4044 	}
4045 
4046 	if ((ret = pcicfg_config_setup(new_child, &config_handle))
4047 	    != PCICFG_SUCCESS) {
4048 		if (ret == PCICFG_NODEVICE) {
4049 			(void) ndi_devi_free(new_child);
4050 			return (ret);
4051 		}
4052 		DEBUG0("pcicfg_probe_children():"
4053 		    "Failed to setup config space\n");
4054 		goto failedconfig;
4055 	}
4056 
4057 	if (is_pcie)
4058 		(void) pcie_init_bus(new_child, PCI_GETBDF(bus, device, func),
4059 		    PCIE_BUS_INITIAL);
4060 
4061 	/*
4062 	 * As soon as we have access to config space,
4063 	 * turn off device. It will get turned on
4064 	 * later (after memory is assigned).
4065 	 */
4066 	(void) pcicfg_device_off(config_handle);
4067 
4068 	/* check if we are PCIe device */
4069 	if (pcicfg_pcie_dev(new_child, PCICFG_DEVICE_TYPE_PCIE, &regs)
4070 	    == DDI_SUCCESS) {
4071 		DEBUG0("PCIe device detected\n");
4072 		pcie_dev = 1;
4073 	}
4074 
4075 	/*
4076 	 * Set 1275 properties common to all devices
4077 	 */
4078 	if (pcicfg_set_standard_props(new_child, config_handle,
4079 	    pcie_dev) != PCICFG_SUCCESS) {
4080 		DEBUG0("Failed to set standard properties\n");
4081 		goto failedchild;
4082 	}
4083 
4084 	/*
4085 	 * Child node properties  NOTE: Both for PCI-PCI bridge and child node
4086 	 */
4087 	if (pcicfg_set_childnode_props(new_child, config_handle,
4088 	    pcie_dev) != PCICFG_SUCCESS) {
4089 		goto failedchild;
4090 	}
4091 
4092 	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
4093 
4094 	/*
4095 	 * If this is not a multi-function card only probe function zero.
4096 	 */
4097 	if ((!(header_type & PCI_HEADER_MULTI)) && (func != 0)) {
4098 
4099 		(void) pcicfg_config_teardown(&config_handle);
4100 		(void) ndi_devi_free(new_child);
4101 		return (PCICFG_NODEVICE);
4102 	}
4103 
4104 	DEBUG1("---Vendor ID = [0x%x]\n",
4105 	    pci_config_get16(config_handle, PCI_CONF_VENID));
4106 	DEBUG1("---Device ID = [0x%x]\n",
4107 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
4108 
4109 	/*
4110 	 * Attach the child to its parent
4111 	 */
4112 	(void) i_ndi_config_node(new_child, DS_LINKED, 0);
4113 
4114 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
4115 
4116 		DEBUG3("--Bridge found bus [0x%x] device"
4117 		    "[0x%x] func [0x%x]\n", bus, device, func);
4118 
4119 		/* Only support read-only probe for leaf device */
4120 		if (flags & PCICFG_FLAG_READ_ONLY)
4121 			goto failedchild;
4122 
4123 		if (pcicfg_probe_bridge(new_child, config_handle,
4124 		    bus, highest_bus, is_pcie) != PCICFG_SUCCESS) {
4125 			(void) pcicfg_free_bridge_resources(new_child);
4126 			goto failedchild;
4127 		}
4128 
4129 	} else {
4130 
4131 		DEBUG3("--Leaf device found bus [0x%x] device"
4132 		    "[0x%x] func [0x%x]\n",
4133 		    bus, device, func);
4134 
4135 		if (flags & PCICFG_FLAG_READ_ONLY) {
4136 			/*
4137 			 * with read-only probe, don't do any resource
4138 			 * allocation, just read the BARs and update props.
4139 			 */
4140 			ret = pcicfg_populate_props_from_bar(new_child,
4141 			    config_handle);
4142 			if (ret != PCICFG_SUCCESS)
4143 				goto failedchild;
4144 
4145 			/*
4146 			 * for readonly probe "assigned-addresses" property
4147 			 * has already been setup by reading the BAR, here
4148 			 * just substract the resource from its parent here.
4149 			 */
4150 			ret = pcicfg_device_assign_readonly(new_child);
4151 			if (ret != PCICFG_SUCCESS) {
4152 				(void) pcicfg_free_device_resources(new_child,
4153 				    flags);
4154 				goto failedchild;
4155 			}
4156 		} else {
4157 			/*
4158 			 * update "reg" property by sizing the BARs.
4159 			 */
4160 			ret = pcicfg_populate_reg_props(new_child,
4161 			    config_handle);
4162 			if (ret != PCICFG_SUCCESS)
4163 				goto failedchild;
4164 
4165 			/* now allocate & program the resources */
4166 			ret = pcicfg_device_assign(new_child);
4167 			if (ret != PCICFG_SUCCESS) {
4168 				(void) pcicfg_free_device_resources(new_child,
4169 				    flags);
4170 				goto failedchild;
4171 			}
4172 		}
4173 
4174 		(void) ndi_devi_bind_driver(new_child, 0);
4175 	}
4176 
4177 	(void) pcicfg_config_teardown(&config_handle);
4178 
4179 	/*
4180 	 * Properties have been setted up, so initilize the rest fields
4181 	 * in bus_t.
4182 	 */
4183 	if (is_pcie)
4184 		(void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
4185 
4186 	return (PCICFG_SUCCESS);
4187 
4188 failedchild:
4189 
4190 	(void) pcicfg_config_teardown(&config_handle);
4191 	if (is_pcie)
4192 		pcie_fini_bus(new_child, PCIE_BUS_FINAL);
4193 
4194 failedconfig:
4195 
4196 	(void) ndi_devi_free(new_child);
4197 	return (PCICFG_FAILURE);
4198 }
4199 
4200 /*
4201  * Sizing the BARs and update "reg" property
4202  */
4203 static int
4204 pcicfg_populate_reg_props(dev_info_t *new_child,
4205     ddi_acc_handle_t config_handle)
4206 {
4207 	int		i;
4208 	uint32_t	request;
4209 
4210 	i = PCI_CONF_BASE0;
4211 
4212 	while (i <= PCI_CONF_BASE5) {
4213 
4214 		pci_config_put32(config_handle, i, 0xffffffff);
4215 
4216 		request = pci_config_get32(config_handle, i);
4217 		/*
4218 		 * If its a zero length, don't do
4219 		 * any programming.
4220 		 */
4221 		if (request != 0) {
4222 			/*
4223 			 * Add to the "reg" property
4224 			 */
4225 			if (pcicfg_update_reg_prop(new_child,
4226 			    request, i) != PCICFG_SUCCESS) {
4227 				goto failedchild;
4228 			}
4229 		} else {
4230 			DEBUG1("BASE register [0x%x] asks for "
4231 			    "[0x0]=[0x0](32)\n", i);
4232 			i += 4;
4233 			continue;
4234 		}
4235 
4236 		/*
4237 		 * Increment by eight if it is 64 bit address space
4238 		 */
4239 		if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4240 			DEBUG3("BASE register [0x%x] asks for "
4241 			    "[0x%x]=[0x%x] (64)\n",
4242 			    i, request,
4243 			    (~(PCI_BASE_M_ADDR_M & request))+1)
4244 			i += 8;
4245 		} else {
4246 			DEBUG3("BASE register [0x%x] asks for "
4247 			    "[0x%x]=[0x%x](32)\n",
4248 			    i, request,
4249 			    (~(PCI_BASE_M_ADDR_M & request))+1)
4250 			i += 4;
4251 		}
4252 	}
4253 
4254 	/*
4255 	 * Get the ROM size and create register for it
4256 	 */
4257 	pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
4258 
4259 	request = pci_config_get32(config_handle, PCI_CONF_ROM);
4260 	/*
4261 	 * If its a zero length, don't do
4262 	 * any programming.
4263 	 */
4264 
4265 	if (request != 0) {
4266 		DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
4267 		    PCI_CONF_ROM, request,
4268 		    (~(PCI_BASE_ROM_ADDR_M & request))+1);
4269 		/*
4270 		 * Add to the "reg" property
4271 		 */
4272 		if (pcicfg_update_reg_prop(new_child,
4273 		    request, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4274 			goto failedchild;
4275 		}
4276 	}
4277 
4278 	return (PCICFG_SUCCESS);
4279 
4280 failedchild:
4281 	return (PCICFG_FAILURE);
4282 }
4283 
4284 static int
4285 pcicfg_fcode_probe(dev_info_t *parent, uint_t bus, uint_t device,
4286     uint_t func, uint_t *highest_bus, pcicfg_flags_t flags, boolean_t is_pcie)
4287 {
4288 	dev_info_t		*new_child;
4289 	int8_t			header_type;
4290 	int			ret;
4291 	ddi_acc_handle_t	h, ph;
4292 	int			error = 0;
4293 	extern int		pcicfg_dont_interpret;
4294 	pcicfg_err_regs_t	parent_regs, regs;
4295 	char			*status_prop = NULL;
4296 #ifdef PCICFG_INTERPRET_FCODE
4297 	struct pci_ops_bus_args	po;
4298 	fco_handle_t		c;
4299 	char			unit_address[64];
4300 	int			fcode_size = 0;
4301 	uchar_t			*fcode_addr;
4302 	uint64_t		mem_answer, mem_alen;
4303 	pci_regspec_t		p;
4304 	int32_t			request;
4305 	ndi_ra_request_t	req;
4306 	int16_t			vendor_id, device_id;
4307 #endif
4308 
4309 	/*
4310 	 * check if our parent is of type pciex.
4311 	 * if so, program config space to disable error msgs during probe.
4312 	 */
4313 	if (pcicfg_pcie_dev(parent, PCICFG_DEVICE_TYPE_PCIE, &parent_regs)
4314 	    == DDI_SUCCESS) {
4315 		DEBUG0("PCI/PCIe parent detected. Disable errors.\n");
4316 		/*
4317 		 * disable parent generating URs or SERR#s during probing
4318 		 * alone.
4319 		 */
4320 		if (pci_config_setup(parent, &ph) != DDI_SUCCESS)
4321 			return (DDI_FAILURE);
4322 
4323 		if ((flags & PCICFG_FLAG_READ_ONLY) == 0) {
4324 			pcicfg_disable_bridge_probe_err(parent,
4325 			    ph, &parent_regs);
4326 		}
4327 	}
4328 
4329 	/*
4330 	 * This node will be put immediately below
4331 	 * "parent". Allocate a blank device node.  It will either
4332 	 * be filled in or freed up based on further probing.
4333 	 */
4334 
4335 	if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
4336 	    (pnode_t)DEVI_SID_NODEID, &new_child)
4337 	    != NDI_SUCCESS) {
4338 		DEBUG0("pcicfg_fcode_probe(): Failed to alloc child node\n");
4339 		/* return (PCICFG_FAILURE); */
4340 		ret = PCICFG_FAILURE;
4341 		goto failed2;
4342 	}
4343 
4344 	/*
4345 	 * Create a dummy reg property.  This will be replaced with
4346 	 * a real reg property when fcode completes or if we need to
4347 	 * produce one by hand.
4348 	 */
4349 	if (pcicfg_add_config_reg(new_child, bus,
4350 	    device, func) != DDI_SUCCESS) {
4351 		ret = PCICFG_FAILURE;
4352 		goto failed3;
4353 	}
4354 #ifdef	EFCODE21554
4355 	if ((ret = pcicfg_config_setup(new_child, &h))
4356 	    != PCICFG_SUCCESS) {
4357 		DEBUG0("pcicfg_fcode_probe():"
4358 		    "Failed to setup config space\n");
4359 		ret = PCICFG_NODEVICE;
4360 		goto failed3;
4361 	}
4362 
4363 #else
4364 	p.pci_phys_hi = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
4365 	p.pci_phys_mid = p.pci_phys_low = 0;
4366 	p.pci_size_hi = p.pci_size_low = 0;
4367 
4368 	/*
4369 	 * Map in configuration space (temporarily)
4370 	 */
4371 	acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
4372 	acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
4373 	acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
4374 
4375 	if (pcicfg_map_phys(new_child, &p, &virt, &acc, &h)) {
4376 		DEBUG0("pcicfg_fcode_probe():"
4377 		    "Failed to setup config space\n");
4378 		ret = PCICFG_NODEVICE;
4379 		goto failed3;
4380 	}
4381 
4382 	/*
4383 	 * First use ddi_peek16 so that if there is not a device there,
4384 	 * a bus error will not cause a panic.
4385 	 */
4386 	v = virt + PCI_CONF_VENID;
4387 	if (ddi_peek16(new_child, (int16_t *)v, &vendor_id)) {
4388 		DEBUG0("Can not read Vendor ID");
4389 		pcicfg_unmap_phys(&h, &p);
4390 		ret = PCICFG_NODEVICE;
4391 		goto failed3;
4392 	}
4393 #endif
4394 
4395 	if (is_pcie)
4396 		(void) pcie_init_bus(new_child, PCI_GETBDF(bus, device, func),
4397 		    PCIE_BUS_INITIAL);
4398 
4399 	DEBUG0("fcode_probe: conf space mapped.\n");
4400 	/*
4401 	 * As soon as we have access to config space,
4402 	 * turn off device. It will get turned on
4403 	 * later (after memory is assigned).
4404 	 */
4405 	(void) pcicfg_device_off(h);
4406 
4407 	/* check if we are PCIe device */
4408 	if (pcicfg_pcie_dev(new_child, PCICFG_DEVICE_TYPE_PCIE, &regs)
4409 	    == DDI_SUCCESS) {
4410 		/*EMPTY*/
4411 		DEBUG0("PCI/PCIe device detected\n");
4412 	}
4413 
4414 	/*
4415 	 * Set 1275 properties common to all devices
4416 	 */
4417 	if (pcicfg_set_standard_props(new_child,
4418 	    h, regs.pcie_dev) != PCICFG_SUCCESS) {
4419 		DEBUG0("Failed to set standard properties\n");
4420 		goto failed;
4421 	}
4422 
4423 	/*
4424 	 * Child node properties  NOTE: Both for PCI-PCI bridge and child node
4425 	 */
4426 	if (pcicfg_set_childnode_props(new_child,
4427 	    h, regs.pcie_dev) != PCICFG_SUCCESS) {
4428 		ret = PCICFG_FAILURE;
4429 		goto failed;
4430 	}
4431 
4432 	header_type = pci_config_get8(h, PCI_CONF_HEADER);
4433 
4434 	/*
4435 	 * If this is not a multi-function card only probe function zero.
4436 	 */
4437 	if (!(header_type & PCI_HEADER_MULTI) && (func > 0)) {
4438 
4439 		ret = PCICFG_NODEVICE;
4440 		goto failed;
4441 	}
4442 
4443 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
4444 
4445 		/*
4446 		 * XXX - Transparent bridges are handled differently
4447 		 * than other devices with regards to fcode.  Since
4448 		 * no transparent bridge currently ships with fcode,
4449 		 * there is no reason to try to extract it from its rom
4450 		 * or call the fcode interpreter to try to load a drop-in.
4451 		 * If fcode is developed to handle transparent bridges,
4452 		 * this code will have to change.
4453 		 */
4454 
4455 		DEBUG3("--Bridge found bus [0x%x] device"
4456 		    "[0x%x] func [0x%x]\n", bus, device, func);
4457 
4458 		/* Only support read-only probe for leaf device */
4459 		if (flags & PCICFG_FLAG_READ_ONLY)
4460 			goto failed;
4461 
4462 		if ((ret = pcicfg_probe_bridge(new_child, h,
4463 		    bus, highest_bus, is_pcie)) != PCICFG_SUCCESS)
4464 			(void) pcicfg_free_bridge_resources(new_child);
4465 		goto done;
4466 	} else {
4467 
4468 		DEBUG3("--Leaf device found bus [0x%x] device"
4469 		    "[0x%x] func [0x%x]\n",
4470 		    bus, device, func);
4471 
4472 		/*
4473 		 * link in tree, but don't bind driver
4474 		 * We don't have compatible property yet
4475 		 */
4476 		(void) i_ndi_config_node(new_child, DS_LINKED, 0);
4477 
4478 		/* XXX for now, don't run Fcode in read-only probe. */
4479 		if (flags & PCICFG_FLAG_READ_ONLY)
4480 			goto no_fcode;
4481 
4482 		if (pci_config_get8(h, PCI_CONF_IPIN)) {
4483 			pci_config_put8(h, PCI_CONF_ILINE, 0xf);
4484 		}
4485 
4486 #ifdef PCICFG_INTERPRET_FCODE
4487 		/*
4488 		 * Some platforms (x86) don't run fcode, so don't interpret
4489 		 * fcode that might be in the ROM.
4490 		 */
4491 		if (pcicfg_dont_interpret == 0) {
4492 
4493 			/* This platform supports fcode */
4494 
4495 			vendor_id = pci_config_get16(h, PCI_CONF_VENID);
4496 			device_id = pci_config_get16(h, PCI_CONF_DEVID);
4497 
4498 			/*
4499 			 * Get the ROM size and create register for it
4500 			 */
4501 			pci_config_put32(h, PCI_CONF_ROM, 0xfffffffe);
4502 
4503 			request = pci_config_get32(h, PCI_CONF_ROM);
4504 
4505 			/*
4506 			 * If its a zero length, don't do
4507 			 * any programming.
4508 			 */
4509 
4510 			if (request != 0) {
4511 				/*
4512 				 * Add resource to assigned-addresses.
4513 				 */
4514 				if (pcicfg_fcode_assign_bars(h, new_child,
4515 				    bus, device, func, request, &p)
4516 				    != PCICFG_SUCCESS) {
4517 					DEBUG0("Failed to assign addresses to "
4518 					    "implemented BARs");
4519 					ret = PCICFG_FAILURE;
4520 					goto failed;
4521 				}
4522 
4523 				/* Turn device on */
4524 				(void) pcicfg_device_on(h);
4525 
4526 				/*
4527 				 * Attempt to load fcode.
4528 				 */
4529 				(void) pcicfg_load_fcode(new_child, bus, device,
4530 				    func, vendor_id, device_id, &fcode_addr,
4531 				    &fcode_size, PCICFG_LOADDR(mem_answer),
4532 				    (~(PCI_BASE_ROM_ADDR_M & request)) + 1);
4533 
4534 				/* Turn device off */
4535 				(void) pcicfg_device_off(h);
4536 
4537 				/*
4538 				 * Free the ROM resources.
4539 				 */
4540 				(void) pcicfg_free_resource(new_child, p, 0);
4541 
4542 				DEBUG2("configure: fcode addr %lx size %x\n",
4543 				    fcode_addr, fcode_size);
4544 
4545 				/*
4546 				 * Create the fcode-rom-offset property.  The
4547 				 * buffer containing the fcode always starts
4548 				 * with 0xF1, so the fcode offset is zero.
4549 				 */
4550 				if (ndi_prop_update_int(DDI_DEV_T_NONE,
4551 				    new_child, "fcode-rom-offset", 0)
4552 				    != DDI_SUCCESS) {
4553 					DEBUG0("Failed to create "
4554 					    "fcode-rom-offset property\n");
4555 					ret = PCICFG_FAILURE;
4556 					goto failed;
4557 				}
4558 			} else {
4559 				DEBUG0("There is no Expansion ROM\n");
4560 				fcode_addr = NULL;
4561 				fcode_size = 0;
4562 			}
4563 
4564 			/*
4565 			 * Fill in the bus specific arguments. For
4566 			 * PCI, it is the config address.
4567 			 */
4568 			po.config_address =
4569 			    PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
4570 
4571 			DEBUG1("config_address=%x\n", po.config_address);
4572 
4573 			/*
4574 			 * Build unit address.
4575 			 */
4576 			(void) sprintf(unit_address, "%x,%x", device, func);
4577 
4578 			DEBUG3("pci_fc_ops_alloc_handle ap=%lx "
4579 			    "new device=%lx unit address=%s\n",
4580 			    parent, new_child, unit_address);
4581 
4582 			c = pci_fc_ops_alloc_handle(parent, new_child,
4583 			    fcode_addr, fcode_size, unit_address, &po);
4584 
4585 			DEBUG0("calling fcode_interpreter()\n");
4586 
4587 			DEBUG3("Before int DIP=%lx binding name %s major %d\n",
4588 			    new_child, ddi_binding_name(new_child),
4589 			    ddi_driver_major(new_child));
4590 
4591 			error = fcode_interpreter(parent, &pci_fc_ops, c);
4592 
4593 			DEBUG1("returned from fcode_interpreter() - "
4594 			    "returned %x\n", error);
4595 
4596 			pci_fc_ops_free_handle(c);
4597 
4598 			DEBUG1("fcode size = %x\n", fcode_size);
4599 			/*
4600 			 * We don't need the fcode anymore. While allocating
4601 			 * we had rounded up to a page size.
4602 			 */
4603 			if (fcode_size) {
4604 				kmem_free(fcode_addr, ptob(btopr(fcode_size)));
4605 			}
4606 		} else {
4607 			/* This platform does not support fcode */
4608 
4609 			DEBUG0("NOT calling fcode_interpreter()\n");
4610 		}
4611 
4612 #endif /* PCICFG_INTERPRET_FCODE */
4613 
4614 		if ((error == 0) && (pcicfg_dont_interpret == 0)) {
4615 			/*
4616 			 * The interpreter completed successfully.
4617 			 * We need to redo the resources based on the new reg
4618 			 * property.
4619 			 */
4620 			DEBUG3("DIP=%lx binding name %s major %d\n", new_child,
4621 			    ddi_binding_name(new_child),
4622 			    ddi_driver_major(new_child));
4623 
4624 			/*
4625 			 * Readjust resources specified by reg property.
4626 			 */
4627 			if (pcicfg_alloc_new_resources(new_child) ==
4628 			    PCICFG_FAILURE) {
4629 				ret = PCICFG_FAILURE;
4630 				goto failed;
4631 			}
4632 
4633 			/*
4634 			 * At this stage, there should be enough info to pull
4635 			 * the status property if it exists.
4636 			 */
4637 			if (ddi_prop_lookup_string(DDI_DEV_T_ANY,
4638 			    new_child, NULL, "status", &status_prop) ==
4639 			    DDI_PROP_SUCCESS) {
4640 				if ((strncmp("disabled", status_prop, 8) ==
4641 				    0) || (strncmp("fail", status_prop, 4) ==
4642 				    0)) {
4643 					ret = PCICFG_FAILURE;
4644 					ddi_prop_free(status_prop);
4645 					goto failed;
4646 				} else {
4647 					ddi_prop_free(status_prop);
4648 				}
4649 			}
4650 
4651 			ret = PCICFG_SUCCESS;
4652 			/* no fcode, bind driver now */
4653 			(void) ndi_devi_bind_driver(new_child, 0);
4654 
4655 			goto done;
4656 		} else if ((error != FC_NO_FCODE) &&
4657 		    (pcicfg_dont_interpret == 0))  {
4658 			/*
4659 			 * The interpreter located fcode, but had an error in
4660 			 * processing. Cleanup and fail the operation.
4661 			 */
4662 			DEBUG0("Interpreter detected fcode failure\n");
4663 			(void) pcicfg_free_resources(new_child, flags);
4664 			ret = PCICFG_FAILURE;
4665 			goto failed;
4666 		} else {
4667 no_fcode:
4668 			/*
4669 			 * Either the interpreter failed with FC_NO_FCODE or we
4670 			 * chose not to run the interpreter
4671 			 * (pcicfg_dont_interpret).
4672 			 *
4673 			 * If the interpreter failed because there was no
4674 			 * dropin, then we need to probe the device ourself.
4675 			 */
4676 
4677 			/*
4678 			 * Free any resources that may have been assigned
4679 			 * during fcode loading/execution since we need
4680 			 * to start over.
4681 			 */
4682 			(void) pcicfg_free_resources(new_child, flags);
4683 
4684 #ifdef	EFCODE21554
4685 			pcicfg_config_teardown(&h);
4686 #else
4687 			pcicfg_unmap_phys(&h, &p);
4688 #endif
4689 			/* destroy the bus_t before the dev node is gone */
4690 			if (is_pcie)
4691 				pcie_fini_bus(new_child, PCIE_BUS_FINAL);
4692 
4693 			(void) ndi_devi_free(new_child);
4694 
4695 			DEBUG0("No Drop-in Probe device ourself\n");
4696 
4697 			ret = pcicfg_probe_children(parent, bus, device, func,
4698 			    highest_bus, flags, is_pcie);
4699 
4700 			if (ret != PCICFG_SUCCESS) {
4701 				DEBUG0("Could not self probe child\n");
4702 				goto failed2;
4703 			}
4704 
4705 			/*
4706 			 * We successfully self probed the device.
4707 			 */
4708 			if ((new_child = pcicfg_devi_find(
4709 			    parent, device, func)) == NULL) {
4710 				DEBUG0("Did'nt find device node "
4711 				    "just created\n");
4712 				ret = PCICFG_FAILURE;
4713 				goto failed2;
4714 			}
4715 #ifdef	EFCODE21554
4716 			/*
4717 			 * Till now, we have detected a non transparent bridge
4718 			 * (ntbridge) as a part of the generic probe code and
4719 			 * configured only one configuration
4720 			 * header which is the side facing the host bus.
4721 			 * Now, configure the other side and create children.
4722 			 *
4723 			 * To make the process simpler, lets load the device
4724 			 * driver for the non transparent bridge as this is a
4725 			 * Solaris bundled driver, and use its configuration map
4726 			 * services rather than programming it here.
4727 			 * If the driver is not bundled into Solaris, it must be
4728 			 * first loaded and configured before performing any
4729 			 * hotplug operations.
4730 			 *
4731 			 * This not only makes the code simpler but also more
4732 			 * generic.
4733 			 *
4734 			 * So here we go.
4735 			 */
4736 			if (pcicfg_is_ntbridge(new_child) != DDI_FAILURE) {
4737 
4738 				DEBUG0("Found nontransparent bridge.\n");
4739 
4740 				ret = pcicfg_configure_ntbridge(new_child,
4741 				    bus, device);
4742 			}
4743 			if (ret != PCICFG_SUCCESS) {
4744 				/*
4745 				 * Bridge configure failed. Free up the self
4746 				 * probed entry. The bus resource allocation
4747 				 * maps need to be cleaned up to prevent
4748 				 * warnings on retries of the failed configure.
4749 				 */
4750 				(void) pcicfg_ntbridge_unconfigure(new_child);
4751 				(void) pcicfg_teardown_device(new_child,
4752 				    flags, is_pcie);
4753 			}
4754 #endif
4755 			goto done2;
4756 		}
4757 	}
4758 done:
4759 failed:
4760 	if (is_pcie) {
4761 		if (ret == PCICFG_SUCCESS)
4762 			(void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
4763 		else
4764 			pcie_fini_bus(new_child, PCIE_BUS_FINAL);
4765 	}
4766 
4767 #ifdef	EFCODE21554
4768 	pcicfg_config_teardown(&h);
4769 #else
4770 	pcicfg_unmap_phys(&h, &p);
4771 #endif
4772 failed3:
4773 	if (ret != PCICFG_SUCCESS)
4774 		(void) ndi_devi_free(new_child);
4775 done2:
4776 failed2:
4777 	if (parent_regs.pcie_dev) {
4778 		if ((flags & PCICFG_FLAG_READ_ONLY) == 0) {
4779 			pcicfg_enable_bridge_probe_err(parent,
4780 			    ph, &parent_regs);
4781 		}
4782 		pci_config_teardown(&ph);
4783 	}
4784 
4785 	return (ret);
4786 }
4787 
4788 /*
4789  * Read the BARs and update properties. Used in virtual hotplug.
4790  */
4791 static int
4792 pcicfg_populate_props_from_bar(dev_info_t *new_child,
4793     ddi_acc_handle_t config_handle)
4794 {
4795 	uint32_t request, base, base_hi, size;
4796 	int i;
4797 
4798 	i = PCI_CONF_BASE0;
4799 
4800 	while (i <= PCI_CONF_BASE5) {
4801 		/*
4802 		 * determine the size of the address space
4803 		 */
4804 		base = pci_config_get32(config_handle, i);
4805 		pci_config_put32(config_handle, i, 0xffffffff);
4806 		request = pci_config_get32(config_handle, i);
4807 		pci_config_put32(config_handle, i, base);
4808 
4809 		/*
4810 		 * If its a zero length, don't do any programming.
4811 		 */
4812 		if (request != 0) {
4813 			/*
4814 			 * Add to the "reg" property
4815 			 */
4816 			if (pcicfg_update_reg_prop(new_child,
4817 			    request, i) != PCICFG_SUCCESS) {
4818 				goto failedchild;
4819 			}
4820 
4821 			if ((PCI_BASE_SPACE_IO & request) == 0 &&
4822 			    (PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4823 				base_hi = pci_config_get32(config_handle, i+4);
4824 			} else {
4825 				base_hi = 0;
4826 			}
4827 			/*
4828 			 * Add to "assigned-addresses" property
4829 			 */
4830 			size = (~(PCI_BASE_M_ADDR_M & request))+1;
4831 			if (pcicfg_update_assigned_prop_value(new_child,
4832 			    size, base, base_hi, i) != PCICFG_SUCCESS) {
4833 				goto failedchild;
4834 			}
4835 		} else {
4836 			DEBUG1("BASE register [0x%x] asks for "
4837 			"[0x0]=[0x0](32)\n", i);
4838 			i += 4;
4839 			continue;
4840 		}
4841 
4842 		/*
4843 		 * Increment by eight if it is 64 bit address space
4844 		 */
4845 		if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4846 			DEBUG3("BASE register [0x%x] asks for "
4847 			"[0x%x]=[0x%x] (64)\n",
4848 			    i, request,
4849 			    (~(PCI_BASE_M_ADDR_M & request))+1)
4850 			i += 8;
4851 		} else {
4852 			DEBUG3("BASE register [0x%x] asks for "
4853 			"[0x%x]=[0x%x](32)\n",
4854 			    i, request,
4855 			    (~(PCI_BASE_M_ADDR_M & request))+1)
4856 			i += 4;
4857 		}
4858 	}
4859 
4860 	/*
4861 	 * Get the ROM size and create register for it
4862 	 */
4863 	base = pci_config_get32(config_handle, PCI_CONF_ROM);
4864 	pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
4865 	request = pci_config_get32(config_handle, PCI_CONF_ROM);
4866 	pci_config_put32(config_handle, PCI_CONF_ROM, base);
4867 
4868 	/*
4869 	 * If its a zero length, don't do
4870 	 * any programming.
4871 	 */
4872 	if (request != 0) {
4873 		DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
4874 		    PCI_CONF_ROM, request,
4875 		    (~(PCI_BASE_ROM_ADDR_M & request))+1);
4876 		/*
4877 		 * Add to the "reg" property
4878 		 */
4879 		if (pcicfg_update_reg_prop(new_child,
4880 		    request, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4881 			goto failedchild;
4882 		}
4883 		/*
4884 		 * Add to "assigned-addresses" property
4885 		 */
4886 		size = (~(PCI_BASE_ROM_ADDR_M & request))+1;
4887 		if (pcicfg_update_assigned_prop_value(new_child, size,
4888 		    base, 0, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4889 			goto failedchild;
4890 		}
4891 	}
4892 
4893 	return (PCICFG_SUCCESS);
4894 
4895 failedchild:
4896 	return (PCICFG_FAILURE);
4897 }
4898 
4899 static int
4900 pcicfg_probe_bridge(dev_info_t *new_child, ddi_acc_handle_t h, uint_t bus,
4901     uint_t *highest_bus, boolean_t is_pcie)
4902 {
4903 	uint64_t next_bus;
4904 	uint_t new_bus, num_slots;
4905 	ndi_ra_request_t req;
4906 	int rval, i, j;
4907 	uint64_t mem_answer, mem_base, mem_alen, mem_size, mem_end;
4908 	uint64_t io_answer, io_base, io_alen, io_size, io_end;
4909 	uint64_t round_answer, round_len;
4910 	pcicfg_range_t range[PCICFG_RANGE_LEN];
4911 	int bus_range[2];
4912 	pcicfg_phdl_t phdl;
4913 	int count;
4914 	uint64_t pcibus_base, pcibus_alen;
4915 	uint64_t max_bus;
4916 	uint8_t pcie_device_type = 0;
4917 	dev_info_t *new_device;
4918 	int trans_device;
4919 	int ari_mode = B_FALSE;
4920 	int max_function = PCICFG_MAX_FUNCTION;
4921 
4922 	/*
4923 	 * Set "device_type" to "pci", the actual type will be set later
4924 	 * by pcicfg_set_busnode_props() below. This is needed as the
4925 	 * pcicfg_ra_free() below would update "available" property based
4926 	 * on "device_type".
4927 	 *
4928 	 * This code can be removed later after PCI configurator is changed
4929 	 * to use PCIRM, which automatically update properties upon allocation
4930 	 * and free, at that time we'll be able to remove the code inside
4931 	 * ndi_ra_alloc/free() which currently updates "available" property
4932 	 * for pci/pcie devices in pcie fabric.
4933 	 */
4934 	if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
4935 	    "device_type", "pci") != DDI_SUCCESS) {
4936 		DEBUG0("Failed to set \"device_type\" props\n");
4937 		return (PCICFG_FAILURE);
4938 	}
4939 
4940 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4941 	req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4942 	req.ra_boundbase = 0;
4943 	req.ra_boundlen = PCICFG_MAX_BUS_DEPTH;
4944 	req.ra_len = PCICFG_MAX_BUS_DEPTH;
4945 	req.ra_align_mask = 0;  /* no alignment needed */
4946 
4947 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4948 	    &pcibus_base, &pcibus_alen, NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4949 
4950 	if (rval != NDI_SUCCESS) {
4951 		if (rval == NDI_RA_PARTIAL_REQ) {
4952 			/*EMPTY*/
4953 			DEBUG0("NDI_RA_PARTIAL_REQ returned for bus range\n");
4954 		} else {
4955 			DEBUG0(
4956 			    "Failed to allocate bus range for bridge\n");
4957 			return (PCICFG_FAILURE);
4958 		}
4959 	}
4960 
4961 	DEBUG2("Bus Range Allocated [base=%d] [len=%d]\n",
4962 	    pcibus_base, pcibus_alen);
4963 
4964 	if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_PCI_BUSNUM)
4965 	    == NDI_FAILURE) {
4966 		DEBUG0("Can not setup resource map - NDI_RA_TYPE_PCI_BUSNUM\n");
4967 		return (PCICFG_FAILURE);
4968 	}
4969 
4970 	/*
4971 	 * Put available bus range into the pool.
4972 	 * Take the first one for this bridge to use and don't give
4973 	 * to child.
4974 	 */
4975 	(void) ndi_ra_free(new_child, pcibus_base+1, pcibus_alen-1,
4976 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4977 
4978 	next_bus = pcibus_base;
4979 	max_bus = pcibus_base + pcibus_alen - 1;
4980 
4981 	new_bus = next_bus;
4982 
4983 	DEBUG1("NEW bus found  ->[%d]\n", new_bus);
4984 
4985 	/* Keep track of highest bus for subordinate bus programming */
4986 	*highest_bus = new_bus;
4987 
4988 	/*
4989 	 * Allocate Memory Space for Bridge
4990 	 */
4991 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4992 	req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4993 	req.ra_boundbase = 0;
4994 	/*
4995 	 * Note: To support a 32b system, boundlen and len need to be
4996 	 * 32b quantities
4997 	 */
4998 	req.ra_boundlen = PCICFG_4GIG_LIMIT + 1;
4999 	req.ra_len = PCICFG_4GIG_LIMIT + 1; /* Get as big as possible */
5000 	req.ra_align_mask =
5001 	    PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
5002 
5003 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
5004 	    &mem_answer, &mem_alen,  NDI_RA_TYPE_MEM, NDI_RA_PASS);
5005 
5006 	if (rval != NDI_SUCCESS) {
5007 		if (rval == NDI_RA_PARTIAL_REQ) {
5008 			/*EMPTY*/
5009 			DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
5010 		} else {
5011 			DEBUG0(
5012 			    "Failed to allocate memory for bridge\n");
5013 			return (PCICFG_FAILURE);
5014 		}
5015 	}
5016 
5017 	DEBUG3("Bridge Memory Allocated [0x%x.%x] len [0x%x]\n",
5018 	    PCICFG_HIADDR(mem_answer),
5019 	    PCICFG_LOADDR(mem_answer),
5020 	    mem_alen);
5021 
5022 	if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
5023 		DEBUG0("Can not setup resource map - NDI_RA_TYPE_MEM\n");
5024 		return (PCICFG_FAILURE);
5025 	}
5026 
5027 	/*
5028 	 * Put available memory into the pool.
5029 	 */
5030 	(void) ndi_ra_free(new_child, mem_answer, mem_alen, NDI_RA_TYPE_MEM,
5031 	    NDI_RA_PASS);
5032 
5033 	mem_base = mem_answer;
5034 
5035 	/*
5036 	 * Allocate I/O Space for Bridge
5037 	 */
5038 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
5039 	req.ra_align_mask = PCICFG_IOGRAN - 1; /* 4k alignment */
5040 	req.ra_boundbase = 0;
5041 	req.ra_boundlen = PCICFG_4GIG_LIMIT;
5042 	req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
5043 	req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
5044 
5045 	rval = ndi_ra_alloc(ddi_get_parent(new_child), &req, &io_answer,
5046 	    &io_alen, NDI_RA_TYPE_IO, NDI_RA_PASS);
5047 
5048 	if (rval != NDI_SUCCESS) {
5049 		if (rval == NDI_RA_PARTIAL_REQ) {
5050 			/*EMPTY*/
5051 			DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
5052 		} else {
5053 			DEBUG0("Failed to allocate io space for bridge\n");
5054 			io_base = io_answer = io_alen = 0;
5055 			/* return (PCICFG_FAILURE); */
5056 		}
5057 	}
5058 
5059 	if (io_alen) {
5060 		DEBUG3("Bridge IO Space Allocated [0x%x.%x] len [0x%x]\n",
5061 		    PCICFG_HIADDR(io_answer), PCICFG_LOADDR(io_answer),
5062 		    io_alen);
5063 
5064 		if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_IO) ==
5065 		    NDI_FAILURE) {
5066 			DEBUG0("Can not setup resource map - NDI_RA_TYPE_IO\n");
5067 			return (PCICFG_FAILURE);
5068 		}
5069 
5070 		/*
5071 		 * Put available I/O into the pool.
5072 		 */
5073 		(void) ndi_ra_free(new_child, io_answer, io_alen,
5074 		    NDI_RA_TYPE_IO, NDI_RA_PASS);
5075 		io_base = io_answer;
5076 	}
5077 
5078 	pcicfg_set_bus_numbers(h, bus, new_bus, max_bus);
5079 
5080 	/*
5081 	 * Setup "bus-range" property before onlining the bridge.
5082 	 */
5083 	bus_range[0] = new_bus;
5084 	bus_range[1] = max_bus;
5085 
5086 	if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
5087 	    "bus-range", bus_range, 2) != DDI_SUCCESS) {
5088 		DEBUG0("Failed to set bus-range property");
5089 		return (PCICFG_FAILURE);
5090 	}
5091 
5092 	/*
5093 	 * Reset the secondary bus
5094 	 */
5095 	pci_config_put16(h, PCI_BCNF_BCNTRL,
5096 	    pci_config_get16(h, PCI_BCNF_BCNTRL) | 0x40);
5097 
5098 	drv_usecwait(100);
5099 
5100 	pci_config_put16(h, PCI_BCNF_BCNTRL,
5101 	    pci_config_get16(h, PCI_BCNF_BCNTRL) & ~0x40);
5102 
5103 	/*
5104 	 * Program the memory base register with the
5105 	 * start of the memory range
5106 	 */
5107 	pci_config_put16(h, PCI_BCNF_MEM_BASE,
5108 	    PCICFG_HIWORD(PCICFG_LOADDR(mem_answer)));
5109 
5110 	/*
5111 	 * Program the memory limit register with the
5112 	 * end of the memory range.
5113 	 */
5114 
5115 	pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
5116 	    PCICFG_HIWORD(PCICFG_LOADDR(
5117 	    PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN) - 1)));
5118 
5119 	/*
5120 	 * Allocate the chunk of memory (if any) not programmed into the
5121 	 * bridge because of the round down.
5122 	 */
5123 	if (PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN)
5124 	    != (mem_answer + mem_alen)) {
5125 		DEBUG0("Need to allocate Memory round off chunk\n");
5126 		bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
5127 		req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
5128 		req.ra_addr = PCICFG_ROUND_DOWN((mem_answer + mem_alen),
5129 		    PCICFG_MEMGRAN);
5130 		req.ra_len =  (mem_answer + mem_alen) -
5131 		    (PCICFG_ROUND_DOWN((mem_answer + mem_alen),
5132 		    PCICFG_MEMGRAN));
5133 
5134 		(void) ndi_ra_alloc(new_child, &req,
5135 		    &round_answer, &round_len,  NDI_RA_TYPE_MEM, NDI_RA_PASS);
5136 	}
5137 
5138 	/*
5139 	 * Program the I/O Space Base
5140 	 */
5141 	pci_config_put8(h, PCI_BCNF_IO_BASE_LOW,
5142 	    PCICFG_HIBYTE(PCICFG_LOWORD(
5143 	    PCICFG_LOADDR(io_answer))));
5144 
5145 	pci_config_put16(h, PCI_BCNF_IO_BASE_HI,
5146 	    PCICFG_HIWORD(PCICFG_LOADDR(io_answer)));
5147 
5148 	/*
5149 	 * Program the I/O Space Limit
5150 	 */
5151 	pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
5152 	    PCICFG_HIBYTE(PCICFG_LOWORD(
5153 	    PCICFG_LOADDR(PCICFG_ROUND_DOWN(io_answer + io_alen,
5154 	    PCICFG_IOGRAN)))) - 1);
5155 
5156 	pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
5157 	    PCICFG_HIWORD(PCICFG_LOADDR(
5158 	    PCICFG_ROUND_DOWN(io_answer + io_alen, PCICFG_IOGRAN)))
5159 	    - 1);
5160 
5161 	/*
5162 	 * Allocate the chunk of I/O (if any) not programmed into the
5163 	 * bridge because of the round down.
5164 	 */
5165 	if (PCICFG_ROUND_DOWN((io_answer + io_alen), PCICFG_IOGRAN)
5166 	    != (io_answer + io_alen)) {
5167 		DEBUG0("Need to allocate I/O round off chunk\n");
5168 		bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
5169 		req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
5170 		req.ra_addr = PCICFG_ROUND_DOWN((io_answer + io_alen),
5171 		    PCICFG_IOGRAN);
5172 		req.ra_len =  (io_answer + io_alen) -
5173 		    (PCICFG_ROUND_DOWN((io_answer + io_alen),
5174 		    PCICFG_IOGRAN));
5175 
5176 		(void) ndi_ra_alloc(new_child, &req,
5177 		    &round_answer, &round_len,  NDI_RA_TYPE_IO, NDI_RA_PASS);
5178 	}
5179 
5180 	/*
5181 	 * Setup "ranges" property before onlining the bridge.
5182 	 */
5183 	bzero((caddr_t)range, sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
5184 
5185 	range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
5186 	range[0].child_lo = range[0].parent_lo = io_base;
5187 	range[1].child_hi = range[1].parent_hi |=
5188 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
5189 	range[1].child_lo = range[1].parent_lo = mem_base;
5190 
5191 	range[0].size_lo = io_alen;
5192 	if (pcicfg_update_ranges_prop(new_child, &range[0])) {
5193 		DEBUG0("Failed to update ranges (io)\n");
5194 		return (PCICFG_FAILURE);
5195 	}
5196 	range[1].size_lo = mem_alen;
5197 	if (pcicfg_update_ranges_prop(new_child, &range[1])) {
5198 		DEBUG0("Failed to update ranges (memory)\n");
5199 		return (PCICFG_FAILURE);
5200 	}
5201 
5202 	/*
5203 	 * Clear status bits
5204 	 */
5205 	pci_config_put16(h, PCI_BCNF_SEC_STATUS, 0xffff);
5206 
5207 	/*
5208 	 * Turn off prefetchable range
5209 	 */
5210 	pci_config_put32(h, PCI_BCNF_PF_BASE_LOW, 0x0000ffff);
5211 	pci_config_put32(h, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
5212 	pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH, 0x0);
5213 
5214 	/*
5215 	 * Needs to be set to this value
5216 	 */
5217 	pci_config_put8(h, PCI_CONF_ILINE, 0xf);
5218 
5219 	/* check our device_type as defined by Open Firmware */
5220 	if (pcicfg_pcie_device_type(new_child, h) == DDI_SUCCESS)
5221 		pcie_device_type = 1;
5222 
5223 	/*
5224 	 * Set bus properties
5225 	 */
5226 	if (pcicfg_set_busnode_props(new_child, pcie_device_type,
5227 	    (int)bus, (int)new_bus) != PCICFG_SUCCESS) {
5228 		DEBUG0("Failed to set busnode props\n");
5229 		return (PCICFG_FAILURE);
5230 	}
5231 
5232 	(void) pcicfg_device_on(h);
5233 
5234 	if (is_pcie)
5235 		(void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
5236 	if (ndi_devi_online(new_child, NDI_NO_EVENT|NDI_CONFIG)
5237 	    != NDI_SUCCESS) {
5238 		DEBUG0("Unable to online bridge\n");
5239 		return (PCICFG_FAILURE);
5240 	}
5241 
5242 	DEBUG0("Bridge is ONLINE\n");
5243 
5244 	/*
5245 	 * After a Reset, we need to wait 2^25 clock cycles before the
5246 	 * first Configuration access.  The worst case is 33MHz, which
5247 	 * is a 1 second wait.
5248 	 */
5249 	drv_usecwait(pcicfg_sec_reset_delay);
5250 
5251 	/*
5252 	 * Probe all children devices
5253 	 */
5254 	DEBUG0("Bridge Programming Complete - probe children\n");
5255 	ndi_devi_enter(new_child, &count);
5256 	for (i = 0; ((i < PCICFG_MAX_DEVICE) && (ari_mode == B_FALSE));
5257 	    i++) {
5258 		for (j = 0; j < max_function; ) {
5259 			if (ari_mode)
5260 				trans_device = j >> 3;
5261 			else
5262 				trans_device = i;
5263 
5264 			if ((rval = pcicfg_fcode_probe(new_child,
5265 			    new_bus, trans_device, (j & 7), highest_bus,
5266 			    0, is_pcie))
5267 			    != PCICFG_SUCCESS) {
5268 				if (rval == PCICFG_NODEVICE) {
5269 					DEBUG3("No Device at bus [0x%x]"
5270 					    "device [0x%x] "
5271 					    "func [0x%x]\n", new_bus,
5272 					    trans_device, j & 7);
5273 
5274 					if (j)
5275 						goto next;
5276 				} else {
5277 					DEBUG3("Failed to configure bus "
5278 					    "[0x%x] device [0x%x] "
5279 					    "func [0x%x]\n", new_bus,
5280 					    trans_device, j & 7);
5281 
5282 					rval = PCICFG_FAILURE;
5283 				}
5284 				break;
5285 			}
5286 next:
5287 			new_device = pcicfg_devi_find(new_child,
5288 			    trans_device, (j & 7));
5289 
5290 			/*
5291 			 * Determine if ARI Forwarding should be enabled.
5292 			 */
5293 			if (j == 0) {
5294 				if (new_device == NULL)
5295 					break;
5296 
5297 				if ((pcie_ari_supported(new_child) ==
5298 				    PCIE_ARI_FORW_ENABLED) &&
5299 				    (pcie_ari_device(new_device) ==
5300 				    PCIE_ARI_DEVICE)) {
5301 					if (pcie_ari_enable(new_child) ==
5302 					    DDI_SUCCESS) {
5303 						(void) ddi_prop_create(
5304 						    DDI_DEV_T_NONE,
5305 						    new_child,
5306 						    DDI_PROP_CANSLEEP,
5307 						    "ari-enabled", NULL, 0);
5308 						ari_mode = B_TRUE;
5309 						max_function =
5310 						    PCICFG_MAX_ARI_FUNCTION;
5311 					}
5312 				}
5313 			}
5314 
5315 			if (ari_mode == B_TRUE) {
5316 				int next_function;
5317 
5318 				if (new_device == NULL)
5319 					break;
5320 
5321 				if (pcie_ari_get_next_function(new_device,
5322 				    &next_function) != DDI_SUCCESS)
5323 					break;
5324 
5325 				j = next_function;
5326 
5327 				if (next_function == 0)
5328 					break;
5329 			} else
5330 				j++;
5331 		}
5332 	}
5333 
5334 	ndi_devi_exit(new_child, count);
5335 
5336 	/* if empty topology underneath, it is still a success. */
5337 	if (rval != PCICFG_FAILURE)
5338 		rval = PCICFG_SUCCESS;
5339 
5340 	/*
5341 	 * Offline the bridge to allow reprogramming of resources.
5342 	 *
5343 	 * This should always succeed since nobody else has started to
5344 	 * use it yet, failing to detach the driver would indicate a bug.
5345 	 * Also in that case it's better just panic than allowing the
5346 	 * configurator to proceed with BAR reprogramming without bridge
5347 	 * driver detached.
5348 	 */
5349 	VERIFY(ndi_devi_offline(new_child, NDI_NO_EVENT|NDI_UNCONFIG)
5350 	    == NDI_SUCCESS);
5351 	if (is_pcie)
5352 		pcie_fini_bus(new_child, PCIE_BUS_INITIAL);
5353 
5354 	phdl.dip = new_child;
5355 	phdl.memory_base = mem_answer;
5356 	phdl.io_base = (uint32_t)io_answer;
5357 	phdl.error = PCICFG_SUCCESS;    /* in case of empty child tree */
5358 
5359 	ndi_devi_enter(ddi_get_parent(new_child), &count);
5360 	ddi_walk_devs(new_child, pcicfg_find_resource_end, (void *)&phdl);
5361 	ndi_devi_exit(ddi_get_parent(new_child), count);
5362 
5363 	if (phdl.error != PCICFG_SUCCESS) {
5364 		DEBUG0("Failure summing resources\n");
5365 		return (PCICFG_FAILURE);
5366 	}
5367 
5368 	num_slots = pcicfg_get_nslots(new_child, h);
5369 	mem_end = PCICFG_ROUND_UP(phdl.memory_base, PCICFG_MEMGRAN);
5370 	io_end = PCICFG_ROUND_UP(phdl.io_base, PCICFG_IOGRAN);
5371 
5372 	DEBUG3("Start of Unallocated Bridge(%d slots) Resources "
5373 	    "Mem=0x%lx I/O=0x%lx\n", num_slots, mem_end, io_end);
5374 
5375 	/*
5376 	 * Before probing the children we've allocated maximum MEM/IO
5377 	 * resources from parent, and updated "available" property
5378 	 * accordingly. Later we'll be giving up unused resources to
5379 	 * the parent, thus we need to destroy "available" property
5380 	 * here otherwise it will be out-of-sync with the actual free
5381 	 * resources this bridge has. This property will be rebuilt below
5382 	 * with the actual free resources reserved for hotplug slots
5383 	 * (if any).
5384 	 */
5385 	(void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "available");
5386 	/*
5387 	 * if the bridge a slots, then preallocate. If not, assume static
5388 	 * configuration. Also check for preallocation limits and spit
5389 	 * warning messages appropriately (perhaps some can be in debug mode).
5390 	 */
5391 	if (num_slots) {
5392 		pci_regspec_t reg;
5393 		uint64_t mem_assigned = mem_end;
5394 		uint64_t io_assigned = io_end;
5395 		uint64_t mem_reqd = mem_answer + (num_slots *
5396 		    pcicfg_slot_memsize);
5397 		uint64_t io_reqd = io_answer + (num_slots *
5398 		    pcicfg_slot_iosize);
5399 		uint8_t highest_bus_reqd = new_bus + (num_slots *
5400 		    pcicfg_slot_busnums);
5401 #ifdef DEBUG
5402 		if (mem_end > mem_reqd)
5403 			DEBUG3("Memory space consumed by bridge"
5404 			    " more than planned for %d slot(s)(%lx, %lx)",
5405 			    num_slots, mem_answer, mem_end);
5406 		if (io_end > io_reqd)
5407 			DEBUG3("IO space consumed by bridge"
5408 			    " more than planned for %d slot(s)(%lx, %lx)",
5409 			    num_slots, io_answer, io_end);
5410 		if (*highest_bus > highest_bus_reqd)
5411 			DEBUG3("Buses consumed by bridge"
5412 			    " more than planned for %d slot(s)(%x, %x)",
5413 			    num_slots, new_bus, *highest_bus);
5414 
5415 		if (mem_reqd > (mem_answer + mem_alen))
5416 			DEBUG3("Memory space required by bridge"
5417 			    " more than available for %d slot(s)(%lx, %lx)",
5418 			    num_slots, mem_answer, mem_end);
5419 
5420 		if (io_reqd > (io_answer + io_alen))
5421 			DEBUG3("IO space required by bridge"
5422 			    " more than available for %d slot(s)(%lx, %lx)",
5423 			    num_slots, io_answer, io_end);
5424 		if (highest_bus_reqd > max_bus)
5425 			DEBUG3("Bus numbers required by bridge"
5426 			    " more than available for %d slot(s)(%x, %x)",
5427 			    num_slots, new_bus, *highest_bus);
5428 #endif
5429 		mem_end = MAX((MIN(mem_reqd, (mem_answer + mem_alen))),
5430 		    mem_end);
5431 		io_end = MAX((MIN(io_reqd, (io_answer + io_alen))), io_end);
5432 		*highest_bus = MAX((MIN(highest_bus_reqd, max_bus)),
5433 		    *highest_bus);
5434 		DEBUG3("mem_end %lx, io_end %lx, highest_bus %x\n",
5435 		    mem_end, io_end, *highest_bus);
5436 
5437 		mem_size = mem_end - mem_assigned;
5438 		io_size = io_end - io_assigned;
5439 
5440 		reg.pci_phys_mid = reg.pci_size_hi = 0;
5441 		if (io_size > 0) {
5442 			reg.pci_phys_hi = (PCI_REG_REL_M | PCI_ADDR_IO);
5443 			reg.pci_phys_low = io_assigned;
5444 			reg.pci_size_low = io_size;
5445 			if (pcicfg_update_available_prop(new_child, &reg)) {
5446 				DEBUG0("Failed to update available prop "
5447 				    "(io)\n");
5448 				return (PCICFG_FAILURE);
5449 			}
5450 		}
5451 		if (mem_size > 0) {
5452 			reg.pci_phys_hi = (PCI_REG_REL_M | PCI_ADDR_MEM32);
5453 			reg.pci_phys_low = mem_assigned;
5454 			reg.pci_size_low = mem_size;
5455 			if (pcicfg_update_available_prop(new_child, &reg)) {
5456 				DEBUG0("Failed to update available prop "
5457 				    "(memory)\n");
5458 				return (PCICFG_FAILURE);
5459 			}
5460 		}
5461 	}
5462 
5463 	/*
5464 	 * Give back unused memory space to parent.
5465 	 */
5466 	(void) ndi_ra_free(ddi_get_parent(new_child),
5467 	    mem_end, (mem_answer + mem_alen) - mem_end, NDI_RA_TYPE_MEM,
5468 	    NDI_RA_PASS);
5469 
5470 	if (mem_end == mem_answer) {
5471 		DEBUG0("No memory resources used\n");
5472 		/*
5473 		 * To prevent the bridge from forwarding any Memory
5474 		 * transactions, the Memory Limit will be programmed
5475 		 * with a smaller value than the Memory Base.
5476 		 */
5477 		pci_config_put16(h, PCI_BCNF_MEM_BASE, 0xffff);
5478 		pci_config_put16(h, PCI_BCNF_MEM_LIMIT, 0);
5479 
5480 		mem_size = 0;
5481 	} else {
5482 		/*
5483 		 * Reprogram the end of the memory.
5484 		 */
5485 		pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
5486 		    PCICFG_HIWORD(mem_end) - 1);
5487 		mem_size = mem_end - mem_base;
5488 	}
5489 
5490 	/*
5491 	 * Give back unused io space to parent.
5492 	 */
5493 	(void) ndi_ra_free(ddi_get_parent(new_child),
5494 	    io_end, (io_answer + io_alen) - io_end,
5495 	    NDI_RA_TYPE_IO, NDI_RA_PASS);
5496 
5497 	if (io_end == io_answer) {
5498 		DEBUG0("No IO Space resources used\n");
5499 
5500 		/*
5501 		 * To prevent the bridge from forwarding any I/O
5502 		 * transactions, the I/O Limit will be programmed
5503 		 * with a smaller value than the I/O Base.
5504 		 */
5505 		pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW, 0);
5506 		pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI, 0);
5507 		pci_config_put8(h, PCI_BCNF_IO_BASE_LOW, 0xff);
5508 		pci_config_put16(h, PCI_BCNF_IO_BASE_HI, 0);
5509 
5510 		io_size = 0;
5511 	} else {
5512 		/*
5513 		 * Reprogram the end of the io space.
5514 		 */
5515 		pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
5516 		    PCICFG_HIBYTE(PCICFG_LOWORD(
5517 		    PCICFG_LOADDR(io_end) - 1)));
5518 
5519 		pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
5520 		    PCICFG_HIWORD(PCICFG_LOADDR(io_end - 1)));
5521 
5522 		io_size = io_end - io_base;
5523 	}
5524 
5525 	if ((max_bus - *highest_bus) > 0) {
5526 		/*
5527 		 * Give back unused bus numbers
5528 		 */
5529 		(void) ndi_ra_free(ddi_get_parent(new_child),
5530 		    *highest_bus+1, max_bus - *highest_bus,
5531 		    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
5532 	}
5533 
5534 	/*
5535 	 * Set bus numbers to ranges encountered during scan
5536 	 */
5537 	pcicfg_set_bus_numbers(h, bus, new_bus, *highest_bus);
5538 
5539 	bus_range[0] = pci_config_get8(h, PCI_BCNF_SECBUS);
5540 	bus_range[1] = pci_config_get8(h, PCI_BCNF_SUBBUS);
5541 	DEBUG1("End of bridge probe: bus_range[0] =  %d\n", bus_range[0]);
5542 	DEBUG1("End of bridge probe: bus_range[1] =  %d\n", bus_range[1]);
5543 
5544 	if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
5545 	    "bus-range", bus_range, 2) != DDI_SUCCESS) {
5546 		DEBUG0("Failed to set bus-range property");
5547 		return (PCICFG_FAILURE);
5548 	}
5549 
5550 	/*
5551 	 * Remove the ranges property if it exists since we will create
5552 	 * a new one.
5553 	 */
5554 	(void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "ranges");
5555 
5556 	DEBUG2("Creating Ranges property - Mem Address %lx Mem Size %x\n",
5557 	    mem_base, mem_size);
5558 	DEBUG2("                         - I/O Address %lx I/O Size %x\n",
5559 	    io_base, io_size);
5560 
5561 	bzero((caddr_t)range, sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
5562 
5563 	range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
5564 	range[0].child_lo = range[0].parent_lo = io_base;
5565 	range[1].child_hi = range[1].parent_hi |=
5566 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
5567 	range[1].child_lo = range[1].parent_lo = mem_base;
5568 
5569 	if (io_size > 0) {
5570 		range[0].size_lo = io_size;
5571 		if (pcicfg_update_ranges_prop(new_child, &range[0])) {
5572 			DEBUG0("Failed to update ranges (io)\n");
5573 			return (PCICFG_FAILURE);
5574 		}
5575 	}
5576 	if (mem_size > 0) {
5577 		range[1].size_lo = mem_size;
5578 		if (pcicfg_update_ranges_prop(new_child, &range[1])) {
5579 			DEBUG0("Failed to update ranges (memory)\n");
5580 			return (PCICFG_FAILURE);
5581 		}
5582 	}
5583 
5584 	/*
5585 	 * Remove the resource maps for the bridge since we no longer
5586 	 * need them.  Note that the failure is ignored since the
5587 	 * ndi_devi_offline above may have already taken care of it via
5588 	 * driver detach.
5589 	 * It has been checked that there are no other reasons for
5590 	 * failure other than map itself being non-existent. So we are Ok.
5591 	 */
5592 	if (ndi_ra_map_destroy(new_child, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
5593 		/*EMPTY*/
5594 		DEBUG0("Can not destroy resource map - NDI_RA_TYPE_MEM\n");
5595 	}
5596 
5597 	if (ndi_ra_map_destroy(new_child, NDI_RA_TYPE_IO) == NDI_FAILURE) {
5598 		/*EMPTY*/
5599 		DEBUG0("Can not destroy resource map - NDI_RA_TYPE_IO\n");
5600 	}
5601 
5602 	if (ndi_ra_map_destroy(new_child, NDI_RA_TYPE_PCI_BUSNUM)
5603 	    == NDI_FAILURE) {
5604 		/*EMPTY*/
5605 		DEBUG0("Can't destroy resource map - NDI_RA_TYPE_PCI_BUSNUM\n");
5606 	}
5607 
5608 	return (rval);
5609 }
5610 
5611 /*
5612  * Return PCICFG_SUCCESS if device exists at the specified address.
5613  * Return PCICFG_NODEVICE is no device exists at the specified address.
5614  *
5615  */
5616 int
5617 pcicfg_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
5618 {
5619 	caddr_t			virt;
5620 	ddi_device_acc_attr_t	attr;
5621 	int			status;
5622 	int			rlen;
5623 	pci_regspec_t		*reg;
5624 	int			ret = DDI_SUCCESS;
5625 	int16_t			tmp;
5626 	/*
5627 	 * flags = PCICFG_CONF_INDIRECT_MAP if configuration space is indirectly
5628 	 * mapped, otherwise it is 0. "flags" is introduced in support of any
5629 	 * non transparent bridges, where configuration space is indirectly
5630 	 * mapped.
5631 	 * Indirect mapping is always true on sun4v systems.
5632 	 */
5633 	int			flags = 0;
5634 
5635 
5636 	/*
5637 	 * Get the pci register spec from the node
5638 	 */
5639 	status = ddi_getlongprop(DDI_DEV_T_ANY,
5640 	    dip, DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &rlen);
5641 
5642 	switch (status) {
5643 		case DDI_PROP_SUCCESS:
5644 		break;
5645 		case DDI_PROP_NO_MEMORY:
5646 			DEBUG0("reg present, but unable to get memory\n");
5647 			return (PCICFG_FAILURE);
5648 		default:
5649 			DEBUG0("no reg property\n");
5650 			return (PCICFG_FAILURE);
5651 	}
5652 
5653 	if (pcicfg_indirect_map(dip) == DDI_SUCCESS)
5654 		flags |= PCICFG_CONF_INDIRECT_MAP;
5655 
5656 	/*
5657 	 * Map in configuration space (temporarily)
5658 	 */
5659 	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
5660 	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
5661 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
5662 	attr.devacc_attr_access = DDI_CAUTIOUS_ACC;
5663 
5664 #ifdef	EFCODE21554
5665 	if (ddi_regs_map_setup(dip, 0, &virt,
5666 	    0, 0, &attr, handle) != DDI_SUCCESS)
5667 #else
5668 	if (pcicfg_map_phys(dip, reg, &virt, &attr, handle)
5669 	    != DDI_SUCCESS)
5670 #endif
5671 	{
5672 		DEBUG0("pcicfg_config_setup():"
5673 		"Failed to setup config space\n");
5674 
5675 		kmem_free((caddr_t)reg, rlen);
5676 		return (PCICFG_FAILURE);
5677 	}
5678 
5679 	if (flags & PCICFG_CONF_INDIRECT_MAP) {
5680 		/*
5681 		 * need to use DDI interfaces as the conf space is
5682 		 * cannot be directly accessed by the host.
5683 		 */
5684 		tmp = (int16_t)ddi_get16(*handle, (uint16_t *)virt);
5685 	} else {
5686 		ret = ddi_peek16(dip, (int16_t *)virt, &tmp);
5687 	}
5688 
5689 	if (ret == DDI_SUCCESS) {
5690 		if (tmp == -1) {
5691 			DEBUG1("NO DEVICEFOUND, read %x\n", tmp);
5692 			ret = PCICFG_NODEVICE;
5693 		} else {
5694 			/* XXX - Need to check why HV is returning 0 */
5695 			if (tmp == 0) {
5696 				DEBUG0("Device Not Ready yet ?");
5697 				ret = PCICFG_NODEVICE;
5698 			} else {
5699 				DEBUG1("DEVICEFOUND, read %x\n", tmp);
5700 				ret = PCICFG_SUCCESS;
5701 			}
5702 		}
5703 	} else {
5704 		DEBUG0("ddi_peek failed, must be NODEVICE\n");
5705 		ret = PCICFG_NODEVICE;
5706 	}
5707 
5708 	/*
5709 	 * A bug in XMITS 3.0 causes us to miss the Master Abort Split
5710 	 * Completion message.  The result is the error message being
5711 	 * sent back as part of the config data.  If the first two words
5712 	 * of the config space happen to be the same as the Master Abort
5713 	 * message, then report back that there is no device there.
5714 	 */
5715 	if ((ret == PCICFG_SUCCESS) && !(flags & PCICFG_CONF_INDIRECT_MAP)) {
5716 		int32_t	pcix_scm;
5717 
5718 #define		PCICFG_PCIX_SCM	0x10000004
5719 
5720 		pcix_scm = 0;
5721 		(void) ddi_peek32(dip, (int32_t *)virt, &pcix_scm);
5722 		if (pcix_scm == PCICFG_PCIX_SCM) {
5723 			pcix_scm = 0;
5724 			(void) ddi_peek32(dip,
5725 			    (int32_t *)(virt + 4), &pcix_scm);
5726 			if (pcix_scm == PCICFG_PCIX_SCM)
5727 				ret = PCICFG_NODEVICE;
5728 		}
5729 	}
5730 
5731 	if (ret == PCICFG_NODEVICE)
5732 #ifdef	EFCODE21554
5733 		ddi_regs_map_free(handle);
5734 #else
5735 		pcicfg_unmap_phys(handle, reg);
5736 #endif
5737 
5738 	kmem_free((caddr_t)reg, rlen);
5739 
5740 	return (ret);
5741 
5742 }
5743 
5744 static void
5745 pcicfg_config_teardown(ddi_acc_handle_t *handle)
5746 {
5747 	(void) ddi_regs_map_free(handle);
5748 }
5749 
5750 static int
5751 pcicfg_add_config_reg(dev_info_t *dip,
5752     uint_t bus, uint_t device, uint_t func)
5753 {
5754 	int reg[10] = { PCI_ADDR_CONFIG, 0, 0, 0, 0};
5755 
5756 	reg[0] = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
5757 
5758 	return (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
5759 	    "reg", reg, 5));
5760 }
5761 
5762 static int
5763 pcicfg_dump_assigned(dev_info_t *dip)
5764 {
5765 	pci_regspec_t		*reg;
5766 	int			length;
5767 	int			rcount;
5768 	int			i;
5769 
5770 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
5771 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&reg,
5772 	    &length) != DDI_PROP_SUCCESS) {
5773 		DEBUG0("Failed to read assigned-addresses property\n");
5774 		return (PCICFG_FAILURE);
5775 	}
5776 
5777 	rcount = length / sizeof (pci_regspec_t);
5778 	for (i = 0; i < rcount; i++) {
5779 		DEBUG4("pcicfg_dump_assigned - size=%x low=%x mid=%x high=%x\n",
5780 		    reg[i].pci_size_low, reg[i].pci_phys_low,
5781 		    reg[i].pci_phys_mid, reg[i].pci_phys_hi);
5782 	}
5783 	/*
5784 	 * Don't forget to free up memory from ddi_getlongprop
5785 	 */
5786 	kmem_free((caddr_t)reg, length);
5787 
5788 	return (PCICFG_SUCCESS);
5789 }
5790 
5791 #ifdef PCICFG_INTERPRET_FCODE
5792 static int
5793 pcicfg_load_fcode(dev_info_t *dip, uint_t bus, uint_t device, uint_t func,
5794     uint16_t vendor_id, uint16_t device_id, uchar_t **fcode_addr,
5795     int *fcode_size, int rom_paddr, int rom_size)
5796 {
5797 	pci_regspec_t		p;
5798 	int			pci_data;
5799 	int			start_of_fcode;
5800 	int			image_length;
5801 	int			code_type;
5802 	ddi_acc_handle_t	h;
5803 	ddi_device_acc_attr_t	acc;
5804 	uint8_t			*addr;
5805 	int8_t			image_not_found, indicator;
5806 	uint16_t		vendor_id_img, device_id_img;
5807 	int16_t			rom_sig;
5808 #ifdef DEBUG
5809 	int i;
5810 #endif
5811 
5812 	DEBUG4("pcicfg_load_fcode() - "
5813 	    "bus %x device =%x func=%x rom_paddr=%lx\n",
5814 	    bus, device, func, rom_paddr);
5815 	DEBUG2("pcicfg_load_fcode() - vendor_id=%x device_id=%x\n",
5816 	    vendor_id, device_id);
5817 
5818 	*fcode_size = 0;
5819 	*fcode_addr = NULL;
5820 
5821 	acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
5822 	acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
5823 	acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
5824 
5825 	p.pci_phys_hi = PCI_ADDR_MEM32 | PCICFG_MAKE_REG_HIGH(bus, device,
5826 	    func, PCI_CONF_ROM);
5827 
5828 	p.pci_phys_mid = 0;
5829 	p.pci_phys_low = 0;
5830 
5831 	p.pci_size_low = rom_size;
5832 	p.pci_size_hi = 0;
5833 
5834 	if (pcicfg_map_phys(dip, &p, (caddr_t *)&addr, &acc, &h)) {
5835 		DEBUG1("Can Not map in ROM %x\n", p.pci_phys_low);
5836 		return (PCICFG_FAILURE);
5837 	}
5838 
5839 	/*
5840 	 * Walk the ROM to find the proper image for this device.
5841 	 */
5842 	image_not_found = 1;
5843 	while (image_not_found) {
5844 		DEBUG1("Expansion ROM maps to %lx\n", addr);
5845 
5846 #ifdef DEBUG
5847 		if (pcicfg_dump_fcode) {
5848 			for (i = 0; i < 100; i++)
5849 				DEBUG2("ROM 0x%x --> 0x%x\n", i,
5850 				    ddi_get8(h, (uint8_t *)(addr + i)));
5851 		}
5852 #endif
5853 
5854 		/*
5855 		 * Some device say they have an Expansion ROM, but do not, so
5856 		 * for non-21554 devices use peek so we don't panic due to
5857 		 * accessing non existent memory.
5858 		 */
5859 		if (pcicfg_indirect_map(dip) == DDI_SUCCESS) {
5860 			rom_sig = ddi_get16(h,
5861 			    (uint16_t *)(addr + PCI_ROM_SIGNATURE));
5862 		} else {
5863 			if (ddi_peek16(dip,
5864 			    (int16_t *)(addr + PCI_ROM_SIGNATURE), &rom_sig)) {
5865 				cmn_err(CE_WARN,
5866 				    "PCI Expansion ROM is not accessible");
5867 				pcicfg_unmap_phys(&h, &p);
5868 				return (PCICFG_FAILURE);
5869 			}
5870 		}
5871 
5872 		/*
5873 		 * Validate the ROM Signature.
5874 		 */
5875 		if ((uint16_t)rom_sig != 0xaa55) {
5876 			DEBUG1("Invalid ROM Signature %x\n", (uint16_t)rom_sig);
5877 			pcicfg_unmap_phys(&h, &p);
5878 			return (PCICFG_FAILURE);
5879 		}
5880 
5881 		DEBUG0("Valid ROM Signature Found\n");
5882 
5883 		start_of_fcode = ddi_get16(h, (uint16_t *)(addr + 2));
5884 
5885 		pci_data =  ddi_get16(h,
5886 		    (uint16_t *)(addr + PCI_ROM_PCI_DATA_STRUCT_PTR));
5887 
5888 		DEBUG2("Pointer To PCI Data Structure %x %x\n", pci_data,
5889 		    addr);
5890 
5891 		/*
5892 		 * Validate the PCI Data Structure Signature.
5893 		 * 0x52494350 = "PCIR"
5894 		 */
5895 
5896 		if (ddi_get8(h, (uint8_t *)(addr + pci_data)) != 0x50) {
5897 			DEBUG0("Invalid PCI Data Structure Signature\n");
5898 			pcicfg_unmap_phys(&h, &p);
5899 			return (PCICFG_FAILURE);
5900 		}
5901 
5902 		if (ddi_get8(h, (uint8_t *)(addr + pci_data + 1)) != 0x43) {
5903 			DEBUG0("Invalid PCI Data Structure Signature\n");
5904 			pcicfg_unmap_phys(&h, &p);
5905 			return (PCICFG_FAILURE);
5906 		}
5907 		if (ddi_get8(h, (uint8_t *)(addr + pci_data + 2)) != 0x49) {
5908 			DEBUG0("Invalid PCI Data Structure Signature\n");
5909 			pcicfg_unmap_phys(&h, &p);
5910 			return (PCICFG_FAILURE);
5911 		}
5912 		if (ddi_get8(h, (uint8_t *)(addr + pci_data + 3)) != 0x52) {
5913 			DEBUG0("Invalid PCI Data Structure Signature\n");
5914 			pcicfg_unmap_phys(&h, &p);
5915 			return (PCICFG_FAILURE);
5916 		}
5917 
5918 		/*
5919 		 * Is this image for this device?
5920 		 */
5921 		vendor_id_img = ddi_get16(h,
5922 		    (uint16_t *)(addr + pci_data + PCI_PDS_VENDOR_ID));
5923 		device_id_img = ddi_get16(h,
5924 		    (uint16_t *)(addr + pci_data + PCI_PDS_DEVICE_ID));
5925 
5926 		DEBUG2("This image is for vendor_id=%x device_id=%x\n",
5927 		    vendor_id_img, device_id_img);
5928 
5929 		code_type = ddi_get8(h, addr + pci_data + PCI_PDS_CODE_TYPE);
5930 
5931 		switch (code_type) {
5932 		case PCI_PDS_CODE_TYPE_PCAT:
5933 			DEBUG0("ROM is of x86/PC-AT Type\n");
5934 			break;
5935 		case PCI_PDS_CODE_TYPE_OPEN_FW:
5936 			DEBUG0("ROM is of Open Firmware Type\n");
5937 			break;
5938 		default:
5939 			DEBUG1("ROM is of Unknown Type 0x%x\n", code_type);
5940 			break;
5941 		}
5942 
5943 		if ((vendor_id_img != vendor_id) ||
5944 		    (device_id_img != device_id) ||
5945 		    (code_type != PCI_PDS_CODE_TYPE_OPEN_FW)) {
5946 			DEBUG0("Firmware Image is not for this device..."
5947 			    "goto next image\n");
5948 			/*
5949 			 * Read indicator byte to see if there is another
5950 			 * image in the ROM
5951 			 */
5952 			indicator = ddi_get8(h,
5953 			    (uint8_t *)(addr + pci_data + PCI_PDS_INDICATOR));
5954 
5955 			if (indicator != 1) {
5956 				/*
5957 				 * There is another image in the ROM.
5958 				 */
5959 				image_length = ddi_get16(h,  (uint16_t *)(addr +
5960 				    pci_data + PCI_PDS_IMAGE_LENGTH)) * 512;
5961 
5962 				addr += image_length;
5963 			} else {
5964 				/*
5965 				 * There are no more images.
5966 				 */
5967 				DEBUG0("There are no more images in the ROM\n");
5968 				pcicfg_unmap_phys(&h, &p);
5969 
5970 				return (PCICFG_FAILURE);
5971 			}
5972 		} else {
5973 			DEBUG0("Correct image was found\n");
5974 			image_not_found = 0;  /* Image was found */
5975 		}
5976 	}
5977 
5978 	*fcode_size =  (ddi_get8(h, addr + start_of_fcode + 4) << 24) |
5979 	    (ddi_get8(h, addr + start_of_fcode + 5) << 16) |
5980 	    (ddi_get8(h, addr + start_of_fcode + 6) << 8) |
5981 	    (ddi_get8(h, addr + start_of_fcode + 7));
5982 
5983 	DEBUG1("Fcode Size %x\n", *fcode_size);
5984 
5985 	/*
5986 	 * Allocate page aligned buffer space
5987 	 */
5988 	*fcode_addr = kmem_zalloc(ptob(btopr(*fcode_size)), KM_SLEEP);
5989 
5990 	if (*fcode_addr == NULL) {
5991 		DEBUG0("kmem_zalloc returned NULL\n");
5992 		pcicfg_unmap_phys(&h, &p);
5993 		return (PCICFG_FAILURE);
5994 	}
5995 
5996 	DEBUG1("Fcode Addr %lx\n", *fcode_addr);
5997 
5998 	ddi_rep_get8(h, *fcode_addr, addr + start_of_fcode, *fcode_size,
5999 	    DDI_DEV_AUTOINCR);
6000 
6001 	pcicfg_unmap_phys(&h, &p);
6002 
6003 	return (PCICFG_SUCCESS);
6004 }
6005 
6006 static int
6007 pcicfg_fcode_assign_bars(ddi_acc_handle_t h, dev_info_t *dip, uint_t bus,
6008     uint_t device, uint_t func, int32_t fc_request, pci_regspec_t *rom_regspec)
6009 {
6010 	/*
6011 	 * Assign values to all BARs so that it is safe to turn on the
6012 	 * device for accessing the fcode on the PROM. On successful
6013 	 * exit from this function, "assigned-addresses" are created
6014 	 * for all BARs and ROM BAR is enabled. Also, rom_regspec is
6015 	 * filled with the values that can be used to free up this
6016 	 * resource later.
6017 	 */
6018 	uint32_t request, hiword, size;
6019 	pci_regspec_t phys_spec;
6020 	ndi_ra_request_t req;
6021 	uint64_t mem_answer, mem_alen;
6022 	int i;
6023 
6024 	DEBUG1("pcicfg_fcode_assign_bars :%s\n", DEVI(dip)->devi_name);
6025 
6026 	/*
6027 	 * Process the BARs.
6028 	 */
6029 	for (i = PCI_CONF_BASE0; i <= PCI_CONF_BASE5; ) {
6030 		pci_config_put32(h, i, 0xffffffff);
6031 		request = pci_config_get32(h, i);
6032 		/*
6033 		 * Check if implemented
6034 		 */
6035 		if (request == 0) {
6036 			DEBUG1("pcicfg_fcode_assign_bars :"
6037 			    "BASE register [0x%x] asks for 0(32)\n", i);
6038 			i += 4;
6039 			continue;
6040 		}
6041 		/*
6042 		 * Build the phys_spec for this BAR
6043 		 */
6044 		hiword = PCICFG_MAKE_REG_HIGH(bus, device, func, i);
6045 		size = (~(PCI_BASE_M_ADDR_M & request)) + 1;
6046 
6047 		DEBUG3("pcicfg_fcode_assign_bars :"
6048 		    "BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
6049 		    i, request, size);
6050 
6051 		if ((PCI_BASE_SPACE_M & request) == PCI_BASE_SPACE_MEM) {
6052 			if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_MEM) {
6053 				hiword |= PCI_ADDR_MEM32;
6054 			} else if ((PCI_BASE_TYPE_M & request)
6055 			    == PCI_BASE_TYPE_ALL) {
6056 				hiword |= PCI_ADDR_MEM64;
6057 			}
6058 			if (request & PCI_BASE_PREF_M)
6059 				hiword |= PCI_REG_PF_M;
6060 		} else {
6061 			hiword |= PCI_ADDR_IO;
6062 		}
6063 		phys_spec.pci_phys_hi = hiword;
6064 		phys_spec.pci_phys_mid = 0;
6065 		phys_spec.pci_phys_low = 0;
6066 		phys_spec.pci_size_hi = 0;
6067 		phys_spec.pci_size_low = size;
6068 
6069 		/*
6070 		 * The following function
6071 		 * - allocates address space
6072 		 * - programs the BAR
6073 		 * - adds an "assigned-addresses" property
6074 		 */
6075 		if (pcicfg_alloc_resource(dip, phys_spec)) {
6076 			cmn_err(CE_WARN, "failed to allocate %d bytes"
6077 			    " for dev %s BASE register [0x%x]\n",
6078 			    size, DEVI(dip)->devi_name, i);
6079 			goto failure;
6080 		}
6081 		if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
6082 			/*
6083 			 * 64 bit, should be in memory space.
6084 			 */
6085 			i += 8;
6086 		} else {
6087 			/*
6088 			 * 32 bit, either memory or I/O space.
6089 			 */
6090 			i += 4;
6091 		}
6092 	}
6093 
6094 	/*
6095 	 * Handle ROM BAR. We do not use the common
6096 	 * resource allocator function because we need to
6097 	 * return reg spec to the caller.
6098 	 */
6099 	size = (~(PCI_BASE_ROM_ADDR_M & fc_request)) + 1;
6100 
6101 	DEBUG3("BASE register [0x%x] asks for "
6102 	    "[0x%x]=[0x%x]\n", PCI_CONF_ROM, fc_request, size);
6103 
6104 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
6105 
6106 	req.ra_boundbase = 0;
6107 	req.ra_boundlen = PCICFG_4GIG_LIMIT;
6108 	req.ra_len = size;
6109 	req.ra_flags = (NDI_RA_ALIGN_SIZE | NDI_RA_ALLOC_BOUNDED);
6110 
6111 	if (ndi_ra_alloc(ddi_get_parent(dip),
6112 	    &req, &mem_answer, &mem_alen,
6113 	    NDI_RA_TYPE_MEM, NDI_RA_PASS)) {
6114 		cmn_err(CE_WARN, "failed to allocate %d bytes"
6115 		    " for dev %s ROM BASE register\n",
6116 		    size, DEVI(dip)->devi_name);
6117 		goto failure;
6118 	}
6119 
6120 	DEBUG3("ROM addr = [0x%x.%x] len [0x%x]\n",
6121 	    PCICFG_HIADDR(mem_answer),
6122 	    PCICFG_LOADDR(mem_answer), mem_alen);
6123 
6124 	/*
6125 	 * Assign address space and enable ROM.
6126 	 */
6127 	pci_config_put32(h, PCI_CONF_ROM,
6128 	    PCICFG_LOADDR(mem_answer) | PCI_BASE_ROM_ENABLE);
6129 
6130 	/*
6131 	 * Add resource to assigned-addresses.
6132 	 */
6133 	phys_spec.pci_phys_hi = PCICFG_MAKE_REG_HIGH(bus, device, func, \
6134 	    PCI_CONF_ROM) | PCI_ADDR_MEM32;
6135 	if (fc_request & PCI_BASE_PREF_M)
6136 		phys_spec.pci_phys_hi |= PCI_REG_PF_M;
6137 	phys_spec.pci_phys_mid = 0;
6138 	phys_spec.pci_phys_low = PCICFG_LOADDR(mem_answer);
6139 	phys_spec.pci_size_hi = 0;
6140 	phys_spec.pci_size_low = size;
6141 
6142 	if (pcicfg_update_assigned_prop(dip, &phys_spec)
6143 	    != PCICFG_SUCCESS) {
6144 		cmn_err(CE_WARN, "failed to update"
6145 		    " assigned-address property for dev %s\n",
6146 		    DEVI(dip)->devi_name);
6147 		goto failure;
6148 	}
6149 	/*
6150 	 * Copy out the reg spec.
6151 	 */
6152 	*rom_regspec = phys_spec;
6153 
6154 	return (PCICFG_SUCCESS);
6155 
6156 failure:
6157 	/*
6158 	 * We came in with no "assigned-addresses".
6159 	 * Free up the resources we may have allocated.
6160 	 */
6161 	(void) pcicfg_free_device_resources(dip, 0);
6162 
6163 	return (PCICFG_FAILURE);
6164 }
6165 
6166 #endif /* PCICFG_INTERPRET_FCODE */
6167 
6168 static int
6169 pcicfg_free_all_resources(dev_info_t *dip)
6170 {
6171 	pci_regspec_t		*assigned;
6172 	int			assigned_len;
6173 	int			acount;
6174 	int			i;
6175 
6176 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6177 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
6178 	    &assigned_len) != DDI_PROP_SUCCESS) {
6179 		DEBUG0("Failed to read assigned-addresses property\n");
6180 		return (PCICFG_FAILURE);
6181 	}
6182 
6183 	acount = assigned_len / sizeof (pci_regspec_t);
6184 
6185 	for (i = 0; i < acount; i++) {
6186 		if (pcicfg_free_resource(dip, assigned[i], 0)) {
6187 			/*
6188 			 * Dont forget to free mem from ddi_getlongprop
6189 			 */
6190 			kmem_free((caddr_t)assigned, assigned_len);
6191 			return (PCICFG_FAILURE);
6192 		}
6193 	}
6194 
6195 	/*
6196 	 * Don't forget to free up memory from ddi_getlongprop
6197 	 */
6198 	if (assigned_len)
6199 		kmem_free((caddr_t)assigned, assigned_len);
6200 
6201 	return (PCICFG_SUCCESS);
6202 }
6203 static int
6204 pcicfg_alloc_new_resources(dev_info_t *dip)
6205 {
6206 	pci_regspec_t		*assigned, *reg;
6207 	int			assigned_len, reg_len;
6208 	int			acount, rcount;
6209 	int			i, j, alloc_size;
6210 	boolean_t		alloc;
6211 
6212 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6213 	    DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
6214 	    &reg_len) != DDI_PROP_SUCCESS) {
6215 		DEBUG0("Failed to read reg property\n");
6216 		return (PCICFG_FAILURE);
6217 	}
6218 	rcount = reg_len / sizeof (pci_regspec_t);
6219 
6220 	DEBUG2("pcicfg_alloc_new_resources() reg size=%x entries=%x\n",
6221 	    reg_len, rcount);
6222 
6223 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6224 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
6225 	    &assigned_len) != DDI_PROP_SUCCESS) {
6226 		acount = 0;
6227 	} else {
6228 		acount = assigned_len / sizeof (pci_regspec_t);
6229 	}
6230 
6231 	DEBUG1("assigned-addresses property len=%x\n", acount);
6232 
6233 	/*
6234 	 * For each address described by reg, search for it in the
6235 	 * assigned-addresses property. If it does not exist, allocate
6236 	 * resources for it. If it does exist, check the size in both.
6237 	 * The size needs to be bigger of the two.
6238 	 */
6239 	for (i = 1; i < rcount; i++) {
6240 		alloc = B_TRUE;
6241 		alloc_size = reg[i].pci_size_low;
6242 		for (j = 0; j < acount; j++) {
6243 			if (assigned[j].pci_phys_hi == reg[i].pci_phys_hi) {
6244 				/*
6245 				 * There is an exact match. Check size.
6246 				 */
6247 				DEBUG1("pcicfg_alloc_new_resources "
6248 				    "- %x - MATCH\n",
6249 				    reg[i].pci_phys_hi);
6250 
6251 				if (reg[i].pci_size_low >
6252 				    assigned[j].pci_size_low) {
6253 					/*
6254 					 * Fcode wants more.
6255 					 */
6256 					DEBUG3("pcicfg_alloc_new_resources"
6257 					    " - %x - RESIZE"
6258 					    " assigned 0x%x reg 0x%x\n",
6259 					    assigned[j].pci_phys_hi,
6260 					    assigned[j].pci_size_low,
6261 					    reg[i].pci_size_low);
6262 
6263 					/*
6264 					 * Free the old resource.
6265 					 */
6266 					(void) pcicfg_free_resource(dip,
6267 					    assigned[j], 0);
6268 				} else {
6269 					DEBUG3("pcicfg_alloc_new_resources"
6270 					    " - %x - ENOUGH"
6271 					    " assigned 0x%x reg 0x%x\n",
6272 					    assigned[j].pci_phys_hi,
6273 					    assigned[j].pci_size_low,
6274 					    reg[i].pci_size_low);
6275 
6276 					alloc = B_FALSE;
6277 				}
6278 				break;
6279 			}
6280 			/*
6281 			 * Fcode may have set one or more of the
6282 			 * NPT bits in phys.hi.
6283 			 */
6284 			if (PCI_REG_BDFR_G(assigned[j].pci_phys_hi) ==
6285 			    PCI_REG_BDFR_G(reg[i].pci_phys_hi)) {
6286 
6287 				DEBUG2("pcicfg_alloc_new_resources "
6288 				    "- PARTIAL MATCH assigned 0x%x "
6289 				    "reg 0x%x\n", assigned[j].pci_phys_hi,
6290 				    reg[i].pci_phys_hi);
6291 				/*
6292 				 * Changing the SS bits is an error
6293 				 */
6294 				if (PCI_REG_ADDR_G(
6295 				    assigned[j].pci_phys_hi) !=
6296 				    PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
6297 
6298 					DEBUG2("Fcode changing"
6299 					    " SS bits of - 0x%x -"
6300 					    " on %s\n", reg[i].pci_phys_hi,
6301 					    DEVI(dip)->devi_name);
6302 
6303 				}
6304 
6305 
6306 				/*
6307 				 * We are going to allocate new resource.
6308 				 * Free the old resource. Again, adjust
6309 				 * the size to be safe.
6310 				 */
6311 				(void) pcicfg_free_resource(dip,
6312 				    assigned[j], 0);
6313 
6314 				alloc_size = MAX(reg[i].pci_size_low,
6315 				    assigned[j].pci_size_low);
6316 
6317 				break;
6318 			}
6319 		}
6320 		/*
6321 		 * We are allocating resources for one of three reasons -
6322 		 * - Fcode wants a larger address space
6323 		 * - Fcode has set changed/set n, p, t bits.
6324 		 * - It is a new "reg", it should be only ROM bar, but
6325 		 *   we don't do the checking.
6326 		 */
6327 		if (alloc == B_TRUE) {
6328 			DEBUG1("pcicfg_alloc_new_resources : creating 0x%x\n",
6329 			    reg[i].pci_phys_hi);
6330 
6331 			reg[i].pci_size_low = alloc_size;
6332 			if (pcicfg_alloc_resource(dip, reg[i])) {
6333 				/*
6334 				 * Dont forget to free mem from
6335 				 * ddi_getlongprop
6336 				 */
6337 				if (acount != 0)
6338 					kmem_free((caddr_t)assigned,
6339 					    assigned_len);
6340 				kmem_free((caddr_t)reg, reg_len);
6341 				return (PCICFG_FAILURE);
6342 			}
6343 		}
6344 	}
6345 
6346 	/*
6347 	 * Don't forget to free up memory from ddi_getlongprop
6348 	 */
6349 	if (acount != 0)
6350 		kmem_free((caddr_t)assigned, assigned_len);
6351 	kmem_free((caddr_t)reg, reg_len);
6352 
6353 	return (PCICFG_SUCCESS);
6354 }
6355 
6356 static int
6357 pcicfg_alloc_resource(dev_info_t *dip, pci_regspec_t phys_spec)
6358 {
6359 	uint64_t answer;
6360 	uint64_t alen;
6361 	int offset;
6362 	pci_regspec_t config;
6363 	caddr_t virt, v;
6364 	ddi_device_acc_attr_t acc;
6365 	ddi_acc_handle_t h;
6366 	ndi_ra_request_t request;
6367 	pci_regspec_t *assigned;
6368 	int assigned_len, entries, i;
6369 
6370 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6371 	    DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
6372 	    &assigned_len) == DDI_PROP_SUCCESS) {
6373 		DEBUG0("pcicfg_alloc_resource - "
6374 		    "searching assigned-addresses\n");
6375 
6376 		entries = assigned_len / (sizeof (pci_regspec_t));
6377 
6378 		/*
6379 		 * Walk through the assigned-addresses entries. If there is
6380 		 * a match, there is no need to allocate the resource.
6381 		 */
6382 		for (i = 0; i < entries; i++) {
6383 			if (assigned[i].pci_phys_hi == phys_spec.pci_phys_hi) {
6384 				DEBUG1("pcicfg_alloc_resource - MATCH %x\n",
6385 				    assigned[i].pci_phys_hi);
6386 				kmem_free(assigned, assigned_len);
6387 				return (0);
6388 			}
6389 		}
6390 		kmem_free(assigned, assigned_len);
6391 	}
6392 
6393 	bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
6394 
6395 	config.pci_phys_hi = PCI_CONF_ADDR_MASK & phys_spec.pci_phys_hi;
6396 	config.pci_phys_hi &= ~PCI_REG_REG_M;
6397 	config.pci_phys_mid = config.pci_phys_low = 0;
6398 	config.pci_size_hi = config.pci_size_low = 0;
6399 
6400 	/*
6401 	 * Map in configuration space (temporarily)
6402 	 */
6403 	acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
6404 	acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
6405 	acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
6406 
6407 	if (pcicfg_map_phys(dip, &config, &virt, &acc, &h)) {
6408 		DEBUG0("Can not map in config space\n");
6409 		return (1);
6410 	}
6411 
6412 	request.ra_flags = NDI_RA_ALIGN_SIZE;
6413 	request.ra_boundbase = 0;
6414 	request.ra_boundlen = PCICFG_4GIG_LIMIT;
6415 	/*
6416 	 * Use size stored in phys_spec parameter.
6417 	 */
6418 	request.ra_len = phys_spec.pci_size_low;
6419 
6420 	offset = PCI_REG_REG_G(phys_spec.pci_phys_hi);
6421 
6422 	v = virt + offset;
6423 
6424 	if (PCI_REG_REG_G(phys_spec.pci_phys_hi) == PCI_CONF_ROM) {
6425 
6426 		request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
6427 
6428 		/* allocate memory space from the allocator */
6429 
6430 		if (ndi_ra_alloc(ddi_get_parent(dip),
6431 		    &request, &answer, &alen,
6432 		    NDI_RA_TYPE_MEM, NDI_RA_PASS)
6433 		    != NDI_SUCCESS) {
6434 			DEBUG0("(ROM)Failed to allocate 32b mem");
6435 			pcicfg_unmap_phys(&h, &config);
6436 			return (1);
6437 		}
6438 		DEBUG3("ROM addr = [0x%x.%x] len [0x%x]\n",
6439 		    PCICFG_HIADDR(answer),
6440 		    PCICFG_LOADDR(answer),
6441 		    alen);
6442 
6443 		/* program the low word */
6444 
6445 		ddi_put32(h, (uint32_t *)v, (uint32_t)PCICFG_LOADDR(answer));
6446 
6447 		phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6448 		phys_spec.pci_phys_mid = PCICFG_HIADDR(answer);
6449 	} else {
6450 
6451 		switch (PCI_REG_ADDR_G(phys_spec.pci_phys_hi)) {
6452 		case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
6453 			request.ra_flags &= ~NDI_RA_ALLOC_BOUNDED;
6454 			/* allocate memory space from the allocator */
6455 			if (ndi_ra_alloc(ddi_get_parent(dip),
6456 			    &request, &answer, &alen,
6457 			    NDI_RA_TYPE_MEM, NDI_RA_PASS)
6458 			    != NDI_SUCCESS) {
6459 				DEBUG0("Failed to allocate 64b mem\n");
6460 				pcicfg_unmap_phys(&h, &config);
6461 				return (1);
6462 			}
6463 			DEBUG3("64 addr = [0x%x.%x] len [0x%x]\n",
6464 			    PCICFG_HIADDR(answer),
6465 			    PCICFG_LOADDR(answer),
6466 			    alen);
6467 
6468 			/* program the low word */
6469 
6470 			ddi_put32(h, (uint32_t *)v,
6471 			    (uint32_t)PCICFG_LOADDR(answer));
6472 
6473 			/* program the high word with value zero */
6474 			v += 4;
6475 			ddi_put32(h, (uint32_t *)v,
6476 			    (uint32_t)PCICFG_HIADDR(answer));
6477 
6478 			phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6479 			phys_spec.pci_phys_mid = PCICFG_HIADDR(answer);
6480 			/*
6481 			 * currently support 32b address space
6482 			 * assignments only.
6483 			 */
6484 			phys_spec.pci_phys_hi ^= PCI_ADDR_MEM64 ^
6485 			    PCI_ADDR_MEM32;
6486 
6487 			break;
6488 
6489 		case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
6490 			request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
6491 			/* allocate memory space from the allocator */
6492 			if (ndi_ra_alloc(ddi_get_parent(dip),
6493 			    &request, &answer, &alen,
6494 			    NDI_RA_TYPE_MEM, NDI_RA_PASS)
6495 			    != NDI_SUCCESS) {
6496 				DEBUG0("Failed to allocate 32b mem\n");
6497 				pcicfg_unmap_phys(&h, &config);
6498 				return (1);
6499 			}
6500 
6501 			DEBUG3("32 addr = [0x%x.%x] len [0x%x]\n",
6502 			    PCICFG_HIADDR(answer),
6503 			    PCICFG_LOADDR(answer),
6504 			    alen);
6505 
6506 			/* program the low word */
6507 
6508 			ddi_put32(h, (uint32_t *)v,
6509 			    (uint32_t)PCICFG_LOADDR(answer));
6510 
6511 			phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6512 
6513 			break;
6514 		case PCI_REG_ADDR_G(PCI_ADDR_IO):
6515 			/* allocate I/O space from the allocator */
6516 			request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
6517 			if (ndi_ra_alloc(ddi_get_parent(dip),
6518 			    &request, &answer, &alen,
6519 			    NDI_RA_TYPE_IO, NDI_RA_PASS)
6520 			    != NDI_SUCCESS) {
6521 				DEBUG0("Failed to allocate I/O\n");
6522 				pcicfg_unmap_phys(&h, &config);
6523 				return (1);
6524 			}
6525 			DEBUG3("I/O addr = [0x%x.%x] len [0x%x]\n",
6526 			    PCICFG_HIADDR(answer),
6527 			    PCICFG_LOADDR(answer),
6528 			    alen);
6529 
6530 			ddi_put32(h, (uint32_t *)v,
6531 			    (uint32_t)PCICFG_LOADDR(answer));
6532 
6533 			phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6534 
6535 			break;
6536 		default:
6537 			DEBUG0("Unknown register type\n");
6538 			pcicfg_unmap_phys(&h, &config);
6539 			return (1);
6540 		} /* switch */
6541 	}
6542 
6543 	/*
6544 	 * Now that memory locations are assigned,
6545 	 * update the assigned address property.
6546 	 */
6547 
6548 	DEBUG1("updating assigned-addresss for %x\n",  phys_spec.pci_phys_hi);
6549 
6550 	if (pcicfg_update_assigned_prop(dip, &phys_spec)) {
6551 		pcicfg_unmap_phys(&h, &config);
6552 		return (1);
6553 	}
6554 
6555 	pcicfg_unmap_phys(&h, &config);
6556 
6557 	return (0);
6558 }
6559 
6560 static int
6561 pcicfg_free_resource(dev_info_t *dip, pci_regspec_t phys_spec,
6562     pcicfg_flags_t flags)
6563 {
6564 	int offset;
6565 	pci_regspec_t config;
6566 	caddr_t virt, v;
6567 	ddi_device_acc_attr_t acc;
6568 	ddi_acc_handle_t h;
6569 	ndi_ra_request_t request;
6570 	int l;
6571 
6572 	bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
6573 
6574 	config.pci_phys_hi = PCI_CONF_ADDR_MASK & phys_spec.pci_phys_hi;
6575 	config.pci_phys_hi &= ~PCI_REG_REG_M;
6576 	config.pci_phys_mid = config.pci_phys_low = 0;
6577 	config.pci_size_hi = config.pci_size_low = 0;
6578 
6579 	/*
6580 	 * Map in configuration space (temporarily)
6581 	 */
6582 	acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
6583 	acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
6584 	acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
6585 
6586 	if (pcicfg_map_phys(dip, &config, &virt, &acc, &h)) {
6587 		DEBUG0("Can not map in config space\n");
6588 		return (1);
6589 	}
6590 
6591 	offset = PCI_REG_REG_G(phys_spec.pci_phys_hi);
6592 
6593 	v = virt + offset;
6594 
6595 	/*
6596 	 * Use size stored in phys_spec parameter.
6597 	 */
6598 	l = phys_spec.pci_size_low;
6599 
6600 	if (PCI_REG_REG_G(phys_spec.pci_phys_hi) == PCI_CONF_ROM) {
6601 
6602 		/* free memory back to the allocator */
6603 		if (ndi_ra_free(ddi_get_parent(dip), phys_spec.pci_phys_low,
6604 		    l, NDI_RA_TYPE_MEM, NDI_RA_PASS) != NDI_SUCCESS) {
6605 			DEBUG0("(ROM)Can not free 32b mem");
6606 			pcicfg_unmap_phys(&h, &config);
6607 			return (1);
6608 		}
6609 
6610 		/* Unmap the BAR by writing a zero */
6611 
6612 		if ((flags & PCICFG_FLAG_READ_ONLY) == 0)
6613 			ddi_put32(h, (uint32_t *)v, (uint32_t)0);
6614 	} else {
6615 
6616 		switch (PCI_REG_ADDR_G(phys_spec.pci_phys_hi)) {
6617 
6618 		case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
6619 		case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
6620 			/* free memory back to the allocator */
6621 			if (ndi_ra_free(ddi_get_parent(dip),
6622 			    PCICFG_LADDR(phys_spec.pci_phys_low,
6623 			    phys_spec.pci_phys_mid),
6624 			    l, NDI_RA_TYPE_MEM,
6625 			    NDI_RA_PASS) != NDI_SUCCESS) {
6626 				DEBUG0("Cannot free mem");
6627 				pcicfg_unmap_phys(&h, &config);
6628 				return (1);
6629 			}
6630 			break;
6631 
6632 		case PCI_REG_ADDR_G(PCI_ADDR_IO):
6633 			/* free I/O space back to the allocator */
6634 			if (ndi_ra_free(ddi_get_parent(dip),
6635 			    phys_spec.pci_phys_low,
6636 			    l, NDI_RA_TYPE_IO,
6637 			    NDI_RA_PASS) != NDI_SUCCESS) {
6638 				DEBUG0("Can not free I/O space");
6639 				pcicfg_unmap_phys(&h, &config);
6640 				return (1);
6641 			}
6642 			break;
6643 
6644 		default:
6645 			DEBUG0("Unknown register type\n");
6646 			pcicfg_unmap_phys(&h, &config);
6647 			return (1);
6648 		} /* switch */
6649 	}
6650 
6651 	/*
6652 	 * Now that memory locations are assigned,
6653 	 * update the assigned address property.
6654 	 */
6655 
6656 	DEBUG1("updating assigned-addresss for %x\n", phys_spec.pci_phys_hi);
6657 
6658 	if (pcicfg_remove_assigned_prop(dip, &phys_spec)) {
6659 		pcicfg_unmap_phys(&h, &config);
6660 		return (1);
6661 	}
6662 
6663 	pcicfg_unmap_phys(&h, &config);
6664 
6665 	return (0);
6666 }
6667 
6668 static int
6669 pcicfg_remove_assigned_prop(dev_info_t *dip, pci_regspec_t *oldone)
6670 {
6671 	int		alen, num_entries, i;
6672 	pci_regspec_t	*assigned, *assigned_copy;
6673 	uint_t		status;
6674 
6675 	status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
6676 	    "assigned-addresses", (caddr_t)&assigned, &alen);
6677 	switch (status) {
6678 		case DDI_PROP_SUCCESS:
6679 		break;
6680 		case DDI_PROP_NO_MEMORY:
6681 			DEBUG0("no memory for assigned-addresses property\n");
6682 			return (1);
6683 		default:
6684 			DEBUG0("assigned-addresses property does not exist\n");
6685 			return (0);
6686 	}
6687 
6688 	/*
6689 	 * Make a copy of old assigned-addresses property.
6690 	 */
6691 	assigned_copy = kmem_alloc(alen, KM_SLEEP);
6692 	bcopy(assigned, assigned_copy, alen);
6693 
6694 	status = ndi_prop_remove(DDI_DEV_T_NONE, dip, "assigned-addresses");
6695 
6696 	if (status != DDI_PROP_SUCCESS) {
6697 		/*
6698 		 * If "assigned-addresses" is retrieved from PROM, the
6699 		 * ndi_prop_remove() will fail.
6700 		 */
6701 		DEBUG1("pcicfg_remove_assigned_prop: 0x%x not removed\n",
6702 		    oldone->pci_phys_hi);
6703 
6704 		/*
6705 		 * Free up allocated memory
6706 		 */
6707 		kmem_free(assigned_copy, alen);
6708 		kmem_free((caddr_t)assigned, alen);
6709 
6710 		return (0);
6711 	}
6712 
6713 	num_entries = alen / sizeof (pci_regspec_t);
6714 
6715 	/*
6716 	 * Rebuild the assigned-addresses property.
6717 	 */
6718 	for (i = 0; i < num_entries; i++) {
6719 		if (assigned_copy[i].pci_phys_hi != oldone->pci_phys_hi) {
6720 			(void) pcicfg_update_assigned_prop(dip,
6721 			    &assigned_copy[i]);
6722 		}
6723 	}
6724 
6725 	/*
6726 	 * Free the copy of the original assigned-addresses.
6727 	 */
6728 	kmem_free(assigned_copy, alen);
6729 
6730 	/*
6731 	 * Don't forget to free up memory from ddi_getlongprop
6732 	 */
6733 	kmem_free((caddr_t)assigned, alen);
6734 
6735 	return (0);
6736 }
6737 
6738 static int
6739 pcicfg_map_phys(dev_info_t *dip, pci_regspec_t *phys_spec,
6740     caddr_t *addrp, ddi_device_acc_attr_t *accattrp,
6741     ddi_acc_handle_t *handlep)
6742 {
6743 	ddi_map_req_t mr;
6744 	ddi_acc_hdl_t *hp;
6745 	int result;
6746 
6747 	*handlep = impl_acc_hdl_alloc(KM_SLEEP, NULL);
6748 	hp = impl_acc_hdl_get(*handlep);
6749 	hp->ah_vers = VERS_ACCHDL;
6750 	hp->ah_dip = dip;
6751 	hp->ah_rnumber = 0;
6752 	hp->ah_offset = 0;
6753 	hp->ah_len = 0;
6754 	hp->ah_acc = *accattrp;
6755 
6756 	mr.map_op = DDI_MO_MAP_LOCKED;
6757 	mr.map_type = DDI_MT_REGSPEC;
6758 	mr.map_obj.rp = (struct regspec *)phys_spec;
6759 	mr.map_prot = PROT_READ | PROT_WRITE;
6760 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
6761 	mr.map_handlep = hp;
6762 	mr.map_vers = DDI_MAP_VERSION;
6763 
6764 	result = ddi_map(dip, &mr, 0, 0, addrp);
6765 
6766 	if (result != DDI_SUCCESS) {
6767 		impl_acc_hdl_free(*handlep);
6768 		*handlep = (ddi_acc_handle_t)NULL;
6769 	} else {
6770 		hp->ah_addr = *addrp;
6771 	}
6772 
6773 	return (result);
6774 }
6775 
6776 void
6777 pcicfg_unmap_phys(ddi_acc_handle_t *handlep,  pci_regspec_t *ph)
6778 {
6779 	ddi_map_req_t mr;
6780 	ddi_acc_hdl_t *hp;
6781 
6782 	hp = impl_acc_hdl_get(*handlep);
6783 	ASSERT(hp);
6784 
6785 	mr.map_op = DDI_MO_UNMAP;
6786 	mr.map_type = DDI_MT_REGSPEC;
6787 	mr.map_obj.rp = (struct regspec *)ph;
6788 	mr.map_prot = PROT_READ | PROT_WRITE;
6789 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
6790 	mr.map_handlep = hp;
6791 	mr.map_vers = DDI_MAP_VERSION;
6792 
6793 	(void) ddi_map(hp->ah_dip, &mr, hp->ah_offset,
6794 	    hp->ah_len, &hp->ah_addr);
6795 
6796 	impl_acc_hdl_free(*handlep);
6797 	*handlep = (ddi_acc_handle_t)NULL;
6798 }
6799 
6800 static int
6801 pcicfg_ari_configure(dev_info_t *dip)
6802 {
6803 	if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
6804 		return (DDI_FAILURE);
6805 
6806 	/*
6807 	 * Until we have resource balancing, dynamically configure
6808 	 * ARI functions without firmware assistamce.
6809 	 */
6810 	return (DDI_FAILURE);
6811 }
6812 
6813 #ifdef DEBUG
6814 static void
6815 debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
6816     uintptr_t a4, uintptr_t a5)
6817 {
6818 	if (pcicfg_debug == 1) {
6819 		prom_printf("pcicfg: ");
6820 		prom_printf(fmt, a1, a2, a3, a4, a5);
6821 	} else
6822 		if (pcicfg_debug)
6823 			cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5);
6824 }
6825 #endif
6826 
6827 /*
6828  * Return true if the devinfo node is in a PCI Express hierarchy.
6829  */
6830 static boolean_t
6831 is_pcie_fabric(dev_info_t *dip)
6832 {
6833 	dev_info_t *root = ddi_root_node();
6834 	dev_info_t *pdip;
6835 	boolean_t found = B_FALSE;
6836 	char *bus;
6837 
6838 	/*
6839 	 * Does this device reside in a pcie fabric ?
6840 	 */
6841 	for (pdip = dip; pdip && (pdip != root) && !found;
6842 	    pdip = ddi_get_parent(pdip)) {
6843 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
6844 		    DDI_PROP_DONTPASS, "device_type", &bus) !=
6845 		    DDI_PROP_SUCCESS)
6846 			break;
6847 
6848 		if (strcmp(bus, "pciex") == 0)
6849 			found = B_TRUE;
6850 
6851 		ddi_prop_free(bus);
6852 	}
6853 
6854 	return (found);
6855 }
6856