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