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