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