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