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 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright (c)  * Copyright (c) 2001 Tadpole Technology plc
  27  * All rights reserved.
  28  * From "@(#)pcicfg.c   1.31    99/06/18 SMI"
  29  */
  30 
  31 #pragma ident   "%Z%%M% %I%     %E% SMI"
  32 
  33 /*
  34  * Cardbus configurator
  35  */
  36 
  37 #include <sys/ddi.h>
  38 #include <sys/sunndi.h>
  39 #include <sys/ndi_impldefs.h>
  40 
  41 #include <sys/pci.h>
  42 #include <sys/ebus.h>
  43 #include <sys/hotplug/hpctrl.h>
  44 #include <sys/hotplug/pci/pcicfg.h>
  45 
  46 #include <sys/pctypes.h>
  47 #include <sys/pcmcia.h>
  48 #include <sys/sservice.h>
  49 
  50 #include <sys/isa_defs.h>
  51 
  52 #include <sys/note.h>
  53 
  54 #include <sys/ethernet.h>
  55 
  56 #include "cardbus.h"
  57 #include "cardbus_parse.h"
  58 #include "cardbus_cfg.h"
  59 
  60 /*
  61  * ************************************************************************
  62  * *** Implementation specific local data structures/definitions.       ***
  63  * ************************************************************************
  64  */
  65 
  66 #define PCICFG_MAX_DEVICE 32
  67 #define PCICFG_MAX_FUNCTION 8
  68 
  69 static uint32_t pcicfg_max_device = PCICFG_MAX_DEVICE;
  70 static uint32_t pcicfg_max_function = PCICFG_MAX_FUNCTION;
  71 
  72 #define PCICFG_NODEVICE 42
  73 #define PCICFG_NOMEMORY 43
  74 #define PCICFG_NOMULTI  44
  75 
  76 #define PCICFG_HIADDR(n) ((uint32_t)(((uint64_t)(n) & 0xFFFFFFFF00000000)>> 32))
  77 #define PCICFG_LOADDR(n) ((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
  78 #define PCICFG_LADDR(lo, hi)    (((uint64_t)(hi) << 32) | (uint32_t)(lo))
  79 
  80 #define PCICFG_HIWORD(n) ((uint16_t)(((uint32_t)(n) & 0xFFFF0000)>> 16))
  81 #define PCICFG_LOWORD(n) ((uint16_t)((uint32_t)(n) & 0x0000FFFF))
  82 #define PCICFG_HIBYTE(n) ((uint8_t)(((uint16_t)(n) & 0xFF00)>> 8))
  83 #define PCICFG_LOBYTE(n) ((uint8_t)((uint16_t)(n) & 0x00FF))
  84 
  85 #define PCICFG_ROUND_UP(addr, gran) ((uintptr_t)((gran+addr-1)&(~(gran-1))))
  86 #define PCICFG_ROUND_DOWN(addr, gran) ((uintptr_t)((addr) & ~(gran-1)))
  87 
  88 #define PCICFG_MEMGRAN 0x100000
  89 #define PCICFG_IOGRAN 0x1000
  90 #define PCICFG_4GIG_LIMIT 0xFFFFFFFFUL
  91 #define CBCFG_MEMGRAN 0x1000
  92 #define CBCFG_IOGRAN 0x4
  93 
  94 #define PCICFG_MEM_MULT 4
  95 #define PCICFG_IO_MULT 4
  96 #define PCICFG_RANGE_LEN 2 /* Number of range entries */
  97 
  98 /*
  99  * ISA node declaration structure.
 100  */
 101 struct isa_node {
 102         char    *name;
 103         char    *compatible[5];
 104         char    *type;
 105         char    *model;
 106         uint16_t        reg;
 107         uint16_t        span;
 108 };
 109 
 110 struct cardbus_name_entry {
 111         uint32_t class_code;
 112         char  *name;
 113         int pil;
 114 };
 115 
 116 struct cardbus_find_ctrl {
 117         uint_t          bus;
 118         uint_t          device;
 119         uint_t          function;
 120         dev_info_t      *dip;
 121 };
 122 
 123 #define PCICFG_MAKE_REG_HIGH(busnum, devnum, funcnum, register)\
 124         (\
 125         ((ulong_t)(busnum & 0xff) << 16)    |\
 126         ((ulong_t)(devnum & 0x1f) << 11)    |\
 127         ((ulong_t)(funcnum & 0x7) <<  8)    |\
 128         ((ulong_t)(register & 0x3f)))
 129 
 130 typedef struct cardbus_phdl cardbus_phdl_t;
 131 
 132 struct cardbus_phdl {
 133 
 134         dev_info_t      *dip;   /* Associated with the attach point */
 135         dev_info_t      *res_dip; /* dip from which io/mem is allocated */
 136         cardbus_phdl_t  *next;
 137 
 138         uint64_t        memory_base;    /* Memory base for this attach point */
 139         uint64_t        memory_last;
 140         uint64_t        memory_len;
 141         uint32_t        memory_gran;
 142         uint32_t        io_base;        /* I/O base for this attach point */
 143         uint32_t        io_last;
 144         uint32_t        io_len;
 145         uint32_t        io_gran;
 146 
 147         int     error;
 148         uint_t  highest_bus;    /* Highest bus seen on the probe */
 149         ndi_ra_request_t mem_req;       /* allocator request for memory */
 150         ndi_ra_request_t io_req;        /* allocator request for I/O */
 151 };
 152 
 153 typedef struct {
 154         dev_info_t  *dip;       /* Associated with the attach point */
 155         ddi_acc_handle_t handle;    /* open handle on parent PCI config space */
 156         uint32_t    io_base;    /* I/O base for this attach point */
 157         int     io_decode_reg;
 158 } isa_phdl_t;
 159 
 160 
 161 /*
 162  * forward declarations for routines defined in this module (called here)
 163  */
 164 static cardbus_phdl_t *cardbus_find_phdl(dev_info_t *dip);
 165 static cardbus_phdl_t *cardbus_create_phdl(dev_info_t *dip);
 166 static int cardbus_destroy_phdl(dev_info_t *dip);
 167 static int cardbus_program_ap(dev_info_t *);
 168 static void cardbus_topbridge_assign(dev_info_t *, cardbus_phdl_t *);
 169 static int cardbus_bridge_ranges(dev_info_t *, cardbus_phdl_t *,
 170                         ddi_acc_handle_t);
 171 static int cardbus_bridge_assign(dev_info_t *, void *);
 172 static int cardbus_isa_bridge_ranges(dev_info_t *dip, cardbus_phdl_t *entry,
 173                         ddi_acc_handle_t handle);
 174 static int cardbus_add_isa_reg(dev_info_t *, void *);
 175 static int cardbus_allocate_chunk(dev_info_t *, uint8_t, uint8_t);
 176 static int cardbus_free_chunk(dev_info_t *);
 177 static void cardbus_setup_bridge(dev_info_t *, cardbus_phdl_t *,
 178                         ddi_acc_handle_t);
 179 static void cardbus_update_bridge(dev_info_t *, cardbus_phdl_t *,
 180                         ddi_acc_handle_t);
 181 static void cardbus_get_mem(dev_info_t *, cardbus_phdl_t *, uint32_t,
 182                         uint64_t *);
 183 static void cardbus_get_io(dev_info_t *, cardbus_phdl_t *, uint32_t,
 184                         uint32_t *);
 185 static int cardbus_sum_resources(dev_info_t *, void *);
 186 static int cardbus_free_bridge_resources(dev_info_t *);
 187 static int cardbus_free_device_resources(dev_info_t *);
 188 static int cardbus_free_resources(dev_info_t *);
 189 static int cardbus_probe_bridge(cbus_t *, dev_info_t *, uint_t,
 190                         uint_t, uint_t);
 191 static int cardbus_probe_children(cbus_t *, dev_info_t *, uint_t, uint_t,
 192                         uint_t, uint8_t *);
 193 static int cardbus_add_config_reg(dev_info_t *, uint_t, uint_t, uint_t);
 194 static int cardbus_add_isa_node(cbus_t *, dev_info_t *, struct isa_node *);
 195 static int cardbus_config_setup(dev_info_t *, ddi_acc_handle_t *);
 196 static void cardbus_config_teardown(ddi_acc_handle_t *);
 197 static void cardbus_reparent_children(dev_info_t *, dev_info_t *);
 198 static int cardbus_update_assigned_prop(dev_info_t *, pci_regspec_t *);
 199 static int cardbus_update_available_prop(dev_info_t *, uint32_t,
 200                         uint64_t, uint64_t);
 201 static int cardbus_update_ranges_prop(dev_info_t *, cardbus_range_t *);
 202 static int cardbus_update_reg_prop(dev_info_t *dip, uint32_t regvalue,
 203                         uint_t reg_offset);
 204 static int cardbus_set_standard_props(dev_info_t *parent, dev_info_t *dip,
 205                         ddi_acc_handle_t config_handle);
 206 static int cardbus_set_isa_props(dev_info_t *parent, dev_info_t *dip,
 207                         char *name, char *compat[]);
 208 static int cardbus_set_busnode_props(dev_info_t *);
 209 static int cardbus_set_busnode_isaprops(dev_info_t *);
 210 static int cardbus_set_childnode_props(dev_info_t *dip,
 211                         ddi_acc_handle_t config_handle);
 212 static void cardbus_set_bus_numbers(ddi_acc_handle_t config_handle,
 213                         uint_t primary, uint_t secondary);
 214 static void enable_pci_isa_bridge(dev_info_t *dip,
 215                         ddi_acc_handle_t config_handle);
 216 static void enable_pci_pci_bridge(dev_info_t *dip,
 217                         ddi_acc_handle_t config_handle);
 218 static void enable_cardbus_bridge(dev_info_t *dip,
 219                         ddi_acc_handle_t config_handle);
 220 static void disable_pci_pci_bridge(dev_info_t *dip,
 221                         ddi_acc_handle_t config_handle);
 222 static void disable_cardbus_bridge(dev_info_t *dip,
 223                         ddi_acc_handle_t config_handle);
 224 static void enable_cardbus_device(dev_info_t *, ddi_acc_handle_t);
 225 static void disable_cardbus_device(ddi_acc_handle_t config_handle);
 226 static void cardbus_force_boolprop(dev_info_t *dip, char *pname);
 227 static void cardbus_force_intprop(dev_info_t *dip, char *pname,
 228                         int *pval, int len);
 229 static void cardbus_force_stringprop(dev_info_t *dip, char *pname,
 230                         char *pval);
 231 static void split_addr(char *, int *, int *);
 232 #ifdef DEBUG
 233 static void cardbus_dump_common_config(ddi_acc_handle_t config_handle);
 234 static void cardbus_dump_device_config(ddi_acc_handle_t config_handle);
 235 static void cardbus_dump_bridge_config(ddi_acc_handle_t config_handle,
 236                         uint8_t header_type);
 237 static void cardbus_dump_config(ddi_acc_handle_t config_handle);
 238 static void cardbus_dump_reg(dev_info_t *dip, const pci_regspec_t *regspec,
 239                         int nelems);
 240 #endif
 241 
 242 static cardbus_phdl_t *cardbus_phdl_list = NULL;
 243 
 244 static struct cardbus_name_entry cardbus_class_lookup [] = {
 245         { 0x001, "display", 9 },
 246         { 0x100, "scsi", 4 },
 247         { 0x101, "ide", 4 },
 248         { 0x102, "fdc", 4 },
 249         { 0x103, "ipi", 4 },
 250         { 0x104, "raid", 4 },
 251         { 0x200, "ethernet", 6 },
 252         { 0x201, "token-ring", 6 },
 253         { 0x202, "fddi", 6 },
 254         { 0x203, "atm", 6 },
 255         { 0x300, "display", 9 },    /* VGA card */
 256         { 0x380, "display", 9 },    /* other - for the Raptor Card */
 257         { 0x400, "video", 11 },
 258         { 0x401, "sound", 11 },
 259         { 0x500, "memory", 11 },
 260         { 0x501, "flash", 11 },
 261         { 0x600, "host", 11 },
 262         { 0x601, "isa", 11 },
 263         { 0x602, "eisa", 11 },
 264         { 0x603, "mca", 11 },
 265         { 0x604, "pci", 11 },
 266         { 0x605, "pcmcia", 11 },
 267         { 0x606, "nubus", 11 },
 268         { 0x607, "cardbus", 11 },
 269         { 0x680, NULL, 8 },
 270         { 0x700, "serial", 11 },
 271         { 0x701, "parallel", 6 },
 272         { 0x800, "interrupt-controller", 3 },
 273         { 0x801, "dma-controller", 3 },
 274         { 0x802, "timer", 3 },
 275         { 0x803, "rtc", 3 },
 276         { 0x900, "keyboard", 8 },
 277         { 0x901, "pen", 8 },
 278         { 0x902, "mouse", 8 },
 279         { 0xa00, "dock", 1 },
 280         { 0xb00, "cpu", 1 },
 281         { 0xc00, "firewire", 9 },
 282         { 0xc01, "access-bus", 4 },
 283         { 0xc02, "ssa", 4 },
 284         { 0xc03, "usb", 9 },
 285         { 0xc04, "fibre-channel", 6 },
 286         { 0, 0 }
 287 };
 288 
 289 #ifndef _DONT_USE_1275_GENERIC_NAMES
 290 static char *cardbus_get_class_name(uint32_t classcode);
 291 #endif /* _DONT_USE_1275_GENERIC_NAMES */
 292 
 293 /*
 294  * Reprogram ILINE with default value only if BIOS doesn't program it
 295  */
 296 int
 297 cardbus_validate_iline(dev_info_t *dip, ddi_acc_handle_t handle)
 298 {
 299         uint8_t intline = 0xff;
 300 
 301         if (pci_config_get8(handle, PCI_CONF_IPIN)) {
 302         intline = pci_config_get8(handle, PCI_CONF_ILINE);
 303         if ((intline == 0) || (intline == 0xff)) {
 304                 intline = ddi_getprop(DDI_DEV_T_ANY, dip,
 305                         DDI_PROP_CANSLEEP|DDI_PROP_DONTPASS,
 306                         "interrupt-line", 0xff);
 307                 if (intline == (uint8_t)0xff) {
 308                         intline = ddi_getprop(DDI_DEV_T_ANY,
 309                                 ddi_get_parent(dip),
 310                                 DDI_PROP_CANSLEEP /* |DDI_PROP_DONTPASS */,
 311                                 "interrupt-line", 0xb);
 312                 }
 313 
 314                 pci_config_put8(handle, PCI_CONF_ILINE, intline);
 315         }
 316         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
 317                 "interrupt-line", intline);
 318         }
 319         return (intline);
 320 }
 321 
 322 /*
 323  * This entry point is called to configure a device (and
 324  * all its children) on the given bus. It is called when
 325  * a new device is added to the PCI domain.  This routine
 326  * will create the device tree and program the devices
 327  * registers.
 328  */
 329 int
 330 cardbus_configure(cbus_t *cbp)
 331 {
 332         uint_t bus;
 333         int cardbus_dev, func;
 334         dev_info_t *attach_point;
 335 
 336         cardbus_err(cbp->cb_dip, 6, "cardbus_configure ()\n");
 337 
 338         bus = cardbus_primary_busno(cbp->cb_dip);
 339 
 340         if (ndi_devi_alloc(cbp->cb_dip, DEVI_PSEUDO_NEXNAME,
 341             (pnode_t)DEVI_SID_NODEID,
 342             &attach_point) != NDI_SUCCESS) {
 343                 cardbus_err(cbp->cb_dip, 1,
 344                     "cardbus_configure(): Failed to alloc probe node\n");
 345                 return (PCICFG_FAILURE);
 346         }
 347 
 348         /*
 349          * Node name marks this node as the "attachment point".
 350          */
 351         if (ndi_devi_set_nodename(attach_point,
 352             "hp_attachment", 0) != NDI_SUCCESS) {
 353             cardbus_err(cbp->cb_dip, 1,
 354                     "Failed to set nodename for attachment node\n");
 355                 (void) ndi_devi_free(attach_point);
 356                 return (PCICFG_FAILURE);
 357         }
 358 
 359         cardbus_err(ddi_get_parent(attach_point), 8,
 360             "Set bus type to cardbus\n");
 361         (void) ddi_prop_update_string(DDI_DEV_T_NONE,
 362             ddi_get_parent(attach_point), PCM_DEVICETYPE,
 363             "cardbus");
 364 
 365         split_addr(ddi_get_name_addr(cbp->cb_dip), &cardbus_dev, &func);
 366 
 367         cardbus_err(attach_point, 8,
 368             "Configuring [0x%x][0x%x][0x%x]\n", bus, cardbus_dev, func);
 369 
 370         switch (cardbus_probe_bridge(cbp, attach_point,
 371             bus, cardbus_dev, func)) {
 372         case PCICFG_FAILURE:
 373                 cardbus_err(cbp->cb_dip, 4,
 374                     "configure failed: bus [0x%x] slot [0x%x] func [0x%x]\n",
 375                     bus, cardbus_dev, func);
 376                 goto cleanup;
 377         case PCICFG_NODEVICE:
 378                 cardbus_err(cbp->cb_dip, 4,
 379                     "no device: bus [0x%x] slot [0x%x] func [0x%x]\n",
 380                     bus, cardbus_dev, func);
 381                 goto cleanup;
 382         default:
 383                 cardbus_err(cbp->cb_dip, 9,
 384                     "configure: bus => [%d] slot => [%d] func => [%d]\n",
 385                     bus, cardbus_dev, func);
 386                 break;
 387         }
 388 
 389         if (cardbus_program_ap(cbp->cb_dip) == PCICFG_SUCCESS) {
 390                 (void) cardbus_reparent_children(attach_point, cbp->cb_dip);
 391                 (void) ndi_devi_free(attach_point);
 392                 cbp->cb_nex_ops->enable_intr(cbp->cb_dip);
 393                 return (PCICFG_SUCCESS);
 394         }
 395 
 396         cardbus_err(cbp->cb_dip, 1, "Failed to program devices\n");
 397 
 398 cleanup:
 399         /*
 400          * Clean up a partially created "probe state" tree.
 401          * There are no resources allocated to the in the
 402          * probe state.
 403          */
 404 
 405         cardbus_err(cbp->cb_dip, 6,
 406             "Look up device [0x%x] function [0x%x] to clean up\n",
 407             cardbus_dev, func);
 408 
 409         cardbus_err(cbp->cb_dip, 6,
 410             "Cleaning up device [0x%x] function [0x%x]\n",
 411             cardbus_dev, func);
 412 
 413         /*
 414          * If this was a bridge device it will have a
 415          * probe handle - if not, no harm in calling this.
 416          */
 417         (void) cardbus_destroy_phdl(cbp->cb_dip);
 418 
 419         if (ddi_get_child(attach_point)) {
 420                 /*
 421                  * This will free up the node
 422                  */
 423                 (void) ndi_devi_offline(ddi_get_child(attach_point),
 424                     NDI_UNCONFIG|NDI_DEVI_REMOVE);
 425         }
 426         (void) ndi_devi_free(attach_point);
 427 
 428         return (PCICFG_FAILURE);
 429 }
 430 
 431 int
 432 cardbus_unconfigure(cbus_t *cbp)
 433 {
 434         ddi_acc_handle_t config_handle;
 435         dev_info_t *dip = cbp->cb_dip;
 436 
 437         cbp->cb_nex_ops->disable_intr(dip);
 438         if (pci_config_setup(dip, &config_handle) == DDI_SUCCESS) {
 439                 disable_cardbus_bridge(dip, config_handle);
 440                 (void) pci_config_teardown(&config_handle);
 441         } else {
 442                 cardbus_err(dip, 1,
 443                     "cardbus_unconfigure(): Failed to setup config space\n");
 444         }
 445 
 446         (void) cardbus_free_chunk(dip);
 447         cardbus_err(dip, 6,
 448             "cardbus_unconfigure: calling cardbus_free_bridge_resources\n");
 449         (void) cardbus_free_bridge_resources(dip);
 450 
 451         return (PCICFG_SUCCESS);
 452 }
 453 
 454 int
 455 cardbus_teardown_device(dev_info_t *dip)
 456 {
 457         /*
 458          * Free up resources associated with 'dip'
 459          */
 460 
 461         if (cardbus_free_resources(dip) != PCICFG_SUCCESS) {
 462                 cardbus_err(dip, 1,
 463                     "cardbus_teardown_device: Failed to free resources\n");
 464                 return (PCICFG_FAILURE);
 465         }
 466 
 467         if (ndi_devi_offline(dip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
 468                 cardbus_err(dip, 1,
 469                     "cardbus_teardown_device: "
 470                     "Failed to offline and remove node\n");
 471                 return (PCICFG_FAILURE);
 472         }
 473 
 474         return (PCICFG_SUCCESS);
 475 }
 476 
 477 /*
 478  * Get the primary pci bus number. This should be the lowest number
 479  * in the bus-range property of our parent.
 480  */
 481 int
 482 cardbus_primary_busno(dev_info_t *dip)
 483 {
 484         int     len, rval;
 485         char    bus_type[16] = "(unknown)";
 486         dev_info_t *par = ddi_get_parent(dip);
 487         cardbus_bus_range_t *bus_range;
 488 
 489         ASSERT(strcmp(ddi_driver_name(dip), "pcic") == 0);
 490         len = sizeof (bus_type);
 491         if ((ddi_prop_op(DDI_DEV_T_ANY, par, PROP_LEN_AND_VAL_BUF,
 492             DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
 493             "device_type",
 494             (caddr_t)&bus_type, &len) == DDI_SUCCESS)) {
 495                 ASSERT((strcmp(bus_type, "pci") == 0) ||
 496                     (strcmp(bus_type, "cardbus") == 0));
 497                 if (ddi_getlongprop(DDI_DEV_T_ANY, par, 0, "bus-range",
 498                     (caddr_t)&bus_range, &len) == DDI_PROP_SUCCESS) {
 499                         cardbus_err(dip, 9,
 500                             "cardbus_primary_busno: bus range is %d to %d\n",
 501                             bus_range->lo, bus_range->hi);
 502                         rval = (int)bus_range->lo;
 503                         kmem_free((caddr_t)bus_range, len);
 504                         return (rval);
 505                 }
 506         }
 507 
 508         cardbus_err(dip, 2,
 509             "cardbus_primary_busno: Not a pci device or no bus-range\n");
 510         return (-1);
 511 }
 512 
 513 static cardbus_phdl_t *
 514 cardbus_find_phdl(dev_info_t *dip)
 515 {
 516         cardbus_phdl_t *entry;
 517 
 518         mutex_enter(&cardbus_list_mutex);
 519         for (entry = cardbus_phdl_list; entry != NULL; entry = entry->next) {
 520                 if (entry->dip == dip) {
 521                         mutex_exit(&cardbus_list_mutex);
 522                         return (entry);
 523                 }
 524         }
 525         mutex_exit(&cardbus_list_mutex);
 526 
 527         /*
 528          * Did'nt find entry - create one
 529          */
 530         return (cardbus_create_phdl(dip));
 531 }
 532 
 533 static cardbus_phdl_t *
 534 cardbus_create_phdl(dev_info_t *dip)
 535 {
 536         cardbus_phdl_t *new;
 537 
 538         new = (cardbus_phdl_t *)kmem_zalloc(sizeof (cardbus_phdl_t), KM_SLEEP);
 539 
 540         new->dip = dip;
 541         new->io_gran = CBCFG_IOGRAN;
 542         new->memory_gran = CBCFG_MEMGRAN;
 543         mutex_enter(&cardbus_list_mutex);
 544         new->next = cardbus_phdl_list;
 545         cardbus_phdl_list = new;
 546         mutex_exit(&cardbus_list_mutex);
 547 
 548         return (new);
 549 }
 550 
 551 static int
 552 cardbus_destroy_phdl(dev_info_t *dip)
 553 {
 554         cardbus_phdl_t *entry;
 555         cardbus_phdl_t *follow = NULL;
 556         ra_return_t     res;
 557 
 558         mutex_enter(&cardbus_list_mutex);
 559         for (entry = cardbus_phdl_list; entry != NULL; follow = entry,
 560             entry = entry->next) {
 561                 if (entry->dip == dip) {
 562                         if (entry == cardbus_phdl_list) {
 563                                 cardbus_phdl_list = entry->next;
 564                         } else {
 565                                 follow->next = entry->next;
 566                         }
 567                         /*
 568                          * If this entry has any allocated memory
 569                          * or IO space associated with it, that
 570                          * must be freed up.
 571                          */
 572                         if (entry->memory_len > 0) {
 573                                 res.ra_addr_lo = entry->memory_base;
 574                                 res.ra_len = entry->memory_len;
 575                                 (void) pcmcia_free_mem(entry->res_dip, &res);
 576 #ifdef  _LP64
 577                                 cardbus_err(dip, 8,
 578                                     "cardbus_destroy_phdl: "
 579                                     "MEMORY BASE = [0x%lx] length [0x%lx]\n",
 580                                     entry->memory_base, entry->memory_len);
 581 #else
 582                                 cardbus_err(dip, 8,
 583                                     "cardbus_destroy_phdl: "
 584                                     "MEMORY BASE = [0x%llx] length [0x%llx]\n",
 585                                     entry->memory_base, entry->memory_len);
 586 #endif
 587                         }
 588                         if (entry->io_len > 0) {
 589                                 res.ra_addr_lo = entry->io_base;
 590                                 res.ra_len = entry->io_len;
 591                                 (void) pcmcia_free_io(entry->res_dip, &res);
 592                                 cardbus_err(dip, 8,
 593                                     "cardbus_destroy_phdl: "
 594                                     "IO BASE = [0x%x] length [0x%x]\n",
 595                                     entry->io_base, entry->io_len);
 596                         }
 597                         /*
 598                          * Destroy this entry
 599                          */
 600                         kmem_free((caddr_t)entry, sizeof (cardbus_phdl_t));
 601                         mutex_exit(&cardbus_list_mutex);
 602                         return (PCICFG_SUCCESS);
 603                 }
 604         }
 605 
 606         mutex_exit(&cardbus_list_mutex);
 607 
 608         /*
 609          * Didn't find the entry
 610          */
 611         return (PCICFG_FAILURE);
 612 }
 613 
 614 static int
 615 cardbus_program_ap(dev_info_t *dip)
 616 {
 617         cardbus_phdl_t *phdl;
 618         uint8_t header_type, sec_bus;
 619         ddi_acc_handle_t handle;
 620 
 621         if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
 622                 cardbus_err(dip, 1,
 623                     "cardbus_program_ap: Failed to map config space!\n");
 624                 return (PCICFG_FAILURE);
 625         }
 626 
 627         header_type = pci_config_get8(handle, PCI_CONF_HEADER);
 628         sec_bus = pci_config_get8(handle, PCI_BCNF_SECBUS);
 629 
 630         cardbus_err(dip, 6,
 631             "cardbus_program_ap (header_type=0x%x)\n", header_type);
 632         (void) pci_config_teardown(&handle);
 633 
 634         /*
 635          * Header type two is PCI to Cardbus bridge, see page 43 of the
 636          * CL-PD6832 data sheet
 637          */
 638         switch (header_type & PCI_HEADER_TYPE_M) {
 639         case PCI_HEADER_CARDBUS:
 640                 cardbus_err(dip, 8,
 641                     "cardbus_program_ap calling cardbus_allocate_chunk\n");
 642                 if (cardbus_allocate_chunk(dip,
 643                     header_type & PCI_HEADER_TYPE_M,
 644                     sec_bus) != PCICFG_SUCCESS) {
 645                         cardbus_err(dip, 1,
 646                             "cardbus_program_ap: "
 647                             "Not enough memory to hotplug\n");
 648                         (void) cardbus_destroy_phdl(dip);
 649                         return (PCICFG_FAILURE);
 650                 }
 651 
 652                 cardbus_err(dip, 8,
 653                     "cardbus_program_ap calling cardbus_find_phdl\n");
 654                 phdl = cardbus_find_phdl(dip);
 655                 ASSERT(phdl);
 656 
 657                 if (phdl == NULL) {
 658                         cardbus_err(dip, 1, "cardbus_find_phdl failed\n");
 659                         return (PCICFG_FAILURE);
 660                 }
 661                 phdl->error = PCICFG_SUCCESS;
 662                 cardbus_err(dip, 8,
 663                     "cardbus_program_ap calling cardbus_topbridge_assign\n");
 664                 cardbus_topbridge_assign(dip, phdl);
 665 
 666                 if (phdl->error != PCICFG_SUCCESS) {
 667                         cardbus_err(dip, 1, "Problem assigning bridge\n");
 668                         (void) cardbus_destroy_phdl(dip);
 669                         return (phdl->error);
 670                 }
 671                 break;
 672 
 673         default:
 674                 return (PCICFG_FAILURE);
 675         }
 676 
 677         return (PCICFG_SUCCESS);
 678 }
 679 
 680 static void
 681 cardbus_topbridge_assign(dev_info_t *dip, cardbus_phdl_t *entry)
 682 {
 683         ddi_acc_handle_t handle;
 684         uint8_t header_type;
 685 
 686         cardbus_err(dip, 6, "cardbus_topbridge_assign\n");
 687 
 688         if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
 689                 cardbus_err(dip, 1,
 690                     "cardbus_topbridge_bridge_assign: "
 691                     "Failed to map config space!\n");
 692                 return;
 693         }
 694 
 695         header_type = pci_config_get8(handle,
 696             PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
 697 
 698         /* cardbus bridge is the same as PCI-PCI bridge */
 699         ASSERT((header_type == PCI_HEADER_PPB) ||
 700             (header_type == PCI_HEADER_CARDBUS));
 701 
 702         (void) cardbus_bridge_ranges(dip, entry, handle);
 703 
 704         (void) pci_config_teardown(&handle);
 705 }
 706 
 707 static int
 708 cardbus_bridge_ranges(dev_info_t *dip, cardbus_phdl_t *entry,
 709                         ddi_acc_handle_t handle)
 710 {
 711         cardbus_range_t range[PCICFG_RANGE_LEN];
 712         int bus_range[2];
 713         int count;
 714         int i;
 715 
 716         cardbus_err(dip, 8, "cardbus_bridge_ranges\n");
 717 
 718         bzero((caddr_t)range, sizeof (cardbus_range_t) * PCICFG_RANGE_LEN);
 719 
 720         (void) cardbus_setup_bridge(dip, entry, handle);
 721 
 722         range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
 723         range[0].child_lo = range[0].parent_lo = entry->io_last;
 724         range[1].child_hi = range[1].parent_hi |= (PCI_REG_REL_M |
 725                                                 PCI_ADDR_MEM32);
 726         range[1].child_lo = range[1].parent_lo = entry->memory_last;
 727 
 728         ndi_devi_enter(dip, &count);
 729         ddi_walk_devs(ddi_get_child(dip), cardbus_bridge_assign, (void *)entry);
 730         ndi_devi_exit(dip, count);
 731 
 732         (void) cardbus_update_bridge(dip, entry, handle);
 733 
 734         bus_range[0] = pci_config_get8(handle, PCI_BCNF_SECBUS);
 735         bus_range[1] = pci_config_get8(handle, PCI_BCNF_SUBBUS);
 736 
 737         cardbus_err(dip, 8,
 738             "Set up bus-range property to %u->%u\n",
 739             bus_range[0], bus_range[1]);
 740 
 741         if ((i = ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
 742             "bus-range",
 743             bus_range, 2)) != DDI_SUCCESS) {
 744 
 745                 if (i == DDI_PROP_NOT_FOUND) {
 746                         cardbus_err(dip, 8,
 747                             "Create bus-range property, %u->%u\n",
 748                             bus_range[0], bus_range[1]);
 749                         i = ddi_prop_create(DDI_DEV_T_NONE, dip,
 750                             DDI_PROP_CANSLEEP,
 751                             "bus-range", (caddr_t)bus_range,
 752                             sizeof (bus_range));
 753                 }
 754 
 755                 if (i != DDI_PROP_SUCCESS) {
 756                         cardbus_err(dip, 1,
 757                             "Failed to set bus-range property, %u->%u (%d)\n",
 758                             bus_range[0], bus_range[1], i);
 759                         entry->error = PCICFG_FAILURE;
 760                         return (DDI_WALK_TERMINATE);
 761                 }
 762         }
 763 
 764         if (entry->io_len > 0) {
 765                 range[0].size_lo = entry->io_last - entry->io_base;
 766                 if (cardbus_update_ranges_prop(dip, &range[0])) {
 767                         cardbus_err(dip, 1, "Failed to update ranges (i/o)\n");
 768                         entry->error = PCICFG_FAILURE;
 769                         return (DDI_WALK_TERMINATE);
 770                 }
 771         }
 772         if (entry->memory_len > 0) {
 773                 range[1].size_lo = entry->memory_last - entry->memory_base;
 774                 if (cardbus_update_ranges_prop(dip, &range[1])) {
 775                         cardbus_err(dip, 1,
 776                             "Failed to update ranges (memory)\n");
 777                         entry->error = PCICFG_FAILURE;
 778                         return (DDI_WALK_TERMINATE);
 779                 }
 780         }
 781 
 782         return (DDI_WALK_PRUNECHILD);
 783 }
 784 static int
 785 cardbus_bridge_assign(dev_info_t *dip, void *hdl)
 786 {
 787         ddi_acc_handle_t handle;
 788         pci_regspec_t *reg;
 789         int length;
 790         int rcount;
 791         int i;
 792         int offset;
 793         uint64_t mem_answer;
 794         uint32_t io_answer, request;
 795         uint8_t header_type, base_class;
 796         cardbus_phdl_t *entry = (cardbus_phdl_t *)hdl;
 797 
 798         /*
 799          * Ignore the attachment point and pcs.
 800          */
 801         if (strcmp(ddi_binding_name(dip), "hp_attachment") == 0 ||
 802             strcmp(ddi_binding_name(dip), "pcs") == 0) {
 803                 cardbus_err(dip, 8, "cardbus_bridge_assign: Ignoring\n");
 804                 return (DDI_WALK_CONTINUE);
 805         }
 806 
 807 
 808         cardbus_err(dip, 6, "cardbus_bridge_assign\n");
 809 
 810         if (entry == NULL) {
 811                 cardbus_err(dip, 1, "Failed to get entry\n");
 812                 return (DDI_WALK_TERMINATE);
 813         }
 814         if (cardbus_config_setup(dip, &handle) != DDI_SUCCESS) {
 815                 cardbus_err(dip, 1,
 816                     "cardbus_bridge_assign: Failed to map config space!\n");
 817                 entry->error = PCICFG_FAILURE;
 818                 return (DDI_WALK_TERMINATE);
 819         }
 820 
 821         header_type = pci_config_get8(handle, PCI_CONF_HEADER) &
 822                 PCI_HEADER_TYPE_M;
 823         base_class = pci_config_get8(handle, PCI_CONF_BASCLASS);
 824 
 825         /*
 826          * This function is not called for the top bridge and we are
 827          * not enumerating down a further cardbus interface yet!
 828          */
 829         if (base_class == PCI_CLASS_BRIDGE) {
 830                 uint8_t sub_class;
 831 
 832                 sub_class = pci_config_get8(handle, PCI_CONF_SUBCLASS);
 833 
 834                 switch (sub_class) {
 835                 case PCI_BRIDGE_PCI:
 836                         if (header_type == PCI_HEADER_PPB) {
 837                                 i = cardbus_bridge_ranges(dip, entry, handle);
 838                                 (void) cardbus_config_teardown(&handle);
 839                                 return (i);
 840                         }
 841                         goto bad_device;
 842 
 843                 case PCI_BRIDGE_ISA:
 844                         i = cardbus_isa_bridge_ranges(dip, entry, handle);
 845                         (void) cardbus_config_teardown(&handle);
 846                         return (i);
 847 
 848                 case PCI_BRIDGE_CARDBUS:
 849                         /*
 850                          * Fall through, there should be at least one register
 851                          * set for this.
 852                          */
 853                         break;
 854 
 855                 case PCI_BRIDGE_OTHER:
 856                 default:
 857                         break;
 858                 }
 859         }
 860 
 861 #ifdef sparc
 862         /*
 863          * If there is an interrupt pin set program
 864          * interrupt line with default values.
 865          */
 866         if (pci_config_get8(handle, PCI_CONF_IPIN)) {
 867             pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
 868         }
 869 #else
 870         (void) cardbus_validate_iline(dip, handle);
 871 #endif
 872 
 873         /*
 874          * A single device (under a bridge).
 875          * For each "reg" property with a length, allocate memory
 876          * and program the base registers.
 877          */
 878         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
 879             DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
 880             &length) != DDI_PROP_SUCCESS) {
 881                 cardbus_err(dip, 1, "Failed to read reg property\n");
 882                 entry->error = PCICFG_FAILURE;
 883                 (void) cardbus_config_teardown(&handle);
 884                 return (DDI_WALK_TERMINATE);
 885         }
 886 
 887         rcount = length / sizeof (pci_regspec_t);
 888         cardbus_err(dip, 9, "rcount = %d\n", rcount);
 889 
 890         for (i = 0; i < rcount; i++) {
 891                 if ((reg[i].pci_size_low != 0) || (reg[i].pci_size_hi != 0)) {
 892                         offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
 893                         switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
 894                         case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
 895 
 896                                 (void) cardbus_get_mem(ddi_get_parent(dip),
 897                                     entry, reg[i].pci_size_low, &mem_answer);
 898                                 ASSERT(!PCICFG_HIADDR(mem_answer));
 899                                 pci_config_put32(handle, offset,
 900                                     PCICFG_LOADDR(mem_answer));
 901                                 pci_config_put32(handle, offset + 4,
 902                                     PCICFG_HIADDR(mem_answer));
 903                                 cardbus_err(dip, 8,
 904                                     "REGISTER (64)LO [0x%x] ----> [0x%02x]\n",
 905                                     pci_config_get32(handle, offset), offset);
 906                                 cardbus_err(dip, 8,
 907                                     "REGISTER (64)HI [0x%x] ----> [0x%02x]\n",
 908                                     pci_config_get32(handle, offset+4),
 909                                         offset+4);
 910                                 reg[i].pci_phys_low = PCICFG_HIADDR(mem_answer);
 911                                 reg[i].pci_phys_mid = PCICFG_LOADDR(mem_answer);
 912                                 break;
 913 
 914                         case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
 915                                 /* allocate memory space from the allocator */
 916 
 917                                 (void) cardbus_get_mem(ddi_get_parent(dip),
 918                                     entry, reg[i].pci_size_low, &mem_answer);
 919                                 pci_config_put32(handle, offset, 0xffffffff);
 920                                 request = pci_config_get32(handle, offset);
 921 
 922                                 pci_config_put32(handle, offset,
 923                                     (uint32_t)mem_answer);
 924                                 reg[i].pci_phys_low = (uint32_t)mem_answer;
 925                                 reg[i].pci_phys_mid = 0;
 926                                 if (((PCI_BASE_TYPE_M & request) ==
 927                                         PCI_BASE_TYPE_ALL) &&
 928                                     ((PCI_BASE_SPACE_M & request) ==
 929                                         PCI_BASE_SPACE_MEM)) {
 930                                         cardbus_err(dip, 8,
 931                                             "REGISTER (64)LO [0x%x] ----> "
 932                                             "[0x%02x]\n",
 933                                             pci_config_get32(handle, offset),
 934                                                 offset);
 935                                             pci_config_put32(handle,
 936                                                 offset + 4, 0);
 937                                         cardbus_err(dip, 8,
 938                                             "REGISTER (64)HI [0x%x] ----> "
 939                                             "[0x%02x]\n",
 940                                             pci_config_get32(handle, offset+4),
 941                                                 offset+4);
 942                                 } else {
 943                                         cardbus_err(dip, 8,
 944                                             "REGISTER (32)LO [0x%x] ----> "
 945                                             "[0x%02x]\n",
 946                                             pci_config_get32(handle, offset),
 947                                             offset);
 948                                 }
 949                                 break;
 950 
 951                         case PCI_REG_ADDR_G(PCI_ADDR_IO):
 952                                 /* allocate I/O space from the allocator */
 953 
 954                                 (void) cardbus_get_io(ddi_get_parent(dip),
 955                                     entry, reg[i].pci_size_low, &io_answer);
 956                                 pci_config_put32(handle, offset, io_answer);
 957                                 cardbus_err(dip, 8,
 958                                     "REGISTER (I/O)LO [0x%x] ----> [0x%02x]\n",
 959                                     pci_config_get32(handle, offset), offset);
 960                                 reg[i].pci_phys_low = io_answer;
 961                                 break;
 962 
 963                         default:
 964                                 cardbus_err(dip, 1, "Unknown register type\n");
 965                                 kmem_free(reg, length);
 966                                 (void) cardbus_config_teardown(&handle);
 967                                 entry->error = PCICFG_FAILURE;
 968                                 return (DDI_WALK_TERMINATE);
 969                         } /* switch */
 970 
 971                         /*
 972                          * Now that memory locations are assigned,
 973                          * update the assigned address property.
 974                          */
 975                         if (cardbus_update_assigned_prop(dip,
 976                             &reg[i]) != PCICFG_SUCCESS) {
 977                                 kmem_free(reg, length);
 978                                 (void) cardbus_config_teardown(&handle);
 979                                 entry->error = PCICFG_FAILURE;
 980                                 return (DDI_WALK_TERMINATE);
 981                         }
 982                 }
 983         }
 984         kmem_free(reg, length);
 985         enable_cardbus_device(dip, handle);
 986 #ifdef CARDBUS_DEBUG
 987         if (cardbus_debug >= 9) {
 988                 cardbus_dump_config(handle);
 989         }
 990 #endif
 991 bad_device:
 992         (void) cardbus_config_teardown(&handle);
 993         return (DDI_WALK_CONTINUE);
 994 }
 995 
 996 static int
 997 cardbus_isa_bridge_ranges(dev_info_t *dip, cardbus_phdl_t *entry,
 998                         ddi_acc_handle_t handle)
 999 {
1000         struct ebus_pci_rangespec range;
1001         int count;
1002         pci_regspec_t *reg;
1003         int length;
1004         int rcount;
1005         uint32_t io_answer = 0xffffffff;
1006         isa_phdl_t isa_phdl;
1007         int i;
1008 
1009         cardbus_err(dip, 8, "cardbus_isa_bridge_ranges\n");
1010 
1011         bzero((caddr_t)&range, sizeof (range));
1012 
1013 #ifdef sparc
1014         /*
1015          * If there is an interrupt pin set program
1016          * interrupt line with default values.
1017          */
1018         if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1019             pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1020         }
1021 #else
1022         (void) cardbus_validate_iline(dip, handle);
1023 #endif
1024 
1025         /*
1026          * For each "reg" property with a length, allocate memory.
1027          */
1028         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1029             DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
1030             &length) != DDI_PROP_SUCCESS) {
1031                 cardbus_err(dip, 1, "Failed to read reg property\n");
1032                 entry->error = PCICFG_FAILURE;
1033                 return (DDI_WALK_TERMINATE);
1034         }
1035 
1036         rcount = length / sizeof (pci_regspec_t);
1037 
1038         for (i = 0; i < rcount; i++) {
1039                 if ((reg[i].pci_size_low != 0) || (reg[i].pci_size_hi != 0)) {
1040                         switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
1041                         case PCI_REG_ADDR_G(PCI_ADDR_IO):
1042                                 /* allocate I/O space from the allocator */
1043 
1044                                 (void) cardbus_get_io(ddi_get_parent(dip),
1045                                     entry, reg[i].pci_size_low, &io_answer);
1046                                 cardbus_err(dip, 8,
1047                                     "ISA (I/O)LO ----> [0x%x]\n", io_answer);
1048                                 reg[i].pci_phys_low = io_answer;
1049                                 range.phys_hi = 0;
1050                                 range.phys_low = io_answer;
1051                                 range.par_phys_hi = reg[i].pci_phys_hi |
1052                                                 PCI_REG_REL_M;
1053                                 range.par_phys_low = reg[i].pci_phys_low;
1054                                 range.par_phys_mid = reg[i].pci_phys_mid;
1055                                 range.rng_size = reg[i].pci_size_low;
1056                                 i = rcount;
1057                                 break;
1058 
1059                         default:
1060                                 cardbus_err(dip, 1, "Unknown register type\n");
1061                                 kmem_free(reg, length);
1062                                 (void) cardbus_config_teardown(&handle);
1063                                 entry->error = PCICFG_FAILURE;
1064                                 return (DDI_WALK_TERMINATE);
1065                         } /* switch */
1066                 }
1067         }
1068         kmem_free(reg, length);
1069 
1070         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
1071             dip, "ranges", (int *)&range,
1072             sizeof (range)/sizeof (int));
1073         if (io_answer != 0xffffffff) {
1074                 isa_phdl.dip = dip;
1075                 isa_phdl.handle = handle;
1076                 isa_phdl.io_base = io_answer;
1077                 isa_phdl.io_decode_reg = 0x58; /* Pos decoded IO space 0 reg */
1078                 /* i_ndi_block_device_tree_changes(&count); */
1079                 ndi_devi_enter(dip, &count);
1080                 ddi_walk_devs(ddi_get_child(dip),
1081                         cardbus_add_isa_reg, (void *)&isa_phdl);
1082                 /* i_ndi_allow_device_tree_changes(count); */
1083                 ndi_devi_exit(dip, count);
1084         }
1085         return (DDI_WALK_PRUNECHILD);
1086 }
1087 
1088 /*
1089  * This is specific to ITE8888 chip.
1090  */
1091 static int
1092 cardbus_add_isa_reg(dev_info_t *dip, void *arg)
1093 {
1094         uint32_t        io_reg = 0;
1095         int             length;
1096         uint32_t        reg[3], *breg;
1097         isa_phdl_t      *phdl;
1098         uint8_t         sz;
1099 
1100         phdl = (isa_phdl_t *)arg;
1101         cardbus_err(dip, 6,
1102             "cardbus_add_isa_reg, base 0x%x\n", phdl->io_base);
1103 
1104         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1105             DDI_PROP_DONTPASS, "basereg", (caddr_t)&breg,
1106             &length) != DDI_PROP_SUCCESS) {
1107                 return (DDI_WALK_CONTINUE);
1108         }
1109 
1110         if ((length / sizeof (reg)) < 1) {
1111                 kmem_free(breg, length);
1112                 return (DDI_WALK_CONTINUE);
1113         }
1114 
1115         /*
1116          * Add the "reg" property.
1117          */
1118         reg[0] = 0;
1119         reg[1] = breg[1] + phdl->io_base;
1120         reg[2] = breg[2];
1121 
1122         /*
1123          * Generate the postive IO decode register setting.
1124          */
1125         for (sz = 0; sz < 8; sz++)
1126                 if ((1<<sz) >= breg[2]) {
1127                         io_reg = breg[1]
1128                             | (1uL <<31) /* Enable */
1129                             | (2uL <<29) /* Medium speed */
1130                             | (1uL <<28) /* Aliase enable, */
1131                                         /* Don't care A[15:10] */
1132                             | (sz<<24); /* Size code */
1133                         break;
1134                 }
1135 
1136         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1137             "reg", (int *)reg, 3);
1138         (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "basereg");
1139 
1140         if (io_reg) {
1141                 pci_config_put32(phdl->handle, phdl->io_decode_reg, io_reg);
1142                 cardbus_err(dip, 6,
1143                     "cardbus_add_isa_reg: I/O decode reg (0x%x) set to 0x%x\n",
1144                     phdl->io_decode_reg,
1145                     pci_config_get32(phdl->handle, phdl->io_decode_reg));
1146                 phdl->io_decode_reg += sizeof (io_reg);
1147         } else
1148                 cardbus_err(dip, 1,
1149                     "cardbus_add_isa_reg: register size (0x%x) too large\n",
1150                     breg[2]);
1151         kmem_free(breg, length);
1152         return (DDI_WALK_CONTINUE);
1153 }
1154 
1155 /*
1156  * In case we want to ensure that some space is allocated to the
1157  * device tree below the cardbus bridge.
1158  * This is only necessary if there is a device that needs to allocate
1159  * resource below us. This can happen if there is another cardbus/PCMCIA
1160  * bridge downstream.
1161  */
1162 static uint32_t cardbus_min_spare_mem = 0;
1163 static uint32_t cardbus_min_spare_io = 0;
1164 
1165 /*
1166  * The "dip" passed to this routine is assumed to be
1167  * the device at the attachment point. Currently it is
1168  * assumed to be a bridge.
1169  */
1170 static int
1171 cardbus_allocate_chunk(dev_info_t *dip, uint8_t type, uint8_t sec_bus)
1172 {
1173         cardbus_phdl_t          *phdl;
1174         ndi_ra_request_t        *mem_request;
1175         ndi_ra_request_t        *io_request;
1176         ra_return_t             res;
1177         int                     count;
1178 
1179         /*
1180          * This should not find an existing entry - so
1181          * it will create a new one.
1182          */
1183         phdl = cardbus_find_phdl(dip);
1184         ASSERT(phdl);
1185 
1186         mem_request = &phdl->mem_req;
1187         io_request  = &phdl->io_req;
1188 
1189         /*
1190          * Set highest_bus here.
1191          * Otherwise if we don't find another bridge
1192          * this never gets set.
1193          */
1194         phdl->highest_bus = sec_bus;
1195 
1196         /*
1197          * From this point in the tree - walk the devices,
1198          * The function passed in will read and "sum" up
1199          * the memory and I/O requirements and put them in
1200          * structure "phdl".
1201          */
1202         phdl->error = PCICFG_SUCCESS;
1203         ndi_devi_enter(dip, &count);
1204         ddi_walk_devs(ddi_get_child(dip), cardbus_sum_resources, (void *)phdl);
1205         ndi_devi_exit(dip, count);
1206 
1207         if (phdl->error != PCICFG_SUCCESS) {
1208                 cmn_err(CE_WARN, "Failure summing resources\n");
1209                 return (phdl->error);
1210         }
1211 
1212         /*
1213          * Call into the memory allocator with the request.
1214          * Record the addresses returned in the phdl
1215          */
1216 #ifdef  _LP64
1217         cardbus_err(dip, 8,
1218             "AP requires [0x%lx] bytes of memory space, alligned 0x%x\n",
1219             mem_request->ra_len, phdl->memory_gran);
1220         cardbus_err(dip, 8,
1221             "AP requires [0x%lx] bytes of I/O space, alligned 0x%x\n",
1222             io_request->ra_len, phdl->io_gran);
1223 #else
1224         cardbus_err(dip, 8,
1225             "AP requires [0x%llx] bytes of memory space, alligned 0x%x\n",
1226             mem_request->ra_len, phdl->memory_gran);
1227         cardbus_err(dip, 8,
1228             "AP requires [0x%llx] bytes of I/O space, alligned 0x%x\n",
1229             io_request->ra_len, phdl->io_gran);
1230 #endif
1231 
1232         ASSERT(type == PCI_HEADER_CARDBUS);
1233 
1234         mem_request->ra_align_mask = phdl->memory_gran - 1;
1235         io_request->ra_align_mask = phdl->io_gran - 1;
1236         phdl->res_dip = (dev_info_t *)-1;
1237 
1238         mem_request->ra_len += cardbus_min_spare_mem;
1239         if (mem_request->ra_len) {
1240                 mem_request->ra_len = PCICFG_ROUND_UP(
1241                                         mem_request->ra_len,
1242                                         phdl->memory_gran);
1243 #ifdef _LP64
1244                 cardbus_err(dip, 8,
1245                     "cardbus_allocate_chunk: ndi_ra_alloc 0x%lx bytes\n",
1246                     mem_request->ra_len);
1247 #else
1248                 cardbus_err(dip, 8,
1249                     "cardbus_allocate_chunk: ndi_ra_alloc 0x%llx bytes\n",
1250                     mem_request->ra_len);
1251 #endif
1252 
1253                 if (pcmcia_alloc_mem(dip, mem_request, &res,
1254                     &phdl->res_dip) != NDI_SUCCESS) {
1255                         cmn_err(CE_WARN, "Failed to allocate memory for %s\n",
1256                                 ddi_driver_name(dip));
1257                         return (PCICFG_FAILURE);
1258                 }
1259 
1260                 phdl->memory_base = phdl->memory_last = res.ra_addr_lo;
1261                 phdl->memory_len = res.ra_len;
1262         }
1263 
1264         io_request->ra_len += cardbus_min_spare_io;
1265         if (io_request->ra_len) {
1266 
1267 #if defined(__x86) || defined(__amd64)
1268                 io_request->ra_boundbase = 0x1000;
1269                 io_request->ra_boundlen = 0xefff;
1270 #else
1271                 io_request->ra_boundbase = 0;
1272                 io_request->ra_boundlen = PCICFG_4GIG_LIMIT;
1273 #endif
1274                 io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1275                 io_request->ra_len = PCICFG_ROUND_UP(io_request->ra_len,
1276                                 phdl->io_gran);
1277                 io_request->ra_align_mask = max(PCICFG_IOGRAN,
1278                                 phdl->io_gran) - 1;
1279 
1280                 if (pcmcia_alloc_io(dip, io_request, &res,
1281                     &phdl->res_dip) != NDI_SUCCESS) {
1282                         cmn_err(CE_WARN, "Failed to allocate I/O space "
1283                                 "for %s\n", ddi_driver_name(dip));
1284                         if (mem_request->ra_len) {
1285                                 res.ra_addr_lo = phdl->memory_base;
1286                                 res.ra_len = phdl->memory_len;
1287                                 (void) pcmcia_free_mem(phdl->res_dip, &res);
1288                                 phdl->memory_len = phdl->io_len = 0;
1289                         }
1290                         return (PCICFG_FAILURE);
1291                 }
1292 
1293                 phdl->io_base = phdl->io_last = (uint32_t)res.ra_addr_lo;
1294                 phdl->io_len  = (uint32_t)res.ra_len;
1295         }
1296 
1297 #ifdef  _LP64
1298         cardbus_err(dip, 6,
1299             "MEMORY BASE = [0x%lx] length [0x%lx]\n",
1300             phdl->memory_base, phdl->memory_len);
1301 #else
1302         cardbus_err(dip, 6,
1303             "MEMORY BASE = [0x%llx] length [0x%llx]\n",
1304             phdl->memory_base, phdl->memory_len);
1305 #endif
1306         cardbus_err(dip, 6,
1307             "IO BASE = [0x%x] length [0x%x]\n",
1308             phdl->io_base, phdl->io_len);
1309 
1310         return (PCICFG_SUCCESS);
1311 }
1312 
1313 static int
1314 cardbus_free_chunk(dev_info_t *dip)
1315 {
1316         uint_t  *bus;
1317         int     k;
1318 
1319         cardbus_err(dip, 6, "cardbus_free_chunk\n");
1320 
1321         (void) cardbus_destroy_phdl(dip);
1322 
1323         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1324             DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
1325             &k) != DDI_PROP_SUCCESS) {
1326                 cardbus_err(dip, 1,
1327                     "cardbus_free_chunk: Failed to read bus-range property\n");
1328                 return (PCICFG_FAILURE);
1329         }
1330 
1331         cardbus_err(dip, 6,
1332             "cardbus_free_chunk: Freeing bus [%d] range [%d]\n",
1333             bus[0], bus[1] - bus[0] + 1);
1334 
1335         if (ndi_ra_free(dip,
1336             (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
1337             NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1338                 cardbus_err(dip, 1,
1339                     "cardbus_free_chunk: Failed to free bus numbers\n");
1340 
1341                 kmem_free(bus, k);
1342                 return (PCICFG_FAILURE);
1343         }
1344 
1345         kmem_free(bus, k);
1346         return (PCICFG_SUCCESS);
1347 }
1348 
1349 /*
1350  * Put bridge registers into initial state
1351  */
1352 static void
1353 cardbus_setup_bridge(dev_info_t *dip, cardbus_phdl_t *entry,
1354                 ddi_acc_handle_t handle)
1355 {
1356         uint8_t header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1357 
1358 #ifdef _LP64
1359         cardbus_err(NULL, 6,
1360             "cardbus_setup_bridge: "
1361             "highest bus %d, mem_last 0x%lx, io_last 0x%x\n",
1362             entry->highest_bus, entry->memory_last, entry->io_last);
1363 #else
1364         cardbus_err(NULL, 6,
1365             "cardbus_setup_bridge: "
1366             "highest bus %d, mem_last 0x%llx, io_last 0x%x\n",
1367             entry->highest_bus, entry->memory_last, entry->io_last);
1368 #endif
1369 
1370         if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1371                 uint32_t uval;
1372 
1373                 /*
1374                  * The highest bus seen during probing is
1375                  * the max-subordinate bus
1376                  */
1377                 pci_config_put8(handle, PCI_BCNF_SUBBUS, entry->highest_bus);
1378 
1379                 uval = PCICFG_ROUND_UP(entry->memory_last, PCICFG_MEMGRAN);
1380                 if (uval != entry->memory_last) {
1381 #ifdef _LP64
1382                         cardbus_err(dip, 8,
1383                             "Adding [0x%lx] before bridge (mem)\n",
1384                             uval - entry->memory_last);
1385 #else
1386                         cardbus_err(dip, 8,
1387                             "Adding [0x%llx] before bridge (mem)\n",
1388                             uval - entry->memory_last);
1389 #endif
1390                         (void) cardbus_get_mem(ddi_get_parent(dip), entry,
1391                             uval - entry->memory_last, NULL);
1392                 }
1393 
1394                 /*
1395                  * Program the memory base register with the
1396                  * start of the memory range
1397                  */
1398 #ifdef _LP64
1399                 cardbus_err(NULL, 8,
1400                     "store 0x%x(0x%lx) in pci bridge memory base register\n",
1401                     PCICFG_HIWORD(PCICFG_LOADDR(uval)),
1402                     entry->memory_last);
1403 #else
1404                 cardbus_err(NULL, 8,
1405                     "store 0x%x(0x%llx) in pci bridge memory base register\n",
1406                     PCICFG_HIWORD(PCICFG_LOADDR(uval)),
1407                     entry->memory_last);
1408 #endif
1409                 pci_config_put16(handle, PCI_BCNF_MEM_BASE,
1410                     PCICFG_HIWORD(PCICFG_LOADDR(uval)));
1411 
1412                 uval = PCICFG_ROUND_UP(entry->io_last, PCICFG_IOGRAN);
1413                 if (uval != entry->io_last) {
1414                         cardbus_err(dip, 8,
1415                             "Adding [0x%x] before bridge (I/O)\n",
1416                             uval - entry->io_last);
1417                         (void) cardbus_get_io(ddi_get_parent(dip), entry,
1418                             uval - entry->io_last, NULL);
1419                 }
1420                 cardbus_err(NULL, 8,
1421                     "store 0x%02x/0x%04x(0x%x) in "
1422                     "pci bridge I/O hi/low base register\n",
1423                     PCICFG_HIWORD(PCICFG_LOADDR(uval)),
1424                     PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(uval))),
1425                     entry->io_last);
1426                 /*
1427                  * Program the I/O base register with the start of the I/O range
1428                  */
1429                 pci_config_put8(handle, PCI_BCNF_IO_BASE_LOW,
1430                     PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(uval))));
1431 
1432                 pci_config_put16(handle, PCI_BCNF_IO_BASE_HI,
1433                     PCICFG_HIWORD(PCICFG_LOADDR(uval)));
1434 
1435                 /*
1436                  * Clear status bits
1437                  */
1438                 pci_config_put16(handle, PCI_BCNF_SEC_STATUS, 0xffff);
1439 
1440                 /*
1441                  * Turn off prefetchable range
1442                  */
1443                 pci_config_put32(handle, PCI_BCNF_PF_BASE_LOW, 0x0000ffff);
1444                 pci_config_put32(handle, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
1445 
1446                 pci_config_put32(handle, PCI_BCNF_PF_LIMIT_HIGH, 0x0);
1447 
1448 #ifdef sparc
1449                 /*
1450                  * If there is an interrupt pin set program
1451                  * interrupt line with default values.
1452                  */
1453                 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1454                     pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1455                 }
1456 #else
1457                 (void) cardbus_validate_iline(dip, handle);
1458 #endif
1459 
1460 
1461         } else if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_CARDBUS) {
1462 
1463                 /*
1464                  * The highest bus seen during probing is
1465                  * the max-subordinate bus
1466                  */
1467                 pci_config_put8(handle, PCI_CBUS_SUB_BUS_NO,
1468                     entry->highest_bus);
1469 
1470                 /*
1471                  * Program the memory base register with the
1472                  * start of the memory range
1473                  */
1474 #ifdef _LP64
1475                 cardbus_err(NULL, 8,
1476                     "store 0x%x(0x%lx) in "
1477                     "cardbus memory base register 0, len 0x%lx\n",
1478                     PCICFG_LOADDR(entry->memory_last), entry->memory_last,
1479                     entry->memory_len);
1480 #else
1481                 cardbus_err(NULL, 8,
1482                     "store 0x%x(0x%llx) in "
1483                     "cardbus memory base register 0, len 0x%llx\n",
1484                     PCICFG_LOADDR(entry->memory_last), entry->memory_last,
1485                     entry->memory_len);
1486 #endif
1487 
1488                 pci_config_put32(handle, PCI_CBUS_MEM_BASE0,
1489                     PCICFG_LOADDR(entry->memory_last));
1490 
1491                 /*
1492                  * Program the I/O base register with the start of the I/O range
1493                  */
1494                 cardbus_err(NULL, 8,
1495                     "store 0x%x in cb IO base register 0 len 0x%x\n",
1496                     PCICFG_LOADDR(entry->io_last),
1497                     entry->io_len);
1498 
1499                 pci_config_put32(handle, PCI_CBUS_IO_BASE0,
1500                     PCICFG_LOADDR(entry->io_last));
1501 
1502                 /*
1503                  * Clear status bits
1504                  */
1505                 pci_config_put16(handle, PCI_CBUS_SEC_STATUS, 0xffff);
1506 
1507 #ifdef sparc
1508                 /*
1509                  * If there is an interrupt pin set program
1510                  * interrupt line with default values.
1511                  */
1512                 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1513                     pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1514                 }
1515 #else
1516                 (void) cardbus_validate_iline(dip, handle);
1517 #endif
1518 
1519 
1520                 /*
1521                  * LATER: use these registers
1522                  */
1523                 pci_config_put32(handle, PCI_CBUS_MEM_BASE1, 0);
1524                 pci_config_put32(handle, PCI_CBUS_MEM_LIMIT1, 0);
1525                 pci_config_put32(handle, PCI_CBUS_IO_BASE1, 0);
1526                 pci_config_put32(handle, PCI_CBUS_IO_LIMIT1, 0);
1527         } else {
1528                 cmn_err(CE_WARN, "header type 0x%x, probably unknown bridge\n",
1529                     header_type & PCI_HEADER_TYPE_M);
1530         }
1531 
1532         cardbus_err(NULL, 7, "cardbus_setup_bridge complete\n");
1533 }
1534 
1535 static void
1536 cardbus_update_bridge(dev_info_t *dip, cardbus_phdl_t *entry,
1537                 ddi_acc_handle_t handle)
1538 {
1539         uint_t length;
1540         uint16_t word16 = pci_config_get16(handle, PCI_CONF_COMM);
1541         const   uint8_t header_type = pci_config_get8(handle, PCI_CONF_HEADER)
1542                         & PCI_HEADER_TYPE_M;
1543         uint32_t bridge_gran;
1544         uint64_t rlval;
1545 
1546         if (header_type == PCI_HEADER_CARDBUS)
1547                 bridge_gran = CBCFG_MEMGRAN;
1548         else
1549                 bridge_gran = PCICFG_MEMGRAN;
1550 
1551         /*
1552          * Program the memory limit register with the end of the memory range
1553          */
1554 #ifdef _LP64
1555         cardbus_err(dip, 6,
1556             "cardbus_update_bridge: Mem base 0x%lx len 0x%lx "
1557             "last 0x%lx gran 0x%x gran end 0x%lx\n",
1558             entry->memory_base, entry->memory_len,
1559             entry->memory_last, entry->memory_gran,
1560             PCICFG_ROUND_UP(entry->memory_last, entry->memory_gran));
1561 #else
1562         cardbus_err(dip, 6,
1563             "cardbus_update_bridge: Mem base 0x%llx len 0x%llx "
1564             "last 0x%llx gran 0x%x gran end 0x%lx\n",
1565             entry->memory_base, entry->memory_len,
1566             entry->memory_last, entry->memory_gran,
1567             PCICFG_ROUND_UP(entry->memory_last, entry->memory_gran));
1568 #endif
1569         /*
1570          * Since this is a bridge, the rest of this range will
1571          * be responded to by the bridge.  We have to round up
1572          * so no other device claims it.
1573          */
1574         length = PCICFG_ROUND_UP(entry->memory_last + cardbus_min_spare_mem,
1575             bridge_gran) - entry->memory_last;
1576 
1577         if (length > 0) {
1578                 /*
1579                  * This is to allow space that isn't actually being used by
1580                  * anything to be allocated by devices such as a downstream
1581                  * PCMCIA controller.
1582                  */
1583                 (void) cardbus_get_mem(dip, entry, length, NULL);
1584                 cardbus_err(dip, 8,
1585                     "Added [0x%x] at the top of the bridge (mem)\n", length);
1586         }
1587 
1588         if (entry->memory_len) {
1589                 if (header_type == PCI_HEADER_CARDBUS) {
1590                         rlval = PCICFG_ROUND_DOWN(entry->memory_last - 1,
1591                             CBCFG_MEMGRAN);
1592 #ifdef _LP64
1593                         cardbus_err(dip, 8,
1594                             "store 0x%x(0x%lx) in memory limit register 0\n",
1595                             PCICFG_LOADDR(rlval), rlval);
1596 #else
1597                         cardbus_err(dip, 8,
1598                             "store 0x%x(0x%llx) in memory limit register 0\n",
1599                             PCICFG_LOADDR(rlval), rlval);
1600 #endif
1601                         pci_config_put32(handle, PCI_CBUS_MEM_LIMIT0,
1602                             PCICFG_LOADDR(rlval));
1603                 } else {
1604                         rlval = PCICFG_ROUND_DOWN(entry->memory_last - 1,
1605                             PCICFG_MEMGRAN);
1606 #ifdef _LP64
1607                         cardbus_err(dip, 8,
1608                             "store 0x%x(0x%lx) in memory limit register\n",
1609                             PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1610                             rlval);
1611 #else
1612                         cardbus_err(dip, 8,
1613                             "store 0x%x(0x%llx) in memory limit register\n",
1614                             PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1615                             rlval);
1616 #endif
1617                         pci_config_put16(handle, PCI_BCNF_MEM_LIMIT,
1618                             PCICFG_HIWORD(PCICFG_LOADDR(rlval)));
1619                 }
1620                 word16 |= PCI_COMM_MAE;
1621         }
1622 
1623         cardbus_err(dip, 6,
1624             "cardbus_update_bridge: I/O base 0x%x len 0x%x last 0x%x "
1625             "gran 0x%x gran_end 0x%lx\n",
1626             entry->io_base, entry->io_len, entry->io_last, entry->io_gran,
1627             PCICFG_ROUND_UP(entry->io_last, entry->io_gran));
1628 
1629         if (header_type == PCI_HEADER_CARDBUS)
1630                 bridge_gran = CBCFG_IOGRAN;
1631         else
1632                 bridge_gran = PCICFG_IOGRAN;
1633 
1634         /*
1635          * Same as above for I/O space. Since this is a
1636          * bridge, the rest of this range will be responded
1637          * to by the bridge.  We have to round up so no
1638          * other device claims it.
1639          */
1640         length = PCICFG_ROUND_UP(entry->io_last + cardbus_min_spare_io,
1641             bridge_gran) - entry->io_last;
1642         if (length > 0) {
1643                 (void) cardbus_get_io(dip, entry, length, NULL);
1644                 cardbus_err(dip, 8,
1645                     "Added [0x%x] at the top of the bridge (I/O)\n",  length);
1646         }
1647 
1648         /*
1649          * Program the I/O limit register with the end of the I/O range
1650          */
1651         if (entry->io_len) {
1652                 if (header_type == PCI_HEADER_CARDBUS) {
1653                         rlval = PCICFG_ROUND_DOWN(entry->io_last - 1,
1654                             CBCFG_IOGRAN);
1655 #ifdef _LP64
1656                         cardbus_err(dip, 8,
1657                             "store 0x%lx in IO limit register 0\n", rlval);
1658 #else
1659                         cardbus_err(dip, 8,
1660                             "store 0x%llx in IO limit register 0\n", rlval);
1661 #endif
1662                         pci_config_put32(handle, PCI_CBUS_IO_LIMIT0, rlval);
1663                 } else {
1664                         rlval = PCICFG_ROUND_DOWN(entry->io_last - 1,
1665                             PCICFG_IOGRAN);
1666 #ifdef _LP64
1667                         cardbus_err(dip, 8,
1668                             "store 0x%x/0x%x(0x%lx) in "
1669                             "IO limit low/hi register\n",
1670                             PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(rlval))),
1671                             PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1672                             rlval);
1673 #else
1674                         cardbus_err(dip, 8,
1675                             "store 0x%x/0x%x(0x%llx) in "
1676                             "IO limit low/hi register\n",
1677                             PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(rlval))),
1678                             PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1679                             rlval);
1680 #endif
1681 
1682                         pci_config_put8(handle, PCI_BCNF_IO_LIMIT_LOW,
1683                             PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(rlval))));
1684                         pci_config_put16(handle, PCI_BCNF_IO_LIMIT_HI,
1685                             PCICFG_HIWORD(PCICFG_LOADDR(rlval)));
1686                 }
1687                 word16 |= PCI_COMM_IO;
1688         }
1689 
1690         pci_config_put16(handle, PCI_CONF_COMM, word16);
1691 }
1692 
1693 static void
1694 cardbus_get_mem(dev_info_t *dip, cardbus_phdl_t *entry,
1695                 uint32_t length, uint64_t *ans)
1696 {
1697         uint32_t hole;
1698 
1699 #ifdef  _LP64
1700         cardbus_err(NULL, 6,
1701             "cardbus_get_mem: memory_last 0x%lx, length 0x%x, "
1702             "memory_base 0x%lx, memory_len 0x%lx ans=0x%p\n",
1703             entry->memory_last, length,
1704             entry->memory_base, entry->memory_len, (void *) ans);
1705 #else
1706         cardbus_err(NULL, 6,
1707             "cardbus_get_mem: memory_last 0x%llx, length 0x%x, "
1708             "memory_base 0x%llx, memory_len 0x%llx ans=0x%p\n",
1709             entry->memory_last, length,
1710             entry->memory_base, entry->memory_len, (void *) ans);
1711 #endif
1712 
1713         if (ans) {
1714                 /*
1715                  * Round up the request to the "size" boundary
1716                  */
1717                 hole = PCICFG_ROUND_UP(entry->memory_last, length)
1718                         - entry->memory_last;
1719                 if (hole != 0) {
1720                         (void) cardbus_update_available_prop(dip,
1721                             PCI_ADDR_MEM32,
1722                             entry->memory_last,
1723                             (uint64_t)hole);
1724                         entry->memory_last += hole;
1725 
1726 #ifdef  _LP64
1727                         cardbus_err(NULL, 6,
1728                             "cardbus_get_mem: "
1729                             "rounded memory_last up by 0x%x to 0x%lx, ",
1730                             hole, entry->memory_last);
1731 #else
1732                         cardbus_err(NULL, 6,
1733                             "cardbus_get_mem: "
1734                             "rounded memory_last up by 0x%x to 0x%llx, ",
1735                             hole, entry->memory_last);
1736 #endif
1737                 }
1738         } else
1739                 (void) cardbus_update_available_prop(dip, PCI_ADDR_MEM32,
1740                         entry->memory_last,
1741                         (uint64_t)length);
1742 
1743         /*
1744          * These routines should parcel out the memory
1745          * completely.  There should never be a case of
1746          * over running the bounds.
1747          */
1748         if ((entry->memory_last + length) >
1749             (entry->memory_base + entry->memory_len))
1750 #ifdef  _LP64
1751                 cardbus_err(NULL, 1,
1752                     "cardbus_get_mem: assert will fail %ld <= %ld,"
1753                     "(0x%lx + 0x%x) <= (0x%lx + 0x%lx)\n",
1754 #else
1755                 cardbus_err(NULL, 1,
1756                     "cardbus_get_mem: assert will fail %lld <= %lld, "
1757                     "(0x%llx + 0x%x) <= (0x%llx + 0x%llx)\n",
1758 #endif
1759                     entry->memory_last + length,
1760                     entry->memory_base + entry->memory_len,
1761                     entry->memory_last,
1762                     length,
1763                     entry->memory_base,
1764                     entry->memory_len);
1765 
1766         ASSERT((entry->memory_last + length) <=
1767         (entry->memory_base + entry->memory_len));
1768         /*
1769          * If ans is NULL don't return anything,
1770          * they are just asking to reserve the memory.
1771          */
1772         if (ans != NULL)
1773                 *ans = entry->memory_last;
1774 
1775         /*
1776          * Increment to the next location
1777          */
1778         entry->memory_last += length;
1779 }
1780 
1781 static void
1782 cardbus_get_io(dev_info_t *dip, cardbus_phdl_t *entry,
1783                 uint32_t length, uint32_t *ans)
1784 {
1785         uint32_t        hole;
1786 
1787         cardbus_err(NULL, 6,
1788             "cardbus_get_io: io_last 0x%x, length 0x%x, "
1789             "io_base 0x%x, io_len 0x%x ans=0x%p\n",
1790             entry->io_last, length,
1791             entry->io_base, entry->io_len, (void *) ans);
1792 
1793         if (ans) {
1794                 /*
1795                  * Round up the request to the "size" boundary
1796                  */
1797                 hole = PCICFG_ROUND_UP(entry->io_last, length) - entry->io_last;
1798                 if (hole != 0) {
1799                         (void) cardbus_update_available_prop(dip, PCI_ADDR_IO,
1800                             (uint64_t)entry->io_last,
1801                             (uint64_t)hole);
1802                         entry->io_last += hole;
1803 
1804                         cardbus_err(NULL, 6,
1805                             "cardbus_get_io: "
1806                             "rounded io_last up by 0x%x to 0x%x, ",
1807                             hole, entry->io_last);
1808                 }
1809         } else
1810                 (void) cardbus_update_available_prop(dip, PCI_ADDR_IO,
1811                     (uint64_t)entry->io_last,
1812                     (uint64_t)length);
1813         /*
1814          * These routines should parcel out the memory
1815          * completely.  There should never be a case of
1816          * over running the bounds.
1817          */
1818         ASSERT((entry->io_last + length) <=
1819             (entry->io_base + entry->io_len));
1820 
1821         /*
1822          * If ans is NULL don't return anything,
1823          * they are just asking to reserve the memory.
1824          */
1825         if (ans != NULL)
1826                 *ans = entry->io_last;
1827 
1828         /*
1829          * Increment to the next location
1830          */
1831         entry->io_last += length;
1832 }
1833 
1834 static int
1835 cardbus_sum_resources(dev_info_t *dip, void *hdl)
1836 {
1837         cardbus_phdl_t *entry = (cardbus_phdl_t *)hdl;
1838         pci_regspec_t *pci_rp;
1839         int length;
1840         int rcount;
1841         int i, ret;
1842         ndi_ra_request_t *mem_request;
1843         ndi_ra_request_t *io_request;
1844         uint8_t header_type, base_class;
1845         ddi_acc_handle_t handle;
1846 
1847         /*
1848          * Ignore the attachment point and pcs.
1849          */
1850         if (strcmp(ddi_binding_name(dip), "hp_attachment") == 0 ||
1851             strcmp(ddi_binding_name(dip), "pcs") == 0) {
1852                 cardbus_err(dip, 8, "cardbus_sum_resources: Ignoring\n");
1853                 return (DDI_WALK_CONTINUE);
1854         }
1855 
1856         mem_request = &entry->mem_req;
1857         io_request =  &entry->io_req;
1858 
1859         if (cardbus_config_setup(dip, &handle) != DDI_SUCCESS) {
1860                 cardbus_err(dip, 1,
1861                     "cardbus_sum_resources: Failed to map config space!\n");
1862                 entry->error = PCICFG_FAILURE;
1863                 return (DDI_WALK_TERMINATE);
1864         }
1865 
1866         ret = DDI_WALK_CONTINUE;
1867         header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1868         base_class = pci_config_get8(handle, PCI_CONF_BASCLASS);
1869 
1870         /*
1871          * If its a bridge - just record the highest bus seen
1872          */
1873         if (base_class == PCI_CLASS_BRIDGE) {
1874                 uint8_t sub_class;
1875 
1876                 sub_class = pci_config_get8(handle, PCI_CONF_SUBCLASS);
1877 
1878                 switch (sub_class) {
1879                 case PCI_BRIDGE_PCI:
1880                         if ((header_type & PCI_HEADER_TYPE_M)
1881                             == PCI_HEADER_PPB) {
1882 
1883                                 if (entry->highest_bus < pci_config_get8(handle,
1884                                     PCI_BCNF_SECBUS)) {
1885                                         entry->highest_bus = pci_config_get8(
1886                                             handle, PCI_BCNF_SECBUS);
1887                                 }
1888 
1889                                 (void) cardbus_config_teardown(&handle);
1890 #if defined(CARDBUS_DEBUG)
1891                                 if (mem_request->ra_len !=
1892                                     PCICFG_ROUND_UP(mem_request->ra_len,
1893                                     PCICFG_MEMGRAN)) {
1894 
1895 #ifdef _LP64
1896                                         cardbus_err(dip, 8,
1897                                             "Pre-align [0x%lx] to PCI bridge "
1898                                             "memory gran "
1899                                             "[0x%lx] -> [0x%lx]\n",
1900                                             PCICFG_ROUND_UP(mem_request->ra_len,
1901                                                 PCICFG_MEMGRAN) -
1902                                                 mem_request->ra_len,
1903                                             mem_request->ra_len,
1904                                             PCICFG_ROUND_UP(mem_request->ra_len,
1905                                                 PCICFG_MEMGRAN));
1906 #else
1907                                         cardbus_err(dip, 8,
1908                                             "Pre-align [0x%llx] to PCI bridge "
1909                                             "memory gran "
1910                                             "[0x%llx] -> [0x%lx]\n",
1911                                             PCICFG_ROUND_UP(mem_request->ra_len,
1912                                                 PCICFG_MEMGRAN) -
1913                                                 mem_request->ra_len,
1914                                             mem_request->ra_len,
1915                                             PCICFG_ROUND_UP(mem_request->ra_len,
1916                                                 PCICFG_MEMGRAN));
1917 #endif
1918                                 }
1919 
1920                                 if (io_request->ra_len !=
1921                                     PCICFG_ROUND_UP(io_request->ra_len,
1922                                     PCICFG_IOGRAN)) {
1923 
1924 #ifdef _LP64
1925                                         cardbus_err(dip, 8,
1926                                             "Pre-align [0x%lx] to PCI bridge "
1927                                             "I/O gran "
1928                                             "[0x%lx] -> [0x%lx]\n",
1929                                             PCICFG_ROUND_UP(io_request->ra_len,
1930                                                 PCICFG_IOGRAN) -
1931                                                 io_request->ra_len,
1932                                             io_request->ra_len,
1933                                             PCICFG_ROUND_UP(io_request->ra_len,
1934                                                 PCICFG_IOGRAN));
1935 #else
1936                                         cardbus_err(dip, 8,
1937                                             "Pre-align [0x%llx] to PCI bridge "
1938                                             "I/O gran "
1939                                             "[0x%llx] -> [0x%lx]\n",
1940                                             PCICFG_ROUND_UP(io_request->ra_len,
1941                                                 PCICFG_IOGRAN) -
1942                                                 io_request->ra_len,
1943                                             io_request->ra_len,
1944                                             PCICFG_ROUND_UP(io_request->ra_len,
1945                                                 PCICFG_IOGRAN));
1946 #endif
1947                                 }
1948 
1949 #endif
1950                                 mem_request->ra_len = PCICFG_ROUND_UP(
1951                                                         mem_request->ra_len,
1952                                                         PCICFG_MEMGRAN);
1953                                 io_request->ra_len = PCICFG_ROUND_UP(
1954                                                         io_request->ra_len,
1955                                                         PCICFG_IOGRAN);
1956                                 if (entry->memory_gran < PCICFG_MEMGRAN)
1957                                         entry->memory_gran = PCICFG_MEMGRAN;
1958                                 if (entry->io_gran < PCICFG_IOGRAN)
1959                                         entry->io_gran = PCICFG_IOGRAN;
1960                                 ddi_walk_devs(ddi_get_child(dip),
1961                                     cardbus_sum_resources,
1962                                     (void *)entry);
1963 #if defined(CARDBUS_DEBUG)
1964                                 if (mem_request->ra_len !=
1965                                     PCICFG_ROUND_UP(mem_request->ra_len +
1966                                     cardbus_min_spare_mem, PCICFG_MEMGRAN)) {
1967 
1968 #ifdef _LP64
1969                                         cardbus_err(dip, 8,
1970                                             "Post-align [0x%lx] to PCI bridge "
1971                                             "memory gran "
1972                                             "[0x%lx] -> [0x%lx]\n",
1973                                             PCICFG_ROUND_UP(
1974                                                 mem_request->ra_len +
1975                                                 cardbus_min_spare_mem,
1976                                                 PCICFG_MEMGRAN) -
1977                                                 mem_request->ra_len,
1978                                             mem_request->ra_len,
1979                                             PCICFG_ROUND_UP(mem_request->ra_len
1980                                                 + cardbus_min_spare_mem,
1981                                                 PCICFG_MEMGRAN));
1982 #else
1983                                         cardbus_err(dip, 8,
1984                                             "Post-align [0x%llx] to PCI bridge "
1985                                             "memory gran "
1986                                             "[0x%llx] -> [0x%lx]\n",
1987                                             PCICFG_ROUND_UP(
1988                                                 mem_request->ra_len +
1989                                                 cardbus_min_spare_mem,
1990                                                 PCICFG_MEMGRAN) -
1991                                                 mem_request->ra_len,
1992                                             mem_request->ra_len,
1993                                             PCICFG_ROUND_UP(mem_request->ra_len
1994                                                 + cardbus_min_spare_mem,
1995                                                 PCICFG_MEMGRAN));
1996 #endif
1997                                 }
1998 
1999                                 if (io_request->ra_len !=
2000                                     PCICFG_ROUND_UP(io_request->ra_len +
2001                                     cardbus_min_spare_io,
2002                                     PCICFG_IOGRAN)) {
2003 
2004 #ifdef _LP64
2005                                         cardbus_err(dip, 8,
2006                                             "Post-align [0x%lx] to PCI bridge "
2007                                             "I/O gran "
2008                                             "[0x%lx] -> [0x%lx]\n",
2009                                             PCICFG_ROUND_UP(io_request->ra_len +
2010                                                 cardbus_min_spare_io,
2011                                                 PCICFG_IOGRAN) -
2012                                                 io_request->ra_len,
2013                                             io_request->ra_len,
2014                                             PCICFG_ROUND_UP(io_request->ra_len +
2015                                                 cardbus_min_spare_io,
2016                                                 PCICFG_IOGRAN));
2017 #else
2018                                         cardbus_err(dip, 8,
2019                                             "Post-align [0x%llx] to PCI bridge "
2020                                             "I/O gran "
2021                                             "[0x%llx] -> [0x%lx]\n",
2022                                             PCICFG_ROUND_UP(io_request->ra_len +
2023                                                 cardbus_min_spare_io,
2024                                                 PCICFG_IOGRAN) -
2025                                                 io_request->ra_len,
2026                                             io_request->ra_len,
2027                                             PCICFG_ROUND_UP(io_request->ra_len +
2028                                                 cardbus_min_spare_io,
2029                                                 PCICFG_IOGRAN));
2030 #endif
2031                                 }
2032 #endif
2033                                 mem_request->ra_len = PCICFG_ROUND_UP(
2034                                                 mem_request->ra_len +
2035                                                     cardbus_min_spare_mem,
2036                                                 PCICFG_MEMGRAN);
2037                                 io_request->ra_len = PCICFG_ROUND_UP(
2038                                                 io_request->ra_len +
2039                                                     cardbus_min_spare_io,
2040                                                 PCICFG_IOGRAN);
2041                         }
2042                         return (DDI_WALK_PRUNECHILD);
2043 
2044                 case PCI_BRIDGE_CARDBUS:
2045                         /*
2046                          * Cardbus has I/O registers.
2047                          */
2048                         break;
2049 
2050                 case PCI_BRIDGE_ISA:
2051                         /*
2052                          * All the registers requirements for ISA
2053                          * are stored in the reg structure of the bridge.
2054                          * Children of ISA are not of type PCI
2055                          * so must not come through here because
2056                          * cardbus_config_setup() will fail.
2057                          */
2058                         ret = DDI_WALK_PRUNECHILD;
2059                         break;
2060 
2061                 default:
2062                         /*
2063                          * Treat other bridges as leaf nodes.
2064                          */
2065                         break;
2066                 }
2067         }
2068 
2069         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2070             DDI_PROP_DONTPASS, "reg", (caddr_t)&pci_rp,
2071             &length) != DDI_PROP_SUCCESS) {
2072                 /*
2073                  * If one node in (the subtree of nodes)
2074                  * does'nt have a "reg" property fail the
2075                  * allocation.
2076                  */
2077                 entry->memory_len = 0;
2078                 entry->io_len = 0;
2079                 entry->error = PCICFG_FAILURE;
2080                 (void) cardbus_config_teardown(&handle);
2081                 return (DDI_WALK_TERMINATE);
2082         }
2083 
2084         /*
2085          * For each "reg" property with a length, add that to the
2086          * total memory (or I/O) to allocate.
2087          */
2088         rcount = length / sizeof (pci_regspec_t);
2089 
2090         for (i = 0; i < rcount; i++) {
2091 
2092                 switch (PCI_REG_ADDR_G(pci_rp[i].pci_phys_hi)) {
2093 
2094                 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2095                         mem_request->ra_len =
2096                                 pci_rp[i].pci_size_low +
2097                                 PCICFG_ROUND_UP(mem_request->ra_len,
2098                                         pci_rp[i].pci_size_low);
2099 
2100                         cardbus_err(dip, 8,
2101                             "ADDING 32 --->0x%x for BAR@0x%x\n",
2102                             pci_rp[i].pci_size_low,
2103                             PCI_REG_REG_G(pci_rp[i].pci_phys_hi));
2104                         /*
2105                          * the granualarity needs to be the larger of
2106                          * the maximum amount of memory that we're going to
2107                          * ask for, and the PCI-PCI bridge granularity (1M)
2108                          */
2109                         if (pci_rp[i].pci_size_low > entry->memory_gran)
2110                                 entry->memory_gran = pci_rp[i].pci_size_low;
2111                         break;
2112 
2113                 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2114                         mem_request->ra_len =
2115                                 pci_rp[i].pci_size_low +
2116                                 PCICFG_ROUND_UP(mem_request->ra_len,
2117                                         pci_rp[i].pci_size_low);
2118                         cardbus_err(dip, 8,
2119                             "ADDING 64 --->0x%x for BAR@0x%x\n",
2120                             pci_rp[i].pci_size_low,
2121                             PCI_REG_REG_G(pci_rp[i].pci_phys_hi));
2122 
2123                         if (pci_rp[i].pci_size_low > entry->memory_gran)
2124                                 entry->memory_gran = pci_rp[i].pci_size_low;
2125                         break;
2126 
2127                 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2128                         io_request->ra_len =
2129                                 pci_rp[i].pci_size_low +
2130                                 PCICFG_ROUND_UP(io_request->ra_len,
2131                                         pci_rp[i].pci_size_low);
2132                         cardbus_err(dip, 8,
2133                             "ADDING I/O --->0x%x for BAR@0x%x\n",
2134                             pci_rp[i].pci_size_low,
2135                             PCI_REG_REG_G(pci_rp[i].pci_phys_hi));
2136 
2137                         if (pci_rp[i].pci_size_low > entry->io_gran)
2138                                 entry->io_gran = pci_rp[i].pci_size_low;
2139                         break;
2140 
2141                 default:
2142                         /* Config space register - not included */
2143                         break;
2144                 }
2145         }
2146 
2147         /*
2148          * free the memory allocated by ddi_getlongprop
2149          */
2150         kmem_free(pci_rp, length);
2151 
2152         /*
2153          * continue the walk to the next sibling to sum memory
2154          */
2155 
2156         (void) cardbus_config_teardown(&handle);
2157 
2158 #ifdef  _LP64
2159         cardbus_err(dip, 8,
2160             "Memory 0x%lx bytes, I/O 0x%lx bytes, "
2161             "Memgran 0x%x, IOgran 0x%x\n",
2162             mem_request->ra_len, io_request->ra_len,
2163             entry->memory_gran, entry->io_gran);
2164 #else
2165         cardbus_err(dip, 8,
2166             "Memory 0x%llx bytes, I/O 0x%llx bytes, "
2167             "Memgran 0x%x, IOgran 0x%x\n",
2168             mem_request->ra_len, io_request->ra_len,
2169             entry->memory_gran, entry->io_gran);
2170 #endif
2171 
2172         return (ret);
2173 }
2174 
2175 /*
2176  * Free resources allocated to a bridge.
2177  * Note that this routine does not call ndi_ra_free() to actually
2178  * free memory/IO/Bus. This is done as a single chunk for the entire
2179  * device tree in cardbus_free_chunk().
2180  */
2181 static int
2182 cardbus_free_bridge_resources(dev_info_t *dip)
2183 {
2184         cardbus_range_t *ranges;
2185         uint_t          *bus;
2186         int             k;
2187         int             length;
2188         int             i;
2189 
2190         cardbus_err(dip, 6, "cardbus_free_bridge_resources\n");
2191 
2192         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2193             DDI_PROP_DONTPASS, "ranges", (caddr_t)&ranges,
2194             &length) == DDI_PROP_SUCCESS) {
2195                 for (i = 0; i < length / sizeof (cardbus_range_t); i++) {
2196                         if (ranges[i].size_lo != 0 || ranges[i].size_hi != 0) {
2197                                 switch (ranges[i].parent_hi & PCI_REG_ADDR_M) {
2198                                 case PCI_ADDR_IO:
2199                                         cardbus_err(dip, 6,
2200                                             "Need to Free I/O    "
2201                                             "base/length = [0x%x]/[0x%x]\n",
2202                                             ranges[i].child_lo,
2203                                             ranges[i].size_lo);
2204                                         break;
2205 
2206                                 case PCI_ADDR_MEM32:
2207                                 case PCI_ADDR_MEM64:
2208                                         cardbus_err(dip, 6,
2209                                             "Need to Free Memory base/length = "
2210                                             "[0x%x.%x]/[0x%x]\n",
2211                                             ranges[i].child_mid,
2212                                             ranges[i].child_lo,
2213                                             ranges[i].size_lo);
2214                                         break;
2215 
2216                                 default:
2217                                         cardbus_err(dip, 6,
2218                                             "Unknown memory space\n");
2219                                         break;
2220                                 }
2221                         }
2222                 }
2223 
2224                 kmem_free(ranges, length);
2225                 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "ranges");
2226         } else {
2227                 cardbus_err(dip, 8,
2228                     "cardbus_free_bridge_resources: Failed"
2229                     "to read ranges property\n");
2230         }
2231 
2232         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2233             DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
2234             &k) != DDI_PROP_SUCCESS) {
2235                 cardbus_err(dip, 6, "Failed to read bus-range property\n");
2236                 return (PCICFG_FAILURE);
2237         }
2238 
2239         cardbus_err(dip, 6,
2240             "Need to free bus [%d] range [%d]\n",
2241             bus[0], bus[1] - bus[0] + 1);
2242         kmem_free(bus, k);
2243         (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "available");
2244         (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "bus-range");
2245 
2246         return (PCICFG_SUCCESS);
2247 }
2248 
2249 static int
2250 cardbus_free_device_resources(dev_info_t *dip)
2251 {
2252         pci_regspec_t *assigned;
2253 
2254         int length;
2255         int acount;
2256         int i;
2257 
2258         if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2259             DDI_PROP_DONTPASS, "assigned-addresses",
2260             (caddr_t)&assigned,
2261             &length) != DDI_PROP_SUCCESS) {
2262                 cardbus_err(dip, 1,
2263                     "Failed to read assigned-addresses property\n");
2264                 return (PCICFG_FAILURE);
2265         }
2266 
2267         /*
2268          * For each "assigned-addresses" property entry with a length,
2269          * call the memory allocation routines to return the
2270          * resource.
2271          */
2272         acount = length / sizeof (pci_regspec_t);
2273         for (i = 0; i < acount; i++) {
2274 
2275                 /*
2276                  * Free the resource if the size of it is not zero.
2277                  */
2278                 if ((assigned[i].pci_size_low != 0)||
2279                     (assigned[i].pci_size_hi != 0)) {
2280                         switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2281                         case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2282                                 cardbus_err(dip, 6,
2283                                     "Need to return 0x%x of 32 bit MEM space"
2284                                     " @ 0x%x from register 0x%x\n",
2285                                     assigned[i].pci_size_low,
2286                                     assigned[i].pci_phys_low,
2287                                     PCI_REG_REG_G(assigned[i].pci_phys_hi));
2288 
2289                                 break;
2290 
2291                         case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2292                                 cardbus_err(dip, 6,
2293                                     "Need to return 0x%x of 64 bit MEM space"
2294                                     " @ 0x%x.%x from register 0x%x\n",
2295                                     assigned[i].pci_size_low,
2296                                     assigned[i].pci_phys_mid,
2297                                     assigned[i].pci_phys_low,
2298                                     PCI_REG_REG_G(assigned[i].pci_phys_hi));
2299 
2300                                 break;
2301 
2302                         case PCI_REG_ADDR_G(PCI_ADDR_IO):
2303                                 cardbus_err(dip, 6,
2304                                     "Need to return 0x%x of IO space @ 0x%x"
2305                                     " from register 0x%x\n",
2306                                     assigned[i].pci_size_low,
2307                                     assigned[i].pci_phys_low,
2308                                     PCI_REG_REG_G(assigned[i].pci_phys_hi));
2309                                 break;
2310 
2311                         default:
2312                                 cardbus_err(dip, 1, "Unknown register type\n");
2313                                 kmem_free(assigned, length);
2314                                 return (PCICFG_FAILURE);
2315                         } /* switch */
2316                 }
2317         }
2318         kmem_free(assigned, length);
2319         return (PCICFG_SUCCESS);
2320 }
2321 
2322 static int
2323 cardbus_free_resources(dev_info_t *dip)
2324 {
2325         uint32_t classcode;
2326 
2327         classcode = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2328                                 "class-code", -1);
2329         /*
2330          * A different algorithim is used for bridges and leaf devices.
2331          */
2332         if (classcode != -1) {
2333                 classcode = ((uint_t)classcode & 0xffff00) >> 8;
2334                 if (classcode == 0x604 || classcode == 0x607) {
2335                         if (cardbus_free_bridge_resources(dip)
2336                             != PCICFG_SUCCESS) {
2337                                 cardbus_err(dip, 1,
2338                                     "Failed freeing up bridge resources\n");
2339                                 return (PCICFG_FAILURE);
2340                         }
2341                         return (PCICFG_SUCCESS);
2342                 }
2343         }
2344 
2345         if (cardbus_free_device_resources(dip) != PCICFG_SUCCESS) {
2346                 cardbus_err(dip, 1, "Failed freeing up device resources\n");
2347                 return (PCICFG_FAILURE);
2348         }
2349         return (PCICFG_SUCCESS);
2350 }
2351 
2352 static int
2353 cardbus_probe_bridge(cbus_t *cbp, dev_info_t *attpt, uint_t bus,
2354                         uint_t device, uint_t func)
2355 {
2356         /* Declairations */
2357         cardbus_bus_range_t     *bus_range;
2358         int                     i, j;
2359         uint8_t                 header_type;
2360         ddi_acc_handle_t        config_handle;
2361         ndi_ra_request_t        req;
2362         uint_t                  new_bus;
2363         uint64_t                blen;
2364         uint64_t                next_bus;
2365         int circ;
2366 
2367         cardbus_err(cbp->cb_dip, 6,
2368             "cardbus_probe_bridge bus %d device %d func %d\n",
2369             bus, device, func);
2370 
2371         ndi_devi_enter(cbp->cb_dip, &circ);
2372         if (pci_config_setup(cbp->cb_dip, &config_handle) != DDI_SUCCESS) {
2373 
2374                 cardbus_err(cbp->cb_dip, 1,
2375                     "cardbus_probe_bridge(): Failed to setup config space\n");
2376 
2377                 ndi_devi_exit(cbp->cb_dip, circ);
2378                 return (PCICFG_FAILURE);
2379         }
2380 
2381         header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
2382 
2383         /*
2384          * As soon as we have access to config space, check device
2385          * is a bridge.
2386          */
2387         if ((header_type & PCI_HEADER_TYPE_M) != PCI_HEADER_CARDBUS)
2388                 goto failed;
2389 
2390         cardbus_err(cbp->cb_dip, 8,
2391             "---Vendor ID = [0x%04x]\n",
2392             pci_config_get16(config_handle, PCI_CONF_VENID));
2393         cardbus_err(cbp->cb_dip, 8,
2394             "---Device ID = [0x%04x]\n",
2395             pci_config_get16(config_handle, PCI_CONF_DEVID));
2396 
2397         /* say what type of header */
2398         cardbus_err(cbp->cb_dip, 8,
2399             "--%s bridge found root bus [0x%x] device [0x%x] func [0x%x]\n",
2400             ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) ?
2401                 "PCI-PCI" : "Cardbus",
2402             bus, device, func);
2403 
2404         if (ddi_getlongprop(DDI_DEV_T_ANY, cbp->cb_dip, 0, "bus-range",
2405             (caddr_t)&bus_range, &i) != DDI_PROP_SUCCESS)
2406                 cardbus_err(cbp->cb_dip, 1,
2407                     "No bus-range property seems to have been set up\n");
2408         else {
2409                 cardbus_err(cbp->cb_dip, 8,
2410                     "allowable bus range is %u->%u\n",
2411                     bus_range->lo, bus_range->hi);
2412                 kmem_free((caddr_t)bus_range, i);
2413         }
2414 
2415         /*
2416          * Get next bus in sequence and program device.
2417          */
2418         bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
2419         req.ra_len = 1;
2420 
2421         if (ndi_ra_alloc(cbp->cb_dip, &req,
2422             &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
2423             NDI_RA_PASS) != NDI_SUCCESS) {
2424                 cmn_err(CE_WARN, "Failed to get a bus number\n");
2425                 goto failed;
2426         }
2427 
2428         new_bus = next_bus;
2429         cardbus_err(cbp->cb_dip, 8,
2430             "NEW bus found [%u]->[%u]\n", bus, new_bus);
2431 
2432         (void) cardbus_set_bus_numbers(config_handle, bus, new_bus);
2433 
2434         /* Enable it all */
2435         enable_cardbus_bridge(cbp->cb_dip, config_handle);
2436 
2437         /*
2438          * Probe all children devices
2439          */
2440         for (i = 0; i < pcicfg_max_device; i++)
2441                 for (j = 0; j < pcicfg_max_function; j++)
2442                         switch (cardbus_probe_children(cbp, attpt, new_bus, i,
2443                             j, &header_type)) {
2444 
2445                         case PCICFG_FAILURE:
2446                                 cardbus_err(cbp->cb_dip, 1,
2447                                     "Failed to configure bus "
2448                                     "[0x%x] device [0x%x] func [0x%x]\n",
2449                                     new_bus, i, j);
2450                                 disable_cardbus_bridge(cbp->cb_dip,
2451                                     config_handle);
2452                                 goto failed;
2453 
2454                         case PCICFG_NODEVICE:
2455                                 /*
2456                                  * if there's no function 0
2457                                  * there's no point in probing other
2458                                  * functions
2459                                  */
2460                                 if (j != 0)
2461                                         break;
2462                                 /* FALLTHROUGH */
2463                         case PCICFG_NOMULTI:
2464                                 j = pcicfg_max_function;
2465                                 break;
2466 
2467                         default:
2468                                 break;
2469                         }
2470 
2471         (void) pci_config_teardown(&config_handle);
2472         (void) i_ndi_config_node(attpt, DS_LINKED, 0);
2473         ndi_devi_exit(cbp->cb_dip, circ);
2474 
2475         return (PCICFG_SUCCESS);
2476 
2477 failed:
2478         (void) pci_config_teardown(&config_handle);
2479         ndi_devi_exit(cbp->cb_dip, circ);
2480 
2481         return (PCICFG_FAILURE);
2482 }
2483 
2484 static struct isa_node isa_nodes[] = {
2485         {"dummy", {NULL, NULL, NULL, NULL, NULL}, "serial", "", 0x4e, 0x2}
2486 };
2487 
2488 static int
2489 cardbus_probe_children(cbus_t *cbp, dev_info_t *parent, uint_t bus,
2490                         uint_t device, uint_t func, uint8_t *header_type)
2491 {
2492         dev_info_t              *new_child;
2493         ddi_acc_handle_t        config_handle;
2494         int                     i, j;
2495         ndi_ra_request_t        req;
2496         uint64_t                next_bus;
2497         uint64_t                blen;
2498         uint32_t                request;
2499         uint8_t                 base_class;
2500         uint_t                  new_bus;
2501         int                     ret;
2502         int                     circ;
2503 
2504         cardbus_err(parent, 6,
2505             "cardbus_probe_children bus %d device %d func %d\n",
2506             bus, device, func);
2507 
2508         /*
2509          * This node will be put immediately below
2510          * "parent". Allocate a blank device node.  It will either
2511          * be filled in or freed up based on further probing.
2512          */
2513 
2514         ndi_devi_enter(parent, &circ);
2515 
2516         if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
2517             (pnode_t)DEVI_SID_NODEID,
2518             &new_child) != NDI_SUCCESS) {
2519                 cardbus_err(parent, 1,
2520                     "cardbus_probe_children(): Failed to alloc child node\n");
2521                 ndi_devi_exit(parent, circ);
2522                 return (PCICFG_FAILURE);
2523         }
2524 
2525         if (cardbus_add_config_reg(new_child, bus,
2526             device, func) != DDI_SUCCESS) {
2527                 cardbus_err(parent, 1,
2528                     "cardbus_probe_children(): Failed to add candidate REG\n");
2529                 goto failedconfig;
2530         }
2531 
2532         if ((ret = cardbus_config_setup(new_child, &config_handle))
2533             != PCICFG_SUCCESS) {
2534 
2535                 if (ret == PCICFG_NODEVICE) {
2536                         (void) ndi_devi_free(new_child);
2537                         return (ret);
2538                 }
2539                 cardbus_err(parent, 1,
2540                     "cardbus_probe_children(): Failed to setup config space\n");
2541 
2542                 goto failedconfig;
2543         }
2544 
2545         base_class = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
2546 
2547         if (func == 0) {
2548                 /*
2549                  * Preserve the header type from function 0.
2550                  * Additional functions may not preserve the PCI_HEADER_MULTI
2551                  * bit.
2552                  */
2553                 *header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
2554         } else if (!(*header_type & PCI_HEADER_MULTI) ||
2555                     ((*header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) ||
2556                     (base_class == PCI_CLASS_BRIDGE)) {
2557 
2558                 (void) cardbus_config_teardown(&config_handle);
2559                 (void) ndi_devi_free(new_child);
2560                 return (PCICFG_NOMULTI);
2561         }
2562 
2563         /*
2564          * As soon as we have access to config space,
2565          * turn off device. It will get turned on
2566          * later (after memory is assigned).
2567          * not if it's a cardbus device. It may be OK to leave
2568          * it on - try LATER
2569          */
2570         disable_cardbus_device(config_handle);
2571 
2572         /*
2573          * Set 1275 properties common to all devices
2574          */
2575         if (cardbus_set_standard_props(parent, new_child,
2576             config_handle) != PCICFG_SUCCESS) {
2577                 cardbus_err(parent, 1, "Failed to set standard properties\n");
2578                 goto failedchild;
2579         }
2580 
2581         /*
2582          * Child node properties  NOTE: Both for PCI-PCI bridge and child node
2583          */
2584         if (cardbus_set_childnode_props(new_child,
2585             config_handle) != PCICFG_SUCCESS) {
2586                 goto failedchild;
2587         }
2588 
2589         cardbus_err(parent, 8,
2590             "---Vendor ID = [0x%04x]\n",
2591             pci_config_get16(config_handle, PCI_CONF_VENID));
2592         cardbus_err(parent, 8,
2593             "---Device ID = [0x%04x]\n",
2594             pci_config_get16(config_handle, PCI_CONF_DEVID));
2595 
2596         if (base_class == PCI_CLASS_BRIDGE) {
2597                 uint8_t sub_class;
2598 
2599                 sub_class = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
2600 
2601                 switch (sub_class) {
2602                 case PCI_BRIDGE_PCI:
2603                         if ((*header_type & PCI_HEADER_TYPE_M)
2604                             == PCI_HEADER_PPB) {
2605                                 cardbus_bus_range_t *bus_range;
2606                                 int k;
2607 
2608                                 /* say what type of header */
2609                                 cardbus_err(parent, 8,
2610                                     "-- Found PCI-PCI bridge @ "
2611                                     " bus [0x%x] device [0x%x] func [0x%x]\n",
2612                                     bus, device, func);
2613 
2614                                 if (ddi_getlongprop(DDI_DEV_T_ANY,
2615                                     new_child, 0, "bus-range",
2616                                     (caddr_t)&bus_range,
2617                                     &k) != DDI_PROP_SUCCESS)
2618                                         cardbus_err(new_child, 1,
2619                                             "No bus-range property"
2620                                             " seems to have been set up\n");
2621                                 else {
2622                                         cardbus_err(new_child, 8,
2623                                             "allowable bus range is %u->%u\n",
2624                                             bus_range->lo, bus_range->hi);
2625                                         kmem_free((caddr_t)bus_range, k);
2626                                 }
2627 
2628                                 /*
2629                                  * Get next bus in sequence and program device.
2630                                  */
2631                                 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
2632                                 req.ra_len = 1;
2633 
2634                                 if (ndi_ra_alloc(new_child, &req,
2635                                     &next_bus, &blen,
2636                                     NDI_RA_TYPE_PCI_BUSNUM,
2637                                     NDI_RA_PASS) != NDI_SUCCESS) {
2638                                         cmn_err(CE_WARN,
2639                                             "Failed to get a bus number\n");
2640                                         goto failedchild;
2641                                 }
2642 
2643                                 new_bus = next_bus;
2644 
2645                                 cardbus_err(new_child, 8,
2646                                     "NEW bus found [%u]->[%u]\n", bus, new_bus);
2647 
2648                                 /* Enable it all */
2649                                 enable_pci_pci_bridge(new_child, config_handle);
2650                                 (void) cardbus_set_bus_numbers(config_handle,
2651                                     bus, new_bus);
2652 
2653 #if defined(CARDBUS_DEBUG)
2654                                 if (cardbus_debug >= 9) {
2655                                         cardbus_dump_config(config_handle);
2656                                 }
2657 #endif
2658 
2659                                 /*
2660                                  * Set bus properties
2661                                  */
2662                                 if (cardbus_set_busnode_props(new_child)
2663                                     != PCICFG_SUCCESS) {
2664                                         cardbus_err(new_child, 1,
2665                                             "Failed to set busnode props\n");
2666                                         disable_pci_pci_bridge(new_child,
2667                                             config_handle);
2668                                         goto failedchild;
2669                                 }
2670 
2671                                 /*
2672                                  * Probe all children devices
2673                                  */
2674                                 for (i = 0; i < pcicfg_max_device; i++)
2675                                         for (j = 0; j < pcicfg_max_function;
2676                                             j++)
2677                                                 switch (cardbus_probe_children(
2678                                                     cbp,
2679                                                     new_child,
2680                                                     new_bus, i,
2681                                                     j, header_type)) {
2682                                                 case PCICFG_FAILURE:
2683                                                         cardbus_err(parent, 1,
2684                                                             "Failed to "
2685                                                             "configure "
2686                                                             "bus [0x%x] "
2687                                                             "device [0x%x] "
2688                                                             "func [0x%x]\n",
2689                                                             new_bus, i, j);
2690                                                         disable_pci_pci_bridge(
2691                                                                 new_child,
2692                                                                 config_handle);
2693                                                         goto failedchild;
2694 
2695                                                 case PCICFG_NODEVICE:
2696                                                         /*
2697                                                          * if there's no
2698                                                          * function 0
2699                                                          * there's no point in
2700                                                          * probing other
2701                                                          * functions
2702                                                          */
2703                                                         if (j != 0)
2704                                                                 break;
2705                                                         /* FALLTHROUGH */
2706                                                 case PCICFG_NOMULTI:
2707                                                         j = pcicfg_max_function;
2708                                                         break;
2709 
2710                                                 default:
2711                                                         break;
2712                                                 }
2713                         }
2714                         break;
2715 
2716                 case PCI_BRIDGE_CARDBUS:
2717                         cardbus_err(parent, 8,
2718                             "--Found Cardbus bridge @ "
2719                             "bus [0x%x] device [0x%x] func [0x%x]\n",
2720                             bus, device, func);
2721                         pci_config_put32(config_handle,
2722                             PCI_CONF_BASE0, 0xffffffff);
2723 
2724                         request = pci_config_get32(config_handle,
2725                             PCI_CONF_BASE0);
2726 
2727                         /*
2728                          * If its a zero length, don't do
2729                          * any programming.
2730                          */
2731                         if (request != 0) {
2732                                 if (request == (uint32_t)0xffffffff) {
2733                                         cmn_err(CE_WARN,
2734                                             "cardbus_probe_children: "
2735                                             "can't access device");
2736                                         goto failedchild;
2737                                 }
2738                                 /*
2739                                  * Add to the "reg" property
2740                                  */
2741                                 if (cardbus_update_reg_prop(new_child,
2742                                     request,
2743                                     PCI_CONF_BASE0) != PCICFG_SUCCESS) {
2744                                         goto failedchild;
2745                                 }
2746                                 cardbus_err(parent, 8,
2747                                     "BASE register [0x%x] asks for "
2748                                     "[0x%x]=[0x%x](32)\n",
2749                                     PCI_CONF_BASE0, request,
2750                                     (~(PCI_BASE_M_ADDR_M & request))+1);
2751                         }
2752                         break;
2753 
2754                 case PCI_BRIDGE_ISA:
2755                         cardbus_err(parent, 8,
2756                             "--Found ISA bridge @ "
2757                             "bus [0x%x] device [0x%x] func [0x%x]\n",
2758                             bus, device, func);
2759                         enable_pci_isa_bridge(new_child, config_handle);
2760 
2761 #if defined(CARDBUS_DEBUG)
2762                         if (cardbus_debug >= 4) {
2763                                 cardbus_dump_common_config(config_handle);
2764                                 cardbus_err(NULL, 1,
2765                                     " DDMA SlvCh0 = [0x%04x]        "
2766                                     "DDMA SlvCh1 = [0x%04x]\n",
2767                                     pci_config_get16(config_handle, 0x40),
2768                                     pci_config_get16(config_handle, 0x42));
2769                                 cardbus_err(NULL, 1,
2770                                     " DDMA SlvCh2 = [0x%04x]        "
2771                                     "DDMA SlvCh3 = [0x%04x]\n",
2772                                     pci_config_get16(config_handle, 0x44),
2773                                     pci_config_get16(config_handle, 0x46));
2774                                 cardbus_err(NULL, 1,
2775                                     " DDMA SlvCh5 = [0x%04x]        "
2776                                     "DDMA SlvCh6 = [0x%04x]\n",
2777                                     pci_config_get16(config_handle, 0x4a),
2778                                     pci_config_get16(config_handle, 0x4c));
2779                                 cardbus_err(NULL, 1,
2780                                     " DDMA SlvCh7 = [0x%04x]        "
2781                                     "Misc Cntrl  = [0x%02x]\n",
2782                                     pci_config_get16(config_handle, 0x4e),
2783                                     pci_config_get8(config_handle, 0x57));
2784                                 cardbus_err(NULL, 1,
2785                                     " DMA Cntl    = [0x%02x]          "
2786                                     "DMA TyF Tim = [0x%02x]\n",
2787                                     pci_config_get8(config_handle, 0x48),
2788                                     pci_config_get8(config_handle, 0x49));
2789                                 cardbus_err(NULL, 1,
2790                                     " TimCntrl    = [0x%02x]          "
2791                                     "MTOP        = [0x%02x]\n",
2792                                     pci_config_get8(config_handle, 0x50),
2793                                     pci_config_get8(config_handle, 0x51));
2794                                 cardbus_err(NULL, 1,
2795                                     " MDMA Access = [0x%02x]          "
2796                                     "ROMCS       = [0x%02x]\n",
2797                                     pci_config_get8(config_handle, 0x52),
2798                                     pci_config_get8(config_handle, 0x53));
2799                                 cardbus_err(NULL, 1,
2800                                     " Dscrd Tmr   = [0x%02x]          "
2801                                     "Retry Tmr   = [0x%02x]\n",
2802                                     pci_config_get8(config_handle, 0x55),
2803                                     pci_config_get8(config_handle, 0x54));
2804                                 cardbus_err(NULL, 1,
2805                                     " I/O Spc 0   = [0x%08x]    "
2806                                     "I/O Spc 1   = [0x%08x]\n",
2807                                     pci_config_get32(config_handle, 0x58),
2808                                     pci_config_get32(config_handle, 0x5c));
2809                                 cardbus_err(NULL, 1,
2810                                     " I/O Spc 2   = [0x%08x]    "
2811                                     "I/O Spc 3   = [0x%08x]\n",
2812                                     pci_config_get32(config_handle, 0x60),
2813                                     pci_config_get32(config_handle, 0x64));
2814                                 cardbus_err(NULL, 1,
2815                                     " I/O Spc 4   = [0x%08x]    "
2816                                     "I/O Spc 5   = [0x%08x]\n",
2817                                     pci_config_get32(config_handle, 0x68),
2818                                     pci_config_get32(config_handle, 0x6c));
2819                                 cardbus_err(NULL, 1,
2820                                     " Mem Spc 0   = [0x%08x]    "
2821                                     "Mem Spc 1   = [0x%08x]\n",
2822                                     pci_config_get32(config_handle, 0x70),
2823                                     pci_config_get32(config_handle, 0x74));
2824                                 cardbus_err(NULL, 1,
2825                                     " Mem Spc 2   = [0x%08x]    "
2826                                     "Mem Spc 3   = [0x%08x]\n",
2827                                     pci_config_get32(config_handle, 0x78),
2828                                     pci_config_get32(config_handle, 0x7c));
2829                         }
2830 #endif
2831                         /*
2832                          * Set bus properties
2833                          */
2834                         if (cardbus_set_busnode_isaprops(new_child)
2835                             != PCICFG_SUCCESS) {
2836                                 cardbus_err(new_child, 1,
2837                                     "Failed to set busnode props\n");
2838                                 disable_cardbus_device(config_handle);
2839                                 goto failedchild;
2840                         }
2841 
2842                         /*
2843                          * Add to the "reg" property.
2844                          * Simply grab 1K of I/O space.
2845                          */
2846                         if (cardbus_update_reg_prop(new_child,
2847                             0xfffffc00 | PCI_BASE_SPACE_IO,
2848                             PCI_CONF_BASE0) != PCICFG_SUCCESS) {
2849                                 goto failedchild;
2850                         }
2851 
2852                         /*
2853                          * Probe all potential children devices.
2854                          */
2855                         for (i = 0;
2856                             i < sizeof (isa_nodes) / sizeof (isa_nodes[0]);
2857                             i++)
2858                                 switch (cardbus_add_isa_node(cbp, new_child,
2859                                     &isa_nodes[i])) {
2860                                 case PCICFG_FAILURE:
2861                                         cardbus_err(parent, 1,
2862                                             "Failed to configure isa bus\n");
2863                                         disable_cardbus_device(config_handle);
2864                                         goto failedchild;
2865 
2866                                 case PCICFG_NODEVICE:
2867                                         continue;
2868                                 }
2869 
2870                         break;
2871 
2872                 case PCI_BRIDGE_OTHER:
2873                 default:
2874                         cardbus_err(parent, 8,
2875                             "--Found unknown bridge, subclass 0x%x @ "
2876                             "bus [0x%x] device [0x%x] func [0x%x]\n",
2877                             sub_class, bus, device, func);
2878                         goto leaf_node;
2879                 }
2880         } else {
2881                 cardbus_err(parent, 8,
2882                     "--Leaf device found "
2883                     "bus [0x%x] device [0x%x] func [0x%x]\n",
2884                     bus, device, func);
2885                 /*
2886                  * Ethernet devices.
2887                  */
2888                 if (strcmp(ddi_binding_name(new_child), "ethernet") == 0) {
2889                         extern int localetheraddr(struct ether_addr *,
2890                             struct ether_addr *);
2891                         uchar_t mac[6];
2892 
2893                         cardbus_force_stringprop(new_child,
2894                             "device_type", "network");
2895 
2896                         if (localetheraddr(NULL, (struct ether_addr *)mac)) {
2897                                 (void) ddi_prop_create(DDI_DEV_T_NONE,
2898                                     new_child,
2899                                     DDI_PROP_CANSLEEP, "local-mac-address",
2900                                     (caddr_t)mac, 6);
2901                         }
2902                 }
2903 leaf_node:
2904                 if (cbp->cb_dsp) {
2905                         struct cb_deviceset_props *cdsp = cbp->cb_dsp;
2906                         uint16_t venid = pci_config_get16(config_handle,
2907                                                 PCI_CONF_VENID);
2908                         uint16_t devid = pci_config_get16(config_handle,
2909                                                 PCI_CONF_DEVID);
2910                         ddi_prop_t *propp;
2911 
2912                         for (cdsp = cbp->cb_dsp; cdsp; cdsp = cdsp->next) {
2913                                 if (cdsp->binding_name &&
2914                                     strcmp(ddi_binding_name(new_child),
2915                                     cdsp->binding_name))
2916                                         continue;
2917                                 if (cdsp->venid && (cdsp->venid != venid))
2918                                         continue;
2919                                 if (cdsp->devid && (cdsp->devid != devid))
2920                                         continue;
2921                                 if (cdsp->nodename) {
2922                                         if (ndi_devi_set_nodename(new_child,
2923                                             cdsp->nodename,
2924                                             0) != NDI_SUCCESS)
2925                                                 cardbus_err(new_child, 1,
2926                                                     "Failed to set nodename\n");
2927                                 }
2928                                 for (propp = cdsp->prop_list; propp;
2929                                     propp = propp->prop_next) {
2930                                         switch (propp->prop_flags) {
2931                                         case DDI_PROP_TYPE_INT:
2932                                                 cardbus_force_intprop(
2933                                                     new_child,
2934                                                     propp->prop_name,
2935                                                     (int *)propp->prop_val,
2936                                                     propp->prop_len);
2937                                                 break;
2938                                         case DDI_PROP_TYPE_STRING:
2939                                                 cardbus_force_stringprop(
2940                                                     new_child,
2941                                                     propp->prop_name,
2942                                                     (char *)propp->prop_val);
2943                                                 break;
2944                                         case DDI_PROP_TYPE_ANY:
2945                                                 cardbus_force_boolprop(
2946                                                     new_child,
2947                                                     propp->prop_name);
2948                                                 break;
2949                                         }
2950                                 }
2951                         }
2952                 }
2953 
2954 #if defined(CARDBUS_DEBUG)
2955                 if (cardbus_debug >= 9) {
2956                         cardbus_dump_config(config_handle);
2957                 }
2958 #endif
2959 
2960                 i = PCI_CONF_BASE0;
2961 
2962                 while (i <= PCI_CONF_BASE5) {
2963                         pci_config_put32(config_handle, i, 0xffffffff);
2964 
2965                         request = pci_config_get32(config_handle, i);
2966 
2967                         /*
2968                          * If its a zero length, don't do
2969                          * any programming.
2970                          */
2971                         if (request != 0) {
2972                                 if (request == (uint32_t)0xffffffff) {
2973                                         cmn_err(CE_WARN,
2974                                             "cardbus_probe_children: "
2975                                             "can't access device");
2976                                         goto failedchild;
2977                                 }
2978                                 /*
2979                                  * Add to the "reg" property
2980                                  */
2981                                 if (cardbus_update_reg_prop(new_child,
2982                                     request, i) != PCICFG_SUCCESS) {
2983                                         goto failedchild;
2984                                 }
2985                         } else {
2986                                 cardbus_err(parent, 8, "All memory found\n");
2987                                 break;
2988                         }
2989 
2990                         /*
2991                          * Increment by eight if it is 64 bit address space
2992                          * only if memory space
2993                          */
2994                         if (((PCI_BASE_TYPE_M & request)
2995                                 == PCI_BASE_TYPE_ALL) &&
2996                             ((PCI_BASE_SPACE_M & request)
2997                                 == PCI_BASE_SPACE_MEM)) {
2998                                 cardbus_err(parent, 8,
2999                                     "BASE register [0x%x] asks for "
3000                                     "[0x%x]=[0x%x] (64)\n",
3001                                     i, request,
3002                                     (~(PCI_BASE_M_ADDR_M & request))+1);
3003                                 i += 8;
3004                         } else {
3005                                 cardbus_err(parent, 8,
3006                                     "BASE register [0x%x] asks for "
3007                                     "[0x%x]=[0x%x](32)\n",
3008                                     i, request,
3009                                     (~(PCI_BASE_M_ADDR_M & request))+1);
3010                                 i += 4;
3011                         }
3012                 }
3013 
3014                 /*
3015                  * Get the ROM size and create register for it
3016                  */
3017                 pci_config_put32(config_handle, PCI_CONF_ROM, 0xffffffff);
3018 
3019                 request = pci_config_get32(config_handle, PCI_CONF_ROM);
3020                 /*
3021                  * If its a zero length, don't do
3022                  * any programming.
3023                  */
3024 
3025                 if (request != 0) {
3026                         cardbus_err(parent, 9,
3027                             "BASE register [0x%x] asks for "
3028                             "[0x%x]=[0x%x] (ROM)\n",
3029                             PCI_CONF_ROM, request,
3030                             (~(PCI_BASE_ROM_ADDR_M & request))+1);
3031                         /*
3032                          * Add to the "reg" property
3033                          */
3034                         if (cardbus_update_reg_prop(new_child,
3035                             request,
3036                             PCI_CONF_ROM) != PCICFG_SUCCESS) {
3037                                 goto failedchild;
3038                         }
3039                 }
3040         }
3041 
3042         (void) cardbus_config_teardown(&config_handle);
3043 
3044         /*
3045          * Attach the child to its parent
3046          */
3047         (void) i_ndi_config_node(new_child, DS_LINKED, 0);
3048         ndi_devi_exit(parent, circ);
3049 
3050         return (PCICFG_SUCCESS);
3051 failedchild:
3052         /*
3053          * check if it should be taken offline (if online)
3054          */
3055         (void) cardbus_config_teardown(&config_handle);
3056 
3057 failedconfig:
3058 
3059         (void) ndi_devi_free(new_child);
3060         ndi_devi_exit(parent, circ);
3061 
3062         return (PCICFG_FAILURE);
3063 }
3064 
3065 static int
3066 cardbus_add_config_reg(dev_info_t *dip,
3067                 uint_t bus, uint_t device, uint_t func)
3068 {
3069         int reg[10] = { PCI_ADDR_CONFIG, 0, 0, 0, 0};
3070 
3071         reg[0] = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
3072 
3073         return (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3074             "reg", reg, 5));
3075 }
3076 
3077 static int
3078 cardbus_add_isa_node(cbus_t *cbp, dev_info_t *parent, struct isa_node *node)
3079 {
3080         dev_info_t              *new_child;
3081         int                     ret;
3082         uint32_t                reg[3];
3083 
3084         _NOTE(ARGUNUSED(cbp))
3085 
3086         cardbus_err(parent, 6, "cardbus_add_isa_node\n");
3087 
3088         /*
3089          * This node will be put immediately below
3090          * "parent". Allocate a blank device node.
3091          */
3092         if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
3093             (pnode_t)DEVI_SID_NODEID,
3094             &new_child) != NDI_SUCCESS) {
3095                 cardbus_err(parent, 1,
3096                     "cardbus_add_isa_child(): Failed to alloc child node\n");
3097                 return (PCICFG_FAILURE);
3098         }
3099 
3100         /*
3101          * Set properties common to ISA devices
3102          */
3103         if (cardbus_set_isa_props(parent, new_child, node->name,
3104             node->compatible) != PCICFG_SUCCESS) {
3105                 cardbus_err(parent, 1, "Failed to set ISA properties\n");
3106                 goto failed;
3107         }
3108 
3109         cardbus_err(new_child, 8, "--Leaf ISA device\n");
3110 
3111         /*
3112          * Add the "reg" property.
3113          */
3114         reg[0] = 0;
3115         reg[1] = node->reg;
3116         reg[2] = node->span;
3117 
3118         ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
3119             "basereg", (int *)reg, 3);
3120         if (ret != DDI_SUCCESS)
3121                 goto failed;
3122 
3123         (void) i_ndi_config_node(new_child, DS_LINKED, 0);
3124 
3125         return (PCICFG_SUCCESS);
3126 
3127 failed:
3128         (void) ndi_devi_free(new_child);
3129 
3130         return (PCICFG_FAILURE);
3131 }
3132 
3133 static int
3134 cardbus_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
3135 {
3136         caddr_t         cfgaddr;
3137         ddi_device_acc_attr_t   attr;
3138         dev_info_t      *anode;
3139         int     status;
3140         int     rlen;
3141         pci_regspec_t   *reg;
3142         int             ret;
3143 #ifdef sparc
3144         int16_t         val;
3145 #endif
3146 
3147         cardbus_err(dip, 10,
3148             "cardbus_config_setup(dip=0x%p)\n", (void *) dip);
3149 
3150         /*
3151          * Get the pci register spec from the node
3152          */
3153         status = ddi_getlongprop(DDI_DEV_T_NONE,
3154             dip, DDI_PROP_DONTPASS, "reg",
3155             (caddr_t)&reg, &rlen);
3156 
3157         cardbus_err(dip, 10,
3158             "cardbus_config_setup, reg = 0x%p\n", (void *) reg);
3159 
3160         switch (status) {
3161         case DDI_PROP_SUCCESS:
3162                 break;
3163         case DDI_PROP_NO_MEMORY:
3164                 cardbus_err(dip, 1, "reg present, but unable to get memory\n");
3165                 return (PCICFG_FAILURE);
3166         default:
3167                 cardbus_err(dip, 1, "no reg property\n");
3168                 return (PCICFG_FAILURE);
3169         }
3170 
3171         anode = dip;
3172 
3173         /*
3174          * Find the attachment point node
3175          */
3176         while ((anode != NULL) && (strcmp(ddi_binding_name(anode),
3177             "hp_attachment") != 0)) {
3178                 anode = ddi_get_parent(anode);
3179         }
3180 
3181         if (anode == NULL) {
3182                 cardbus_err(dip, 1, "Tree not in PROBE state\n");
3183                 kmem_free((caddr_t)reg, rlen);
3184                 return (PCICFG_FAILURE);
3185         }
3186 
3187         if ((ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, anode,
3188             "reg", (int *)reg, 5)) != 0) {
3189                 cardbus_err(dip, 1,
3190                     "Failed to update reg property, error code %d\n", ret);
3191                 kmem_free((caddr_t)reg, rlen);
3192                 return (PCICFG_FAILURE);
3193         }
3194 
3195         attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3196         attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3197         attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3198 
3199         if (ddi_regs_map_setup(anode, 0, &cfgaddr,
3200             0, /* PCI_CONF_HDR_SIZE */
3201             0,
3202             &attr, handle) != DDI_SUCCESS) {
3203                 cardbus_err(dip, 1,
3204                     "Failed to setup registers for [0x%x][0x%x][0x%x]\n",
3205                     PCI_REG_BUS_G(reg->pci_phys_hi),
3206                     PCI_REG_DEV_G(reg->pci_phys_hi),
3207                     PCI_REG_FUNC_G(reg->pci_phys_hi));
3208                 kmem_free((caddr_t)reg, rlen);
3209                 return (PCICFG_FAILURE);
3210         }
3211 
3212         cardbus_err(dip, 9,
3213             "PROBING =>->->->->->-> [0x%x][0x%x][0x%x] 0x%x 0x%p\n",
3214             PCI_REG_BUS_G(reg->pci_phys_hi),
3215             PCI_REG_DEV_G(reg->pci_phys_hi),
3216             PCI_REG_FUNC_G(reg->pci_phys_hi),
3217             reg->pci_phys_hi, (void *) cfgaddr);
3218 
3219         /*
3220          * must do peek16 otherwise the system crashes when probing
3221          * a non zero function on a non-multi-function card.
3222          */
3223 #ifdef sparc
3224         if (ddi_peek16(anode, (int16_t *)cfgaddr, &val) != DDI_SUCCESS) {
3225                 cardbus_err(dip, 8,
3226                     "cardbus_config_setup peek failed\n");
3227                 ret = PCICFG_NODEVICE;
3228         } else if (ddi_get16(*handle, (uint16_t *)cfgaddr) == 0xffff) {
3229                 cardbus_err(dip, 8,
3230                     "cardbus_config_setup PCICFG_NODEVICE\n");
3231                 ret = PCICFG_NODEVICE;
3232 #elif defined(__x86) || defined(__amd64)
3233         if (ddi_get16(*handle, (uint16_t *)cfgaddr) == 0xffff) {
3234                 cardbus_err(dip, 8,
3235                     "cardbus_config_setup PCICFG_NODEVICE\n");
3236                 ret = PCICFG_NODEVICE;
3237 #endif
3238         } else {
3239                 cardbus_err(dip, 1,
3240                     "cardbus_config_setup found device at:[0x%x][0x%x][0x%x]\n",
3241                     PCI_REG_BUS_G(reg->pci_phys_hi),
3242                     PCI_REG_DEV_G(reg->pci_phys_hi),
3243                     PCI_REG_FUNC_G(reg->pci_phys_hi));
3244 
3245                 ret = PCICFG_SUCCESS;
3246         }
3247 
3248         kmem_free((caddr_t)reg, rlen);
3249         if (ret != PCICFG_SUCCESS) {
3250                 cardbus_config_teardown(handle);
3251         }
3252 
3253         cardbus_err(dip, 7,
3254             "cardbus_config_setup returning %d\n", ret);
3255 
3256         return (ret);
3257 }
3258 
3259 static void
3260 cardbus_config_teardown(ddi_acc_handle_t *handle)
3261 {
3262         (void) ddi_regs_map_free(handle);
3263 }
3264 
3265 static void
3266 cardbus_reparent_children(dev_info_t *dip, dev_info_t *parent)
3267 {
3268         dev_info_t *child;
3269         int circ;
3270 
3271         while (child = ddi_get_child(dip)) {
3272                 ASSERT(i_ddi_node_state(child) <= DS_LINKED);
3273                 /*
3274                  * Unlink node from tree before reparenting
3275                  */
3276                 ndi_devi_enter(dip, &circ);
3277                 (void) i_ndi_unconfig_node(child, DS_PROTO, 0);
3278                 ndi_devi_exit(dip, circ);
3279                 DEVI(child)->devi_parent = DEVI(parent);
3280                 DEVI(child)->devi_bus_ctl = DEVI(parent);
3281                 ndi_devi_enter(parent, &circ);
3282                 (void) i_ndi_config_node(child, DS_LINKED, 0);
3283                 ndi_devi_exit(parent, circ);
3284         }
3285 }
3286 
3287 static int
3288 cardbus_update_assigned_prop(dev_info_t *dip, pci_regspec_t *newone)
3289 {
3290         int             alen;
3291         pci_regspec_t   *assigned;
3292         caddr_t         newreg;
3293         uint_t          status;
3294 
3295         status = ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3296             "assigned-addresses", (caddr_t)&assigned, &alen);
3297         switch (status) {
3298         case DDI_PROP_SUCCESS:
3299                 cardbus_err(dip, 5,
3300                     "cardbus_update_assigned_prop: found prop len %d\n",
3301                     alen);
3302                 /*
3303                  * Allocate memory for the existing
3304                  * assigned-addresses(s) plus one and then
3305                  * build it.
3306                  */
3307                 newreg = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
3308 
3309                 bcopy(assigned, newreg, alen);
3310                 bcopy(newone, newreg + alen, sizeof (*newone));
3311                 break;
3312 
3313         case DDI_PROP_NO_MEMORY:
3314                 cardbus_err(dip, 1,
3315                     "no memory for assigned-addresses property\n");
3316                 return (PCICFG_FAILURE);
3317 
3318         default:
3319                 cardbus_err(dip, 5,
3320                     "cardbus_update_assigned_prop: creating prop\n");
3321                 alen = 0;
3322                 newreg = (caddr_t)newone;
3323                 break;
3324         }
3325 
3326         /*
3327          * Write out the new "assigned-addresses" spec
3328          */
3329         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3330             "assigned-addresses", (int *)newreg,
3331             (alen + sizeof (*newone))/sizeof (int));
3332 
3333         if (status == DDI_PROP_SUCCESS)
3334                 kmem_free((caddr_t)newreg, alen+sizeof (*newone));
3335 
3336         if (alen)
3337                 kmem_free(assigned, alen);
3338 
3339         return (PCICFG_SUCCESS);
3340 }
3341 
3342 static int
3343 cardbus_update_available_prop(dev_info_t *dip, uint32_t hi_type,
3344                                 uint64_t base, uint64_t size)
3345 {
3346         int             alen, rlen;
3347         pci_regspec_t   *available, *reg;
3348         pci_regspec_t   addition;
3349         caddr_t         newreg;
3350         uint_t          status;
3351 
3352         cardbus_err(dip, 6, "cardbus_update_available_prop\n");
3353 
3354         status = ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3355             "reg", (caddr_t)&reg, &rlen);
3356 
3357         switch (status) {
3358         case DDI_PROP_SUCCESS:
3359                 break;
3360         case DDI_PROP_NO_MEMORY:
3361                 cardbus_err(dip, 1, "reg present, but unable to get memory\n");
3362                 return (PCICFG_FAILURE);
3363         default:
3364                 cardbus_err(dip, 1, "no reg property\n");
3365                 return (PCICFG_FAILURE);
3366         }
3367 
3368         status = ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3369             "available", (caddr_t)&available, &alen);
3370         switch (status) {
3371         case DDI_PROP_SUCCESS:
3372                 break;
3373         case DDI_PROP_NO_MEMORY:
3374                 cardbus_err(dip, 1, "no memory for available property\n");
3375                 kmem_free((caddr_t)reg, rlen);
3376                 return (PCICFG_FAILURE);
3377         default:
3378                 alen = 0;
3379         }
3380 
3381         /*
3382          * Allocate memory for the existing
3383          * available(s) plus one and then
3384          * build it.
3385          */
3386         newreg = kmem_zalloc(alen + sizeof (pci_regspec_t), KM_SLEEP);
3387 
3388         /*
3389          * Build the regspec, then add it to the existing one(s)
3390          */
3391         addition.pci_phys_hi = hi_type |
3392             PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3393             PCI_REG_DEV_G(reg->pci_phys_hi),
3394             PCI_REG_FUNC_G(reg->pci_phys_hi), 0);
3395 
3396         addition.pci_phys_mid = (uint32_t)((base>>32) & 0xffffffff);
3397         addition.pci_phys_low = (uint32_t)(base & 0xffffffff);
3398         addition.pci_size_hi = (uint32_t)((size>>32) & 0xffffffff);
3399         addition.pci_size_low = (uint32_t)(size & 0xffffffff);
3400 
3401 #ifdef DEBUG
3402         cardbus_dump_reg(dip, &addition, 1);
3403 #endif
3404 
3405         if (alen)
3406                 bcopy(available, newreg, alen);
3407         bcopy(&addition, newreg + alen, sizeof (pci_regspec_t));
3408 
3409         /*
3410          * Write out the new "available" spec
3411          */
3412         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3413             "available", (int *)newreg,
3414             (alen + sizeof (pci_regspec_t))/sizeof (int));
3415 
3416         if (alen)
3417                 kmem_free((caddr_t)available, alen);
3418         kmem_free((caddr_t)reg, rlen);
3419         kmem_free((caddr_t)newreg, alen + sizeof (pci_regspec_t));
3420 
3421         return (PCICFG_SUCCESS);
3422 }
3423 
3424 static int
3425 cardbus_update_ranges_prop(dev_info_t *dip, cardbus_range_t *addition)
3426 {
3427         int             rlen;
3428         cardbus_range_t *ranges;
3429         caddr_t         newreg;
3430         uint_t          status;
3431 #if defined(CARDBUS_DEBUG)
3432         int     i, nrange;
3433         const cardbus_range_t   *nr;
3434 #endif
3435 
3436         cardbus_err(dip, 6, "cardbus_update_ranges_prop\n");
3437 
3438         status = ddi_getlongprop(DDI_DEV_T_NONE,
3439             dip, DDI_PROP_DONTPASS, "ranges",
3440             (caddr_t)&ranges, &rlen);
3441 
3442         switch (status) {
3443         case DDI_PROP_SUCCESS:
3444                 break;
3445         case DDI_PROP_NO_MEMORY:
3446                 cardbus_err(dip, 1,
3447                     "ranges present, but unable to get memory\n");
3448                 return (PCICFG_FAILURE);
3449         default:
3450                 cardbus_err(dip, 8, "no ranges property - creating one\n");
3451                 if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
3452                     dip, "ranges", (int *)addition,
3453                     sizeof (cardbus_range_t)/sizeof (int))
3454                     != DDI_SUCCESS) {
3455                         cardbus_err(dip, 1, "Did'nt create ranges property\n");
3456                         return (PCICFG_FAILURE);
3457                 }
3458                 return (PCICFG_SUCCESS);
3459         }
3460 
3461         /*
3462          * Allocate memory for the existing reg(s) plus one and then
3463          * build it.
3464          */
3465         newreg = kmem_zalloc(rlen+sizeof (cardbus_range_t), KM_SLEEP);
3466 
3467         bcopy(ranges, newreg, rlen);
3468         bcopy(addition, newreg + rlen, sizeof (cardbus_range_t));
3469 
3470         /*
3471          * Write out the new "ranges" property
3472          */
3473         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3474             dip, "ranges", (int *)newreg,
3475             (rlen + sizeof (cardbus_range_t))/sizeof (int));
3476 
3477 #if defined(CARDBUS_DEBUG)
3478         cardbus_err(dip, 8, "cardbus_update_ranges_prop ranges property:\n");
3479 
3480         nrange = rlen / sizeof (cardbus_range_t);
3481         nr = (cardbus_range_t *)newreg;
3482         for (i = 0; i <= nrange; i++) {
3483                 /* nrange is one higher for new entry */
3484                 cardbus_err(dip, 9,
3485                     "\trange parent addr 0x%x.0x%x.0x%x "
3486                     "child addr 0x%x.0x%x.0x%x size 0x%x.0x%x\n",
3487                     nr->parent_hi,
3488                     nr->parent_mid, nr->parent_lo,
3489                     nr->child_hi,
3490                     nr->child_mid, nr->child_lo,
3491                     nr->size_hi, nr->size_lo);
3492                 nr++;
3493         }
3494 #endif
3495 
3496         kmem_free((caddr_t)newreg, rlen+sizeof (cardbus_range_t));
3497         kmem_free((caddr_t)ranges, rlen);
3498 
3499         return (PCICFG_SUCCESS);
3500 }
3501 
3502 static int
3503 cardbus_update_reg_prop(dev_info_t *dip, uint32_t regvalue, uint_t reg_offset)
3504 {
3505         int     rlen;
3506         pci_regspec_t   *reg;
3507         caddr_t         newreg;
3508         uint32_t        hiword;
3509         pci_regspec_t   addition;
3510         uint32_t        size;
3511         uint_t          status;
3512 
3513         status = ddi_getlongprop(DDI_DEV_T_NONE,
3514             dip, DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &rlen);
3515 
3516         switch (status) {
3517         case DDI_PROP_SUCCESS:
3518                 break;
3519         case DDI_PROP_NO_MEMORY:
3520                 cardbus_err(dip, 1, "reg present, but unable to get memory\n");
3521                 return (PCICFG_FAILURE);
3522         default:
3523                 cardbus_err(dip, 1, "no reg property\n");
3524                 return (PCICFG_FAILURE);
3525         }
3526 
3527         /*
3528          * Allocate memory for the existing reg(s) plus one and then
3529          * build it.
3530          */
3531         newreg = kmem_zalloc(rlen+sizeof (pci_regspec_t), KM_SLEEP);
3532 
3533         /*
3534          * Build the regspec, then add it to the existing one(s)
3535          */
3536         hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3537                         PCI_REG_DEV_G(reg->pci_phys_hi),
3538                         PCI_REG_FUNC_G(reg->pci_phys_hi),
3539                         reg_offset);
3540 
3541         if (reg_offset == PCI_CONF_ROM) {
3542                 size = (~(PCI_BASE_ROM_ADDR_M & regvalue))+1;
3543                 hiword |= PCI_ADDR_MEM32;
3544         } else {
3545                 size = (~(PCI_BASE_M_ADDR_M & regvalue))+1;
3546 
3547                 if ((PCI_BASE_SPACE_M & regvalue) == PCI_BASE_SPACE_MEM) {
3548                         if ((PCI_BASE_TYPE_M & regvalue) == PCI_BASE_TYPE_MEM) {
3549                                 hiword |= PCI_ADDR_MEM32;
3550                         } else if ((PCI_BASE_TYPE_M & regvalue)
3551                                     == PCI_BASE_TYPE_ALL) {
3552                                 /*
3553                                  * This is a 64 bit PCI memory space.
3554                                  * It needs to be allocated as 32 bit
3555                                  * for bus map purposes.
3556                                  */
3557                                 hiword |= PCI_ADDR_MEM32;
3558                         }
3559                 } else {
3560                         hiword |= PCI_ADDR_IO;
3561                 }
3562         }
3563 
3564         addition.pci_phys_hi = hiword;
3565         addition.pci_phys_mid = 0;
3566         addition.pci_phys_low = 0;
3567         addition.pci_size_hi = 0;
3568         addition.pci_size_low = size;
3569 
3570         cardbus_err(dip, 8,
3571             "cardbus_update_reg_prop, phys_hi 0x%08x,"
3572             " phys_mid 0x%08x, phys_low 0x%08x, size_hi 0x%08x,"
3573             " size_low 0x%08x\n", hiword, 0, 0, 0, size);
3574 
3575         bcopy(reg, newreg, rlen);
3576         bcopy(&addition, newreg + rlen, sizeof (pci_regspec_t));
3577 
3578         /*
3579          * Write out the new "reg" property
3580          */
3581         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3582             dip, "reg", (int *)newreg,
3583             (rlen + sizeof (pci_regspec_t))/sizeof (int));
3584 
3585         kmem_free((caddr_t)reg, rlen);
3586         kmem_free((caddr_t)newreg, rlen+sizeof (pci_regspec_t));
3587 
3588         return (PCICFG_SUCCESS);
3589 }
3590 
3591 /*
3592  * Setup the basic 1275 properties based on information found in the config
3593  * header of the PCI device
3594  */
3595 static int
3596 cardbus_set_standard_props(dev_info_t *parent, dev_info_t *dip,
3597                         ddi_acc_handle_t config_handle)
3598 {
3599         int ret;
3600         uint16_t val;
3601         uint32_t wordval;
3602         uint8_t byteval;
3603 
3604         /* These two exists only for non-bridges */
3605         if ((pci_config_get8(config_handle,
3606             PCI_CONF_HEADER) & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) {
3607                 byteval = pci_config_get8(config_handle, PCI_CONF_MIN_G);
3608                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3609                     "min-grant", byteval)) != DDI_SUCCESS) {
3610                         cardbus_err(dip, 1, "Failed to sent min-grant\n");
3611                         return (ret);
3612                 }
3613 
3614                 byteval = pci_config_get8(config_handle, PCI_CONF_MAX_L);
3615                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3616                     "max-latency", byteval)) != DDI_SUCCESS) {
3617                         return (ret);
3618                 }
3619         }
3620 
3621         /*
3622          * These should always exist and have the value of the
3623          * corresponding register value
3624          */
3625         val = pci_config_get16(config_handle, PCI_CONF_VENID);
3626 
3627         /*
3628          * according to section 6.2.1 of revision 2 of the PCI local
3629          * bus specification - 0FFFFh is an invalid value for the vendor ID
3630          */
3631         if (val == 0xffff) {
3632                 cardbus_err(dip, 1, "Illegal vendor-id 0x%x\n", val);
3633                 return (PCICFG_FAILURE);
3634         }
3635         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3636             "vendor-id", val)) != DDI_SUCCESS) {
3637                 return (ret);
3638         }
3639 
3640         val = pci_config_get16(config_handle, PCI_CONF_DEVID);
3641         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3642             "device-id", val)) != DDI_SUCCESS) {
3643                 return (ret);
3644         }
3645         byteval = pci_config_get8(config_handle, PCI_CONF_REVID);
3646         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3647             "revision-id", byteval)) != DDI_SUCCESS) {
3648                 return (ret);
3649         }
3650 
3651         wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3652                 (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3653 
3654         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3655             "class-code", wordval)) != DDI_SUCCESS) {
3656                 return (ret);
3657         }
3658         val = (pci_config_get16(config_handle,
3659             PCI_CONF_STAT) & PCI_STAT_DEVSELT) >> 9;
3660         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3661             "devsel-speed", val)) != DDI_SUCCESS) {
3662                 return (ret);
3663         }
3664 
3665         /*
3666          * The next three are bits set in the status register.  The property is
3667          * present (but with no value other than its own existence) if the bit
3668          * is set, non-existent otherwise
3669          */
3670         if (ddi_prop_exists(DDI_DEV_T_ANY, parent, DDI_PROP_DONTPASS,
3671             "fast-back-to-back") &&
3672             pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_FBBC) {
3673 
3674                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3675                     "fast-back-to-back", 0)) != DDI_SUCCESS) {
3676                         return (ret);
3677                 }
3678         }
3679         if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_66MHZ) {
3680                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3681                     "66mhz-capable", 0)) != DDI_SUCCESS) {
3682                         return (ret);
3683                 }
3684         }
3685         if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_UDF) {
3686                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3687                     "udf-supported", 0)) != DDI_SUCCESS) {
3688                         return (ret);
3689                 }
3690         }
3691 
3692         /*
3693          * These next three are optional and are not present
3694          * if the corresponding register is zero.  If the value
3695          * is non-zero then the property exists with the value
3696          * of the register.
3697          */
3698 
3699         /* look in the correct place for header type 2 */
3700         byteval = pci_config_get8(config_handle, PCI_CONF_HEADER);
3701         if ((byteval & PCI_HEADER_TYPE_M) == PCI_HEADER_TWO) {
3702                 if ((val = pci_config_get16(config_handle,
3703                     PCI_CBUS_SUBVENID)) != 0) {
3704                         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3705                             "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3706                                 return (ret);
3707                         }
3708                 }
3709                 if ((val = pci_config_get16(config_handle,
3710                     PCI_CBUS_SUBSYSID)) != 0) {
3711                         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3712                             "subsystem-id", val)) != DDI_SUCCESS) {
3713                                 return (ret);
3714                         }
3715                 }
3716         } else {
3717                 if ((val = pci_config_get16(config_handle,
3718                     PCI_CONF_SUBVENID)) != 0) {
3719                         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3720                             "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3721                                 return (ret);
3722                         }
3723                 }
3724                 if ((val = pci_config_get16(config_handle,
3725                     PCI_CONF_SUBSYSID)) != 0) {
3726                         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3727                             "subsystem-id", val)) != DDI_SUCCESS) {
3728                                 return (ret);
3729                         }
3730                 }
3731         }
3732 
3733         if ((val = pci_config_get8(config_handle,
3734             PCI_CONF_CACHE_LINESZ)) != 0) {
3735                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3736                     "cache-line-size", val)) != DDI_SUCCESS) {
3737                         return (ret);
3738                 }
3739         }
3740 
3741         /*
3742          * If the Interrupt Pin register is non-zero then the
3743          * interrupts property exists
3744          */
3745         if ((byteval = pci_config_get8(config_handle, PCI_CONF_IPIN)) != 0) {
3746                 /*
3747                  * If interrupt pin is non-zero,
3748                  * record the interrupt line used
3749                  */
3750                 cardbus_err(dip, 8, "Adding interrupts property\n");
3751                 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3752                     "interrupts", byteval)) != DDI_SUCCESS) {
3753                         return (ret);
3754                 }
3755         }
3756         return (PCICFG_SUCCESS);
3757 }
3758 
3759 /*
3760  * Setup the basic properties required by the ISA node.
3761  */
3762 static int
3763 cardbus_set_isa_props(dev_info_t *parent, dev_info_t *dip,
3764                         char *name, char *compat[])
3765 {
3766         int ret, n;
3767 
3768         _NOTE(ARGUNUSED(parent))
3769 
3770         cardbus_err(dip, 8, "Adding interrupts property\n");
3771         if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3772             "interrupts", 1)) != DDI_SUCCESS) {
3773                 return (ret);
3774         }
3775 
3776         /*
3777          * The node name field needs to be filled in with the name
3778          */
3779         if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3780                 cardbus_err(dip, 1, "Failed to set nodename for node\n");
3781                 return (PCICFG_FAILURE);
3782         }
3783 
3784         /*
3785          * Create the compatible property as an array of pointers
3786          * to strings.  Start with the buffer created above.
3787          */
3788         n = 0;
3789         while (compat[n] != NULL)
3790                 n++;
3791 
3792         if (n != 0)
3793                 if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
3794                     "compatible", compat, n)) != DDI_SUCCESS)
3795                         return (ret);
3796 
3797         return (PCICFG_SUCCESS);
3798 }
3799 
3800 static int
3801 cardbus_set_busnode_props(dev_info_t *dip)
3802 {
3803         cardbus_err(dip, 6, "cardbus_set_busnode_props\n");
3804 
3805         cardbus_force_stringprop(dip, "device_type", "pci");
3806 
3807         if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3808             "#address-cells", 3) != DDI_SUCCESS) {
3809                 cardbus_err(dip, 4, "Failed to set #address-cells\n");
3810         }
3811         if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3812             "#size-cells", 2) != DDI_SUCCESS) {
3813                 cardbus_err(dip, 4, "Failed to set #size-cells\n");
3814         }
3815         return (PCICFG_SUCCESS);
3816 }
3817 
3818 static int
3819 cardbus_set_busnode_isaprops(dev_info_t *dip)
3820 {
3821         cardbus_err(dip, 6, "cardbus_set_busnode_props\n");
3822 
3823         cardbus_force_stringprop(dip, "device_type", "isa");
3824 
3825         if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3826             "#address-cells", 2) != DDI_SUCCESS) {
3827                 cardbus_err(dip, 4, "Failed to set #address-cells\n");
3828         }
3829         if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3830             "#size-cells", 1) != DDI_SUCCESS) {
3831                 cardbus_err(dip, 4, "Failed to set #size-cells\n");
3832         }
3833         return (PCICFG_SUCCESS);
3834 }
3835 
3836 /*
3837  * Use cb%x,%x rather than pci%x,%x so that we can use specific cardbus
3838  * drivers in /etc/driver_aliases if required
3839  */
3840 static int
3841 cardbus_set_childnode_props(dev_info_t *dip, ddi_acc_handle_t config_handle)
3842 {
3843         int             ret;
3844 #ifndef _DONT_USE_1275_GENERIC_NAMES
3845         uint32_t        wordval;
3846 #endif
3847         char            *name;
3848         char            buffer[64];
3849         uint32_t        classcode;
3850         char            *compat[8];
3851         int             i, n;
3852         uint16_t        subsysid, subvenid, devid, venid;
3853         uint8_t         header_type;
3854 
3855         /*
3856          * NOTE: These are for both a child and PCI-PCI bridge node
3857          */
3858 #ifndef _DONT_USE_1275_GENERIC_NAMES
3859         wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3860             (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3861 #endif
3862 
3863         /* Cardbus support */
3864         venid = pci_config_get16(config_handle, PCI_CONF_VENID);
3865         devid = pci_config_get16(config_handle, PCI_CONF_DEVID);
3866 
3867         header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
3868         if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_TWO) {
3869                 subvenid = pci_config_get16(config_handle, PCI_CBUS_SUBVENID);
3870                 subsysid = pci_config_get16(config_handle, PCI_CBUS_SUBSYSID);
3871         } else {
3872                 subvenid = pci_config_get16(config_handle, PCI_CONF_SUBVENID);
3873                 subsysid = pci_config_get16(config_handle, PCI_CONF_SUBSYSID);
3874         }
3875 
3876         if (subsysid != 0) {
3877                 (void) sprintf(buffer, "pci%x,%x", subvenid, subsysid);
3878         } else {
3879                 (void) sprintf(buffer, "pci%x,%x", venid, devid);
3880         }
3881 
3882         cardbus_err(dip, 8, "Childname is %s\n", buffer);
3883 
3884         /*
3885          * In some environments, trying to use "generic" 1275 names is
3886          * not the convention.  In those cases use the name as created
3887          * above.  In all the rest of the cases, check to see if there
3888          * is a generic name first.
3889          */
3890 #ifdef _DONT_USE_1275_GENERIC_NAMES
3891         name = buffer;
3892 #else
3893         if ((name = cardbus_get_class_name(wordval>>8)) == NULL) {
3894                 /*
3895                  * Set name to the above fabricated name
3896                  */
3897                 name = buffer;
3898         }
3899 
3900         cardbus_err(dip, 8, "Set nodename to %s\n", name);
3901 #endif
3902 
3903         /*
3904          * The node name field needs to be filled in with the name
3905          */
3906         if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3907                 cardbus_err(dip, 1, "Failed to set nodename for node\n");
3908                 return (PCICFG_FAILURE);
3909         }
3910 
3911         /*
3912          * Create the compatible property as an array of pointers
3913          * to strings.  Start with the cb name.
3914          */
3915         n = 0;
3916 
3917         if (subsysid != 0) {
3918                 (void) sprintf(buffer, "cb%x,%x", subvenid, subsysid);
3919         } else {
3920                 (void) sprintf(buffer, "cb%x,%x", venid, devid);
3921         }
3922 
3923         compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3924         (void) strcpy(compat[n++], buffer);
3925 
3926         if (subsysid != 0) {
3927                 /*
3928                  * Add subsys numbers as pci compatible.
3929                  */
3930                 (void) sprintf(buffer, "pci%x,%x", subvenid, subsysid);
3931                 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3932                 (void) strcpy(compat[n++], buffer);
3933         }
3934 
3935         /*
3936          * Add in the VendorID/DeviceID compatible name.
3937          */
3938         (void) sprintf(buffer, "pci%x,%x", venid, devid);
3939 
3940         compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3941         (void) strcpy(compat[n++], buffer);
3942 
3943         classcode = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3944             (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3945 
3946         /*
3947          * Add in the Classcode
3948          */
3949         (void) sprintf(buffer, "pciclass,%06x", classcode);
3950 
3951         cardbus_err(dip, 8, "class code %s\n", buffer);
3952 
3953         compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3954         (void) strcpy(compat[n++], buffer);
3955 
3956         if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
3957             "compatible", (char **)compat, n)) != DDI_SUCCESS) {
3958                 return (ret);
3959         }
3960 
3961         for (i = 0; i < n; i++) {
3962                 kmem_free(compat[i], strlen(compat[i]) + 1);
3963         }
3964 
3965         return (PCICFG_SUCCESS);
3966 }
3967 
3968 /*
3969  * Program the bus numbers into the bridge
3970  */
3971 static void
3972 cardbus_set_bus_numbers(ddi_acc_handle_t config_handle,
3973                         uint_t primary, uint_t secondary)
3974 {
3975         cardbus_err(NULL, 8,
3976             "cardbus_set_bus_numbers [%d->%d]\n", primary, secondary);
3977 
3978         /*
3979          * Primary bus#
3980          */
3981         pci_config_put8(config_handle, PCI_BCNF_PRIBUS, primary);
3982 
3983         /*
3984          * Secondary bus#
3985          */
3986         pci_config_put8(config_handle, PCI_BCNF_SECBUS, secondary);
3987 
3988         /*
3989          * Set the subordinate bus number to ff in order to pass through any
3990          * type 1 cycle with a bus number higher than the secondary bus#
3991          * Note that this is reduced once the probe is complete in the
3992          * cardbus_setup_bridge() function.
3993          */
3994         pci_config_put8(config_handle, PCI_BCNF_SUBBUS, 0xFF);
3995 }
3996 
3997 static void
3998 enable_pci_isa_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
3999 {
4000         uint16_t comm, stat;
4001 
4002         stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4003         comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4004 
4005         /*
4006          * Enable memory, IO, bus mastership and error detection.
4007          */
4008         comm |= (PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO |
4009             PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
4010         if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
4011             "fast-back-to-back"))
4012                 comm |= PCI_COMM_BACK2BACK_ENAB;
4013         pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4014         cardbus_err(NULL, 8,
4015             "enable_pci_isa_bridge stat 0x%04x comm 0x%04x\n", stat, comm);
4016 
4017         /*
4018          * ITE8888 Specific registers.
4019          */
4020         pci_config_put8(config_handle, 0x50, 0x00); /* Timing Control */
4021         pci_config_put8(config_handle, 0x52, 0x00); /* Master DMA Access */
4022         pci_config_put8(config_handle, 0x53, 0x01); /* ROMCS */
4023 }
4024 
4025 static void
4026 enable_pci_pci_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4027 {
4028         uint16_t comm, stat, bctrl;
4029 
4030         stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4031         comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4032         bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4033 
4034         comm &= ~(PCI_COMM_IO | PCI_COMM_MAE);
4035         comm |= (PCI_COMM_ME | PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
4036 
4037         /*
4038          * Enable back to back.
4039          */
4040         if (stat & PCI_STAT_FBBC)
4041                 comm |= PCI_COMM_BACK2BACK_ENAB;
4042 
4043         pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4044 
4045         /*
4046          * Reset the sub-ordinate bus.
4047          */
4048         if (!(bctrl & PCI_BCNF_BCNTRL_RESET))
4049                 pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL,
4050                         bctrl | PCI_BCNF_BCNTRL_RESET);
4051         else
4052                 bctrl &= ~PCI_BCNF_BCNTRL_RESET;
4053 
4054         /*
4055          * Enable error reporting.
4056          */
4057         bctrl |= (PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE |
4058             PCI_BCNF_BCNTRL_MAST_AB_MODE);
4059 
4060         /*
4061          * Enable back to back on secondary bus.
4062          */
4063         if (stat & PCI_STAT_FBBC)
4064                 bctrl |= PCI_BCNF_BCNTRL_B2B_ENAB;
4065 
4066         pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4067         cardbus_err(dip, 8,
4068             "enable_pci_pci_bridge stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4069             stat, comm, bctrl);
4070 }
4071 
4072 static int      cardbus_reset_wait = 20;
4073 
4074 static void
4075 enable_cardbus_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4076 {
4077         uint16_t comm, stat, bctrl;
4078 
4079         stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4080         comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4081         bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4082 
4083         /*
4084          * Don't mess with the command register on the cardbus bridge
4085          * itself. This should have been done when it's parent
4086          * did the setup. Some devices *require* certain things to
4087          * disabled, this can be done using the "command-preserve"
4088          * property and if we mess with it here it breaks that.
4089          *
4090          * comm |= (PCI_COMM_ME | PCI_COMM_PARITY_DETECT |
4091          *      PCI_COMM_SERR_ENABLE);
4092          */
4093 
4094         /*
4095          * Reset the sub-ordinate bus.
4096          */
4097         if (!(bctrl & PCI_BCNF_BCNTRL_RESET))
4098                 pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL,
4099                         bctrl | PCI_BCNF_BCNTRL_RESET);
4100         else
4101                 bctrl &= ~PCI_BCNF_BCNTRL_RESET;
4102 
4103         /*
4104          * Turn off pre-fetch.
4105          */
4106         bctrl &= ~(CB_BCNF_BCNTRL_MEM0_PREF | CB_BCNF_BCNTRL_MEM1_PREF |
4107             PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE);
4108 
4109         /*
4110          * Enable error reporting.
4111          */
4112         bctrl |= (PCI_BCNF_BCNTRL_MAST_AB_MODE | CB_BCNF_BCNTRL_WRITE_POST);
4113         if (comm & PCI_COMM_PARITY_DETECT)
4114                 bctrl |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
4115         if (comm & PCI_COMM_SERR_ENABLE)
4116                 bctrl |= PCI_BCNF_BCNTRL_SERR_ENABLE;
4117 
4118         pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4119         pci_config_put8(config_handle, PCI_CBUS_LATENCY_TIMER,
4120             cardbus_latency_timer);
4121 
4122         pci_config_put16(config_handle, PCI_CONF_STAT, stat);
4123         pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4124 
4125         cardbus_err(dip, 8,
4126             "enable_cardbus_bridge() stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4127             stat, comm, bctrl);
4128 
4129         /* after resetting the bridge, wait for everything to stablize */
4130         delay(drv_usectohz(cardbus_reset_wait * 1000));
4131 
4132 }
4133 
4134 static void
4135 disable_pci_pci_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4136 {
4137         uint16_t comm, bctrl;
4138 
4139         comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4140         bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4141 
4142         /*
4143          * Turn off subordinate bus access.
4144          */
4145         pci_config_put8(config_handle, PCI_BCNF_SECBUS, 0);
4146         pci_config_put8(config_handle, PCI_BCNF_SUBBUS, 0);
4147 
4148         /*
4149          * Disable error reporting.
4150          */
4151         bctrl &= ~(PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE |
4152             PCI_BCNF_BCNTRL_MAST_AB_MODE);
4153         comm = 0;
4154 
4155         pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4156         pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4157 
4158         cardbus_err(dip, 6,
4159             "disable_pci_pci_bridge() stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4160             pci_config_get16(config_handle, PCI_CONF_STAT), comm, bctrl);
4161 }
4162 
4163 static void
4164 disable_cardbus_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4165 {
4166         uint16_t comm, bctrl;
4167 
4168         comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4169         bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4170 
4171         /*
4172          * Turn off subordinate bus access.
4173          */
4174         pci_config_put8(config_handle, PCI_BCNF_SECBUS, 0);
4175         pci_config_put8(config_handle, PCI_BCNF_SUBBUS, 0);
4176 
4177         /*
4178          * Disable error reporting.
4179          */
4180         bctrl &= ~(PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE |
4181             PCI_BCNF_BCNTRL_MAST_AB_MODE);
4182 
4183         pci_config_put32(config_handle, PCI_CBUS_MEM_LIMIT0, 0);
4184         pci_config_put32(config_handle, PCI_CBUS_MEM_BASE0, 0);
4185         pci_config_put32(config_handle, PCI_CBUS_IO_LIMIT0, 0);
4186         pci_config_put32(config_handle, PCI_CBUS_IO_BASE0, 0);
4187         pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4188         pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4189 
4190         cardbus_err(dip, 6,
4191             "disable_cardbus_bridge() stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4192             pci_config_get16(config_handle, PCI_CONF_STAT), comm, bctrl);
4193 }
4194 
4195 static void
4196 enable_cardbus_device(dev_info_t *dip, ddi_acc_handle_t config_handle)
4197 {
4198         uint16_t comm, stat;
4199 
4200         stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4201         comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4202 
4203         /*
4204          * Enable memory, IO, bus mastership and error detection.
4205          */
4206         comm |= (PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO |
4207             PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
4208         if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
4209             "fast-back-to-back"))
4210                 comm |= PCI_COMM_BACK2BACK_ENAB;
4211         pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4212         cardbus_err(NULL, 8,
4213             "enable_cardbus_device stat 0x%04x comm 0x%04x\n", stat, comm);
4214 }
4215 
4216 static void
4217 disable_cardbus_device(ddi_acc_handle_t config_handle)
4218 {
4219         cardbus_err(NULL, 8, "disable_cardbus_device\n");
4220 
4221         /*
4222          * Turn off everything in the command register.
4223          */
4224         pci_config_put16(config_handle, PCI_CONF_COMM, 0x0);
4225 }
4226 
4227 #ifndef _DONT_USE_1275_GENERIC_NAMES
4228 static char *
4229 cardbus_get_class_name(uint32_t classcode)
4230 {
4231         struct cardbus_name_entry *ptr;
4232 
4233         for (ptr = &cardbus_class_lookup[0]; ptr->name != NULL; ptr++) {
4234                 if (ptr->class_code == classcode) {
4235                         return (ptr->name);
4236                 }
4237         }
4238         return (NULL);
4239 }
4240 #endif /* _DONT_USE_1275_GENERIC_NAMES */
4241 
4242 static void
4243 cardbus_force_boolprop(dev_info_t *dip, char *pname)
4244 {
4245         int ret;
4246 
4247         if ((ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
4248             pname)) != DDI_SUCCESS) {
4249                 if (ret == DDI_PROP_NOT_FOUND)
4250                         if (ddi_prop_create(DDI_DEV_T_NONE, dip,
4251                             DDI_PROP_CANSLEEP, pname,
4252                             (caddr_t)NULL, 0) != DDI_SUCCESS)
4253                                 cardbus_err(dip, 4,
4254                                     "Failed to set boolean property "
4255                                     "\"%s\"\n", pname);
4256         }
4257 }
4258 
4259 static void
4260 cardbus_force_intprop(dev_info_t *dip, char *pname, int *pval, int len)
4261 {
4262         int ret;
4263 
4264         if ((ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
4265             pname, pval, len)) != DDI_SUCCESS) {
4266                 if (ret == DDI_PROP_NOT_FOUND)
4267                         if (ddi_prop_create(DDI_DEV_T_NONE, dip,
4268                             DDI_PROP_CANSLEEP, pname,
4269                             (caddr_t)pval, len*sizeof (int))
4270                             != DDI_SUCCESS)
4271                                 cardbus_err(dip, 4,
4272                                     "Failed to set int property \"%s\"\n",
4273                                     pname);
4274         }
4275 }
4276 
4277 static void
4278 cardbus_force_stringprop(dev_info_t *dip, char *pname, char *pval)
4279 {
4280         int ret;
4281 
4282         if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
4283             pname, pval)) != DDI_SUCCESS) {
4284                 if (ret == DDI_PROP_NOT_FOUND)
4285                         if (ddi_prop_create(DDI_DEV_T_NONE, dip,
4286                             DDI_PROP_CANSLEEP, pname,
4287                             pval, strlen(pval) + 1) != DDI_SUCCESS)
4288                                 cardbus_err(dip, 4,
4289                                     "Failed to set string property "
4290                                     "\"%s\" to \"%s\"\n",
4291                                     pname, pval);
4292         }
4293 }
4294 
4295 static void
4296 split_addr(char *naddr, int *dev, int *func)
4297 {
4298         char    c;
4299         int     *ip = dev;
4300 
4301         *dev = 0;
4302         *func = 0;
4303 
4304         while (c = *naddr++) {
4305                 if (c == ',') {
4306                         ip = func;
4307                         continue;
4308                 }
4309                 if (c >= '0' && c <= '9') {
4310                         *ip = (*ip * 16) + (c - '0');
4311                 } else if (c >= 'a' && c <= 'f') {
4312                         *ip = (*ip * 16) + 10 + (c - 'a');
4313                 } else
4314                         break;
4315         }
4316 }
4317 
4318 #ifdef DEBUG
4319 static void
4320 cardbus_dump_common_config(ddi_acc_handle_t config_handle)
4321 {
4322         cardbus_err(NULL, 1,
4323             " Vendor ID   = [0x%04x]        "
4324             "Device ID   = [0x%04x]\n",
4325             pci_config_get16(config_handle, PCI_CONF_VENID),
4326             pci_config_get16(config_handle, PCI_CONF_DEVID));
4327         cardbus_err(NULL, 1,
4328             " Command REG = [0x%04x]        "
4329             "Status  REG = [0x%04x]\n",
4330             pci_config_get16(config_handle, PCI_CONF_COMM),
4331             pci_config_get16(config_handle, PCI_CONF_STAT));
4332         cardbus_err(NULL, 1,
4333             " Revision ID = [0x%02x]          "
4334             "Prog Class  = [0x%02x]\n",
4335             pci_config_get8(config_handle, PCI_CONF_REVID),
4336             pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
4337         cardbus_err(NULL, 1,
4338             " Dev Class   = [0x%02x]          "
4339             "Base Class  = [0x%02x]\n",
4340             pci_config_get8(config_handle, PCI_CONF_SUBCLASS),
4341             pci_config_get8(config_handle, PCI_CONF_BASCLASS));
4342         cardbus_err(NULL, 1,
4343             " Cache LnSz  = [0x%02x]          "
4344             "Latency Tmr = [0x%02x]\n",
4345             pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ),
4346             pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER));
4347         cardbus_err(NULL, 1,
4348             " Header Type = [0x%02x]          "
4349             "BIST        = [0x%02x]\n",
4350             pci_config_get8(config_handle, PCI_CONF_HEADER),
4351             pci_config_get8(config_handle, PCI_CONF_BIST));
4352 }
4353 
4354 static void
4355 cardbus_dump_device_config(ddi_acc_handle_t config_handle)
4356 {
4357         cardbus_dump_common_config(config_handle);
4358 
4359         cardbus_err(NULL, 1,
4360             " BASE 0      = [0x%08x]    BASE 1      = [0x%08x]\n",
4361             pci_config_get32(config_handle, PCI_CONF_BASE0),
4362             pci_config_get32(config_handle, PCI_CONF_BASE1));
4363         cardbus_err(NULL, 1,
4364             " BASE 2      = [0x%08x]    BASE 3      = [0x%08x]\n",
4365             pci_config_get32(config_handle, PCI_CONF_BASE2),
4366             pci_config_get32(config_handle, PCI_CONF_BASE3));
4367         cardbus_err(NULL, 1,
4368             " BASE 4      = [0x%08x]    BASE 5      = [0x%08x]\n",
4369             pci_config_get32(config_handle, PCI_CONF_BASE4),
4370             pci_config_get32(config_handle, PCI_CONF_BASE5));
4371         cardbus_err(NULL, 1,
4372             " Cardbus CIS = [0x%08x]    ROM         = [0x%08x]\n",
4373             pci_config_get32(config_handle, PCI_CONF_CIS),
4374             pci_config_get32(config_handle, PCI_CONF_ROM));
4375         cardbus_err(NULL, 1,
4376             " Sub VID     = [0x%04x]    Sub SID     = [0x%04x]\n",
4377             pci_config_get16(config_handle, PCI_CONF_SUBVENID),
4378             pci_config_get16(config_handle, PCI_CONF_SUBSYSID));
4379         cardbus_err(NULL, 1,
4380             " I Line      = [0x%02x]    I Pin       = [0x%02x]\n",
4381             pci_config_get8(config_handle, PCI_CONF_ILINE),
4382             pci_config_get8(config_handle, PCI_CONF_IPIN));
4383         cardbus_err(NULL, 1,
4384             " Max Grant   = [0x%02x]    Max Latent  = [0x%02x]\n",
4385             pci_config_get8(config_handle, PCI_CONF_MIN_G),
4386             pci_config_get8(config_handle, PCI_CONF_MAX_L));
4387 }
4388 
4389 static void
4390 cardbus_dump_bridge_config(ddi_acc_handle_t config_handle,
4391                         uint8_t header_type)
4392 {
4393         if (header_type == PCI_HEADER_PPB) {
4394                 cardbus_dump_common_config(config_handle);
4395                 cardbus_err(NULL, 1,
4396                     "........................................\n");
4397         } else {
4398                 cardbus_dump_common_config(config_handle);
4399                 cardbus_err(NULL, 1,
4400                     " Mem Base    = [0x%08x]    CBus Status = [0x%04x]\n",
4401                     pci_config_get32(config_handle, PCI_CBUS_SOCK_REG),
4402                     pci_config_get16(config_handle, PCI_CBUS_SEC_STATUS));
4403         }
4404 
4405         cardbus_err(NULL, 1,
4406             " Pri Bus   = [0x%02x]              Sec Bus = [0x%02x]\n",
4407             pci_config_get8(config_handle, PCI_BCNF_PRIBUS),
4408             pci_config_get8(config_handle, PCI_BCNF_SECBUS));
4409         cardbus_err(NULL, 1,
4410             " Sub Bus     = [0x%02x]            Sec Latency = [0x%02x]\n",
4411             pci_config_get8(config_handle, PCI_BCNF_SUBBUS),
4412             pci_config_get8(config_handle, PCI_BCNF_LATENCY_TIMER));
4413 
4414         switch (header_type) {
4415         case PCI_HEADER_PPB:
4416                 cardbus_err(NULL, 1,
4417                     " I/O Base LO = [0x%02x]    I/O Lim LO  = [0x%02x]\n",
4418                     pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW),
4419                     pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW));
4420                 cardbus_err(NULL, 1,
4421                     " Sec. Status = [0x%04x]\n",
4422                     pci_config_get16(config_handle, PCI_BCNF_SEC_STATUS));
4423                 cardbus_err(NULL, 1,
4424                     " Mem Base    = [0x%04x]    Mem Limit   = [0x%04x]\n",
4425                     pci_config_get16(config_handle, PCI_BCNF_MEM_BASE),
4426                     pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT));
4427                 cardbus_err(NULL, 1,
4428                     " PF Mem Base = [0x%04x]    PF Mem Lim  = [0x%04x]\n",
4429                     pci_config_get16(config_handle, PCI_BCNF_PF_BASE_LOW),
4430                     pci_config_get16(config_handle, PCI_BCNF_PF_LIMIT_LOW));
4431                 cardbus_err(NULL, 1,
4432                     " PF Base HI  = [0x%08x]    PF Lim  HI  = [0x%08x]\n",
4433                     pci_config_get32(config_handle, PCI_BCNF_PF_BASE_HIGH),
4434                     pci_config_get32(config_handle, PCI_BCNF_PF_LIMIT_HIGH));
4435                 cardbus_err(NULL, 1,
4436                     " I/O Base HI = [0x%04x]    I/O Lim HI  = [0x%04x]\n",
4437                     pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI),
4438                     pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI));
4439                 cardbus_err(NULL, 1,
4440                     " ROM addr    = [0x%08x]\n",
4441                     pci_config_get32(config_handle, PCI_BCNF_ROM));
4442                 break;
4443         case PCI_HEADER_CARDBUS:
4444                 cardbus_err(NULL, 1,
4445                     " Mem Base 0  = [0x%08x]    Mem Limit 0 = [0x%08x]\n",
4446                     pci_config_get32(config_handle, PCI_CBUS_MEM_BASE0),
4447                     pci_config_get32(config_handle, PCI_CBUS_MEM_LIMIT0));
4448                 cardbus_err(NULL, 1,
4449                     " Mem Base 1  = [0x%08x]    Mem Limit 1 = [0x%08x]\n",
4450                     pci_config_get32(config_handle, PCI_CBUS_MEM_BASE1),
4451                     pci_config_get32(config_handle, PCI_CBUS_MEM_LIMIT1));
4452                 cardbus_err(NULL, 1,
4453                     " IO Base 0   = [0x%08x]    IO Limit 0  = [0x%08x]\n",
4454                     pci_config_get32(config_handle, PCI_CBUS_IO_BASE0),
4455                     pci_config_get32(config_handle, PCI_CBUS_IO_LIMIT0));
4456                 cardbus_err(NULL, 1,
4457                     " IO Base 1   = [0x%08x]    IO Limit 1  = [0x%08x]\n",
4458                     pci_config_get32(config_handle, PCI_CBUS_IO_BASE1),
4459                     pci_config_get32(config_handle, PCI_CBUS_IO_LIMIT1));
4460                 break;
4461         }
4462         cardbus_err(NULL, 1,
4463             " Intr Line   = [0x%02x]            Intr Pin    = [0x%02x]\n",
4464             pci_config_get8(config_handle, PCI_BCNF_ILINE),
4465             pci_config_get8(config_handle, PCI_BCNF_IPIN));
4466         cardbus_err(NULL, 1,
4467             " Bridge Ctrl = [0x%04x]\n",
4468             pci_config_get16(config_handle, PCI_BCNF_BCNTRL));
4469 
4470         switch (header_type) {
4471         case PCI_HEADER_CARDBUS:
4472                 cardbus_err(NULL, 1,
4473                     " Sub VID     = [0x%04x]    Sub SID     = [0x%04x]\n",
4474                     pci_config_get16(config_handle, PCI_CBUS_SUBVENID),
4475                     pci_config_get16(config_handle, PCI_CBUS_SUBSYSID));
4476                 /* LATER: TI1250 only */
4477                 cardbus_err(NULL, 1,
4478                     " Sys Control = [0x%08x]\n",
4479                     pci_config_get32(config_handle, 0x80));
4480         }
4481 }
4482 
4483 static void
4484 cardbus_dump_config(ddi_acc_handle_t config_handle)
4485 {
4486         uint8_t header_type = pci_config_get8(config_handle,
4487             PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
4488 
4489         if (header_type == PCI_HEADER_PPB || header_type == PCI_HEADER_CARDBUS)
4490                 cardbus_dump_bridge_config(config_handle, header_type);
4491         else
4492                 cardbus_dump_device_config(config_handle);
4493 }
4494 
4495 static void
4496 cardbus_dump_reg(dev_info_t *dip, const pci_regspec_t *regspec, int nelems)
4497 {
4498         /* int rlen = nelems * sizeof(pci_regspec_t); */
4499 
4500         cardbus_err(dip, 6,
4501             "cardbus_dump_reg: \"reg\" has %d elements\n", nelems);
4502 
4503 #if defined(CARDBUS_DEBUG)
4504         if (cardbus_debug >= 1) {
4505                 int     i;
4506                 uint32_t *regs = (uint32_t *)regspec;
4507 
4508                 for (i = 0; i < nelems; i++) {
4509 
4510                         cardbus_err(NULL, 6,
4511                             "\t%d:%08x %08x %08x %08x %08x\n",
4512                             i, regs[0], regs[1], regs[2], regs[3], regs[4]);
4513                 }
4514         }
4515 #endif
4516 }
4517 
4518 #endif
4519 
4520 #if defined(CARDBUS_DEBUG)
4521 void
4522 cardbus_dump_children(dev_info_t *dip, int level)
4523 {
4524         dev_info_t *next;
4525 
4526         cardbus_err(dip, 1,
4527             "\t%d: %s: 0x%p\n", level, ddi_node_name(dip), (void *) dip);
4528         for (next = ddi_get_child(dip); next;
4529             next = ddi_get_next_sibling(next))
4530                 cardbus_dump_children(next, level + 1);
4531 }
4532 
4533 void
4534 cardbus_dump_family_tree(dev_info_t *dip)
4535 {
4536         cardbus_err(dip, 1, "0x%p family tree:\n", (void *) dip);
4537         cardbus_dump_children(dip, 1);
4538 }
4539 #endif