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