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