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