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