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 /*
  27  * Copyright (c)  * Copyright (c) 2001 Tadpole Technology plc
  28  * All rights reserved.
  29  * From "@(#)pcicfg.c   1.31    99/06/18 SMI"
  30  */
  31 
  32 /*
  33  * Cardbus module
  34  */
  35 
  36 #include <sys/conf.h>
  37 #include <sys/modctl.h>
  38 
  39 #include <sys/pci.h>
  40 
  41 #include <sys/ddi.h>
  42 #include <sys/sunndi.h>
  43 #include <sys/ddi_impldefs.h>
  44 
  45 #include <sys/hotplug/hpcsvc.h>
  46 
  47 #include <sys/pctypes.h>
  48 #include <sys/pcmcia.h>
  49 #include <sys/sservice.h>
  50 #include <sys/note.h>
  51 
  52 #include <sys/pci/pci_types.h>
  53 #include <sys/pci/pci_sc.h>
  54 
  55 #include <sys/pcic_reg.h>
  56 #include <sys/pcic_var.h>
  57 #include <sys/pcmcia.h>
  58 
  59 #ifdef sparc
  60 #include <sys/ddi_subrdefs.h>
  61 #elif defined(__x86) || defined(__amd64)
  62 #include <sys/pci_intr_lib.h>
  63 #include <sys/mach_intr.h>
  64 #endif
  65 
  66 #include "cardbus.h"
  67 #include "cardbus_parse.h"
  68 #include "cardbus_hp.h"
  69 #include "cardbus_cfg.h"
  70 
  71 static int cardbus_command_default = PCI_COMM_SERR_ENABLE |
  72                                 PCI_COMM_WAIT_CYC_ENAB |
  73                                 PCI_COMM_PARITY_DETECT |
  74                                 PCI_COMM_ME | PCI_COMM_MAE |
  75                                 PCI_COMM_IO;
  76 
  77 static int cardbus_next_instance = 0;
  78 static int cardbus_count = 0;
  79 int number_of_cardbus_cards = 0;
  80 
  81 static int cardbus_bus_map(dev_info_t *dip, dev_info_t *rdip,
  82                 ddi_map_req_t *mp, off_t offset, off_t len, caddr_t *vaddrp);
  83 static void pcirp2rp(const pci_regspec_t *pci_rp, struct regspec *rp);
  84 
  85 static int cardbus_ctlops(dev_info_t *, dev_info_t *,
  86                         ddi_ctl_enum_t, void *arg, void *);
  87 static void cardbus_init_child_regs(dev_info_t *child);
  88 static int cardbus_initchild(dev_info_t *, dev_info_t *,
  89                         dev_info_t *, void *);
  90 static int cardbus_name_child(dev_info_t *, char *, int);
  91 static void cardbus_removechild(dev_info_t *dip);
  92 
  93 static int cardbus_dma_allochdl(dev_info_t *dip, dev_info_t *rdip,
  94                 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg,
  95                 ddi_dma_handle_t *handlep);
  96 static int cardbus_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
  97                 ddi_dma_handle_t handle);
  98 static int cardbus_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
  99                 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
 100                 ddi_dma_cookie_t *cp, uint_t *ccountp);
 101 static int cardbus_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
 102                 ddi_dma_handle_t handle);
 103 static int cardbus_dma_flush(dev_info_t *dip, dev_info_t *rdip,
 104                 ddi_dma_handle_t handle, off_t off, size_t len,
 105                 uint_t cache_flags);
 106 static int cardbus_dma_win(dev_info_t *dip, dev_info_t *rdip,
 107                 ddi_dma_handle_t handle, uint_t win, off_t *offp,
 108                 size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp);
 109 static int cardbus_dma_map(dev_info_t *dip, dev_info_t *rdip,
 110                 struct ddi_dma_req *dmareqp, ddi_dma_handle_t *handlep);
 111 
 112 static int cardbus_prop_op(dev_t dev, dev_info_t *dip, dev_info_t *ch_dip,
 113                 ddi_prop_op_t prop_op, int mod_flags,
 114                 char *name, caddr_t valuep, int *lengthp);
 115 
 116 static int cardbus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
 117                 char *eventname, ddi_eventcookie_t *cookiep);
 118 static int cardbus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
 119                 ddi_eventcookie_t cookie, void (*callback)(dev_info_t *dip,
 120                 ddi_eventcookie_t cookie, void *arg, void *bus_impldata),
 121                 void *arg, ddi_callback_id_t *cb_id);
 122 static int cardbus_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id);
 123 static int cardbus_post_event(dev_info_t *dip, dev_info_t *rdip,
 124                 ddi_eventcookie_t cookie, void *bus_impldata);
 125 
 126 static int cardbus_intr_ops(dev_info_t *dip, dev_info_t *rdip,
 127                 ddi_intr_op_t intr_op,
 128                 ddi_intr_handle_impl_t *hdlp, void *result);
 129 
 130 static int check_token(char *token, int *len);
 131 static char *find_token(char **cp, int *l, char *endc);
 132 static int parse_token(char *token);
 133 static int token_to_hex(char *token, unsigned *val, int len);
 134 static int token_to_dec(char *token, unsigned *val, int len);
 135 static void cardbus_add_prop(struct cb_deviceset_props *cdsp, int type,
 136                 char *name, caddr_t vp, int len);
 137 static void cardbus_add_stringprop(struct cb_deviceset_props *cdsp,
 138                 char *name, char *vp, int len);
 139 static void cardbus_prop_free(ddi_prop_t *propp);
 140 static void cardbus_devprops_free(struct cb_deviceset_props *cbdp);
 141 static int cardbus_parse_devprop(cbus_t *cbp, char *cp);
 142 static void cardbus_device_props(cbus_t *cbp);
 143 
 144 static void cardbus_expand_busrange(dev_info_t *dip);
 145 
 146 static int cardbus_convert_properties(dev_info_t *dip);
 147 static void cardbus_revert_properties(dev_info_t *dip);
 148 
 149 /*
 150  * driver global data
 151  */
 152 kmutex_t cardbus_list_mutex; /* Protects the probe handle list */
 153 void *cardbus_state;
 154 int cardbus_latency_timer = 0x40;
 155 int cardbus_debug = 0;
 156 
 157 /*
 158  * Module linkage information for the kernel.
 159  */
 160 extern struct mod_ops mod_miscops;
 161 static struct modlmisc modlmisc = {
 162         &mod_miscops,
 163         "Cardbus Configurator support",
 164 };
 165 
 166 static struct modlinkage modlinkage = {
 167         MODREV_1,
 168         { &modlmisc, NULL }
 169 };
 170 
 171 int
 172 _init(void)
 173 {
 174         int error;
 175 
 176         error =  ddi_soft_state_init(&cardbus_state, sizeof (cbus_t), 0);
 177         if (error != 0)
 178                 return (error);
 179 
 180         mutex_init(&cardbus_list_mutex, NULL, MUTEX_DRIVER, NULL);
 181         if ((error = mod_install(&modlinkage)) != 0) {
 182                 mutex_destroy(&cardbus_list_mutex);
 183         }
 184 
 185         return (error);
 186 }
 187 
 188 int
 189 _fini(void)
 190 {
 191         int error;
 192         if ((error = mod_remove(&modlinkage)) == 0) {
 193                 mutex_destroy(&cardbus_list_mutex);
 194                 ddi_soft_state_fini(&cardbus_state);
 195         }
 196         return (error);
 197 }
 198 
 199 int
 200 _info(struct modinfo *modinfop)
 201 {
 202         return (mod_info(&modlinkage, modinfop));
 203 }
 204 
 205 static
 206 struct bus_ops cardbusbus_ops = {
 207         BUSO_REV,
 208         cardbus_bus_map,
 209         NULL,
 210         NULL,
 211         NULL,
 212         i_ddi_map_fault,
 213         cardbus_dma_map,
 214         cardbus_dma_allochdl,
 215         cardbus_dma_freehdl,
 216         cardbus_dma_bindhdl,
 217         cardbus_dma_unbindhdl,
 218         cardbus_dma_flush,
 219         cardbus_dma_win,
 220         ddi_dma_mctl,
 221         cardbus_ctlops,                 /* (*bus_ctl)();                */
 222         cardbus_prop_op,
 223         cardbus_get_eventcookie,        /* (*bus_get_eventcookie)();    */
 224         cardbus_add_eventcall,          /* (*bus_add_eventcall)();      */
 225         cardbus_remove_eventcall,       /* (*bus_remove_eventcall)();   */
 226         cardbus_post_event,             /* (*bus_post_event)();         */
 227         NULL,                           /* (*bus_intr_ctl)();           */
 228         NULL,                           /* (*bus_config)();             */
 229         NULL,                           /* (*bus_unconfig)();           */
 230         NULL,                           /* (*bus_fm_init)();            */
 231         NULL,                           /* (*bus_fm_fini)();            */
 232         NULL,                           /* (*bus_enter)();              */
 233         NULL,                           /* (*bus_exit)();               */
 234         NULL,                           /* (*bus_power)();              */
 235         cardbus_intr_ops                /* (*bus_intr_op)();            */
 236 };
 237 
 238 #define CB_EVENT_TAG_INSERT     0
 239 #define CB_EVENT_TAG_REMOVE     1
 240 
 241 static ndi_event_definition_t cb_ndi_event_defs[] = {
 242         { CB_EVENT_TAG_INSERT, DDI_DEVI_INSERT_EVENT, EPL_INTERRUPT, 0 },
 243         { CB_EVENT_TAG_REMOVE, DDI_DEVI_REMOVE_EVENT, EPL_INTERRUPT, 0 }
 244 };
 245 
 246 #define CB_N_NDI_EVENTS \
 247         (sizeof (cb_ndi_event_defs) / sizeof (cb_ndi_event_defs[0]))
 248 
 249 #ifdef sparc
 250 struct busnum_ctrl {
 251         int     rv;
 252         dev_info_t *dip;
 253         cardbus_bus_range_t *range;
 254 };
 255 
 256 static int
 257 cardbus_claim_pci_busnum(dev_info_t *dip, void *arg)
 258 {
 259         cardbus_bus_range_t pci_bus_range;
 260         struct busnum_ctrl *ctrl;
 261         ndi_ra_request_t req;
 262         char bus_type[16] = "(unknown)";
 263         int len;
 264         uint64_t base;
 265         uint64_t retlen;
 266 
 267         ctrl = (struct busnum_ctrl *)arg;
 268 
 269         /* check if this is a PCI bus node */
 270         len = sizeof (bus_type);
 271         if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
 272             DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
 273             "device_type",
 274             (caddr_t)&bus_type, &len) != DDI_SUCCESS)
 275                 return (0);     /* (DDI_WALK_PRUNECHILD); */
 276 
 277         if ((strcmp(bus_type, "pci") != 0) &&
 278             (strcmp(bus_type, "pciex") != 0)) /* it is not a pci bus type */
 279                 return (0);     /* (DDI_WALK_PRUNECHILD); */
 280 
 281         /* look for the bus-range property */
 282         len = sizeof (struct cardbus_bus_range);
 283         if (ddi_getlongprop_buf(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
 284             "bus-range", (caddr_t)&pci_bus_range, &len) == DDI_SUCCESS) {
 285                 cardbus_err(dip, 1, "cardbus_claim_pci_busnum: %u -> %u \n",
 286                     pci_bus_range.lo, pci_bus_range.hi);
 287                 if ((pci_bus_range.lo >= ctrl->range->lo) &&
 288                     (pci_bus_range.hi <= ctrl->range->hi)) {
 289                         cardbus_err(dip, 1,
 290                             "cardbus_claim_pci_busnum: claim %u -> %u \n",
 291                             pci_bus_range.lo, pci_bus_range.hi);
 292 
 293                         /* claim the bus range from the bus resource map */
 294                         bzero((caddr_t)&req, sizeof (req));
 295                         req.ra_addr = (uint64_t)pci_bus_range.lo;
 296                         req.ra_flags |= NDI_RA_ALLOC_SPECIFIED;
 297                         req.ra_len = (uint64_t)pci_bus_range.hi -
 298                             (uint64_t)pci_bus_range.lo + 1;
 299 
 300                         if (ndi_ra_alloc(ctrl->dip, &req, &base, &retlen,
 301                             NDI_RA_TYPE_PCI_BUSNUM, 0) == NDI_SUCCESS)
 302                                 return (0);     /* (DDI_WALK_PRUNECHILD); */
 303                 }
 304         }
 305 
 306         /*
 307          * never Error return.
 308          */
 309         ctrl->rv = DDI_SUCCESS;
 310         return (DDI_WALK_TERMINATE);
 311 }
 312 
 313 static void
 314 cardbus_walk_node_child(dev_info_t *parent,
 315         int (*f)(dev_info_t *, void *), void *arg)
 316 {
 317         dev_info_t *dip;
 318         int ret;
 319 
 320         for (dip = ddi_get_child(parent); dip;
 321             dip = ddi_get_next_sibling(dip)) {
 322 
 323                 ret = (*f) (dip, arg);
 324                 if (ret)
 325                         return;
 326         }
 327 }
 328 
 329 static void cardbus_fix_hostbridge_busrange(dev_info_t *dip)
 330 {
 331         cardbus_bus_range_t bus_range;
 332         struct busnum_ctrl ctrl;
 333 
 334         uint64_t next_bus;
 335         uint64_t blen;
 336         ndi_ra_request_t req;
 337         int     len;
 338 
 339         cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange\n");
 340 
 341         bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
 342         req.ra_len = 1;
 343         if (ndi_ra_alloc(dip, &req,
 344             &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
 345             0) != NDI_SUCCESS) {
 346                 (void) ndi_ra_map_destroy(dip, NDI_RA_TYPE_PCI_BUSNUM);
 347 
 348                 if (ndi_ra_map_setup(dip, NDI_RA_TYPE_PCI_BUSNUM)
 349                     == NDI_FAILURE) {
 350                         cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange "
 351                             "NDI_RA_TYPE_PCI_BUSNUM setup fail\n");
 352                         return;
 353                 }
 354 
 355                 bus_range.lo = 0;
 356                 (void) ddi_getlongprop_buf(DDI_DEV_T_NONE, dip,
 357                     DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus_range, &len);
 358                 bus_range.hi = 255;
 359 
 360                 (void) ndi_ra_free(dip,
 361                     (uint64_t)bus_range.lo + 1,
 362                     (uint64_t)bus_range.hi - (uint64_t)bus_range.lo,
 363                     NDI_RA_TYPE_PCI_BUSNUM, 0);
 364 
 365                 ctrl.rv = DDI_SUCCESS;
 366                 ctrl.dip = dip;
 367                 ctrl.range = &bus_range;
 368 
 369                 cardbus_walk_node_child(dip, cardbus_claim_pci_busnum,
 370                     (void*)&ctrl);
 371 
 372                 if (ctrl.rv != DDI_SUCCESS)
 373                         cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange "
 374                             "cardbus_walk_node_child fails\n");
 375 
 376                 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
 377                     "bus-range", (int *)&bus_range, 2);
 378 
 379         } else {
 380                 cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange "
 381                     "already set up %x\n", (int)next_bus);
 382                 (void) ndi_ra_free(dip, next_bus, (uint64_t)1,
 383                     NDI_RA_TYPE_PCI_BUSNUM, 0);
 384         }
 385 }
 386 
 387 static dev_info_t *
 388 cardbus_find_hsbridge_dip(dev_info_t *dip)
 389 {
 390         dev_info_t *pdip;
 391 
 392         pdip = ddi_get_parent(dip);
 393         while (pdip) {
 394                 if (ddi_get_parent(pdip) == ddi_root_node())
 395                         break;
 396                 pdip = ddi_get_parent(pdip);
 397         }
 398 
 399         return (pdip);
 400 }
 401 #endif /* sparc */
 402 
 403 /*
 404  * Attach a device to the cardbus infrastructure.
 405  */
 406 int
 407 cardbus_attach(dev_info_t *dip, cb_nexus_cb_t *nex_ops)
 408 {
 409         cbus_t *cbp;
 410         int cb_instance;
 411         anp_t *anp = (anp_t *)ddi_get_driver_private(dip);
 412         struct dev_info *devi = DEVI(dip);
 413 
 414         mutex_enter(&cardbus_list_mutex);
 415 
 416         /*
 417          * Make sure that it is not already initialized.
 418          */
 419         if (ddi_prop_exists(DDI_DEV_T_ANY, dip,
 420             DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
 421             "cbus-instance") == 1) {
 422                 cmn_err(CE_WARN,
 423                     "%s%d: cardbus instance already initialized!\n",
 424                     ddi_driver_name(dip), ddi_get_instance(dip));
 425                         mutex_exit(&cardbus_list_mutex);
 426                 return (DDI_FAILURE);
 427         }
 428 
 429         /*
 430          * initialize soft state structure for the bus instance.
 431          */
 432         cb_instance = cardbus_next_instance++;
 433 
 434         if (ddi_soft_state_zalloc(cardbus_state, cb_instance) != DDI_SUCCESS) {
 435                 cmn_err(CE_WARN, "%s%d: can't allocate cardbus soft state\n",
 436                     ddi_driver_name(dip), ddi_get_instance(dip));
 437                 mutex_exit(&cardbus_list_mutex);
 438                 return (DDI_FAILURE);
 439         }
 440 
 441         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
 442         cbp->cb_instance = cb_instance;
 443         cbp->cb_dip = dip;
 444         mutex_init(&cbp->cb_mutex, NULL, MUTEX_DRIVER, NULL);
 445 
 446         /*
 447          * Save the instance number of the soft state structure for
 448          * this bus as a devinfo property.
 449          */
 450         if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
 451             "cbus-instance", (caddr_t)&cb_instance,
 452             sizeof (cb_instance)) != DDI_SUCCESS) {
 453                 cmn_err(CE_WARN,
 454                     "%s%d: failed to add the property 'cbus-instance'",
 455                     ddi_driver_name(dip), ddi_get_instance(dip));
 456                 ddi_soft_state_free(cardbus_state, cb_instance);
 457                 mutex_exit(&cardbus_list_mutex);
 458                 return (DDI_FAILURE);
 459         }
 460 
 461         cbp->cb_nex_ops = nex_ops;
 462         /*
 463          * TODO - Should probably be some sort of locking on the devinfo here.
 464          */
 465         cbp->orig_dopsp = devi->devi_ops;
 466         cbp->orig_bopsp = devi->devi_ops->devo_bus_ops;
 467         cbp->cb_dops = *devi->devi_ops;
 468         devi->devi_ops = &cbp->cb_dops;
 469 
 470         if (ndi_event_alloc_hdl(dip, *anp->an_iblock, &cbp->cb_ndi_event_hdl,
 471             NDI_SLEEP) == NDI_SUCCESS) {
 472                 cbp->cb_ndi_events.ndi_n_events = CB_N_NDI_EVENTS;
 473                 cbp->cb_ndi_events.ndi_events_version = NDI_EVENTS_REV1;
 474                 cbp->cb_ndi_events.ndi_event_defs = cb_ndi_event_defs;
 475                 if (ndi_event_bind_set(cbp->cb_ndi_event_hdl,
 476                     &cbp->cb_ndi_events,
 477                     NDI_SLEEP) != NDI_SUCCESS) {
 478                         cardbus_err(dip, 1,
 479                             "cardbus_attach: ndi_event_bind_set failed\n");
 480                 }
 481         }
 482 
 483         /*
 484          * Check for device initialization property.
 485          */
 486         cardbus_device_props(cbp);
 487 
 488         if (cardbus_init_hotplug(cbp) != DDI_SUCCESS) {
 489                 ddi_soft_state_free(cardbus_state, cb_instance);
 490                 mutex_exit(&cardbus_list_mutex);
 491                 return (DDI_FAILURE);
 492         }
 493 
 494 #ifdef sparc
 495         /* a hack to fix the bus-range problem on pci root nodes */
 496         {
 497                 dev_info_t *hs_dip;
 498 
 499                 hs_dip = cardbus_find_hsbridge_dip(dip);
 500                 cardbus_fix_hostbridge_busrange(hs_dip);
 501         }
 502 #endif
 503 
 504         cardbus_expand_busrange(dip);
 505         cardbus_count++;
 506         mutex_exit(&cardbus_list_mutex);
 507         return (DDI_SUCCESS);
 508 }
 509 
 510 #ifdef TODO
 511 static int
 512 cardbus_detach(dev_info_t *dip)
 513 {
 514         int cb_instance;
 515         cbus_t *cbp;
 516 
 517         mutex_enter(&cardbus_list_mutex);
 518         /* get the instance number for the cardbus soft state data */
 519         cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
 520             DDI_PROP_DONTPASS, "cbus-instance", -1);
 521         if (cb_instance < 0) {
 522                 mutex_exit(&cardbus_list_mutex);
 523                 return (DDI_FAILURE); /* no instance is setup for this bus */
 524         }
 525 
 526         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
 527 
 528         if (cbp->cb_dsp) {
 529                 struct cb_deviceset_props *cbdp, *ncbdp;
 530 
 531                 cbdp = cbp->cb_dsp;
 532                 while (cbdp) {
 533                         ncbdp = cbdp->next;
 534                         cardbus_devprops_free(cbdp);
 535                         cbdp = ncbdp;
 536                 }
 537         }
 538         /*
 539          * Unregister the bus with the HPS.
 540          *
 541          * (Note: It is assumed that the HPS framework uninstalls
 542          *  event handlers for all the hot plug slots on this bus.)
 543          */
 544         (void) hpc_nexus_unregister_bus(dip);
 545 
 546         if (cbp->cb_ndi_event_hdl != NULL) {
 547                 (void) ndi_event_unbind_set(cbp->cb_ndi_event_hdl,
 548                     &cbp->cb_ndi_events, NDI_SLEEP);
 549                 ndi_event_free_hdl(cbp->cb_ndi_event_hdl);
 550         }
 551 
 552         mutex_destroy(&cbp->cb_mutex);
 553         if (cbp->nexus_path)
 554                 kmem_free(cbp->nexus_path, strlen(cbp->nexus_path) + 1);
 555         if (cbp->name)
 556                 kmem_free(cbp->name, strlen(cbp->name) + 1);
 557 
 558         ddi_soft_state_free(cardbus_state, cb_instance);
 559 
 560         /* remove the 'cbus-instance' property from the devinfo node */
 561         (void) ddi_prop_remove(DDI_DEV_T_ANY, dip, "cbus-instance");
 562 
 563         ASSERT(cardbus_count != 0);
 564         --cardbus_count;
 565 
 566         mutex_exit(&cardbus_list_mutex);
 567         return (DDI_SUCCESS);
 568 }
 569 #endif
 570 
 571 boolean_t
 572 cardbus_load_cardbus(dev_info_t *dip, uint_t socket, uint32_t pc_base)
 573 {
 574 #ifndef HOTPLUG
 575         struct cardbus_config_ctrl ctrl;
 576         int circular_count;
 577 #endif
 578         int cb_instance;
 579         cbus_t *cbp;
 580         struct dev_info *devi = DEVI(dip);
 581 
 582         _NOTE(ARGUNUSED(socket, pc_base))
 583 
 584 #if defined(CARDBUS_DEBUG)
 585         cardbus_err(dip, 6, "cardbus_load_cardbus\n");
 586 #endif
 587 
 588         cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
 589             DDI_PROP_DONTPASS, "cbus-instance", -1);
 590         ASSERT(cb_instance >= 0);
 591         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
 592 
 593         if (cbp->fatal_problem)
 594                 return (B_FALSE);
 595 
 596         if (cardbus_convert_properties(dip) == DDI_FAILURE)
 597                 return (B_FALSE);
 598 
 599         number_of_cardbus_cards++;
 600         devi->devi_ops->devo_bus_ops = &cardbusbus_ops;
 601 
 602 #ifdef HOTPLUG
 603         mutex_enter(&cbp->cb_mutex);
 604         cbp->card_present = B_TRUE;
 605 
 606         (void) hpc_slot_event_notify(cbp->slot_handle,
 607             HPC_EVENT_SLOT_INSERTION, 0);
 608         (void) hpc_slot_event_notify(cbp->slot_handle,
 609             HPC_EVENT_SLOT_POWER_ON, 0);
 610         (void) hpc_slot_event_notify(cbp->slot_handle,
 611             HPC_EVENT_SLOT_CONFIGURE, 0);
 612 
 613         mutex_exit(&cbp->cb_mutex);
 614 #else
 615         if (cardbus_configure(cbp) != PCICFG_SUCCESS) {
 616 #if defined(CARDBUS_DEBUG)
 617                 cardbus_err(dip, 6, "cardbus_configure failed\n");
 618 #endif
 619                 return (B_FALSE);
 620         }
 621 
 622         ctrl.rv = NDI_SUCCESS;
 623         ctrl.busno = cardbus_primary_busno(dip);
 624         ctrl.op = PCICFG_OP_ONLINE;
 625         ctrl.dip = NULL;
 626         ctrl.flags = PCICFG_FLAGS_CONTINUE;
 627 
 628         /*
 629          * The child of the dip is the cardbus dip. The child of the
 630          * cardbus dip is the device itself
 631          */
 632 #if defined(CARDBUS_DEBUG)
 633         cardbus_err(dip, 8, "cardbus_load_cardbus: calling cbus_configure\n");
 634 #endif
 635         ndi_devi_enter(dip, &circular_count);
 636         ddi_walk_devs(ddi_get_child(dip), cbus_configure, (void *)&ctrl);
 637         ndi_devi_exit(dip, circular_count);
 638 
 639         if (ctrl.rv != NDI_SUCCESS) {
 640                 cardbus_err(dip, 1,
 641                     "cardbus_load_cardbus (%s%d): failed to attach (%d)\n",
 642                     ctrl.dip ? ddi_driver_name(ctrl.dip) : "Unknown",
 643                     ctrl.dip ? ddi_get_instance(ctrl.dip) : 0,
 644                     ctrl.rv);
 645 
 646                 /*
 647                  * Returning error here will cause the pcic_load_cardbus() call
 648                  * to fail. This will invoke pcic_unload_cardbus() which calls
 649                  * cardbus_unload_cardbus() below.
 650                  */
 651                 return (B_FALSE);
 652         }
 653 #endif
 654 
 655 #if defined(CARDBUS_DEBUG)
 656         cardbus_err(dip, 7, "cardbus_load_cardbus: returning TRUE\n");
 657 #endif
 658 
 659         return (B_TRUE);
 660 }
 661 
 662 /*
 663  * Unload the cardbus module
 664  */
 665 void
 666 cardbus_unload_cardbus(dev_info_t *dip)
 667 {
 668         int     cb_instance;
 669 #ifndef HOTPLUG
 670         int     prim_bus = cardbus_primary_busno(dip);
 671         int     rval;
 672 #endif
 673         cbus_t *cbp;
 674 
 675         cardbus_err(dip, 6, "cardbus_unload_cardbus\n");
 676 
 677         cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
 678             DDI_PROP_DONTPASS, "cbus-instance", -1);
 679         ASSERT(cb_instance >= 0);
 680         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
 681 
 682         if (number_of_cardbus_cards == 0)
 683                 return;
 684 
 685 #ifdef HOTPLUG
 686         mutex_enter(&cbp->cb_mutex);
 687         cbp->card_present = B_FALSE;
 688 
 689         (void) hpc_slot_event_notify(cbp->slot_handle,
 690             HPC_EVENT_SLOT_POWER_OFF, 0);
 691         (void) hpc_slot_event_notify(cbp->slot_handle,
 692             HPC_EVENT_SLOT_UNCONFIGURE, 0);
 693         (void) hpc_slot_event_notify(cbp->slot_handle,
 694             HPC_EVENT_SLOT_REMOVAL, 0);
 695 
 696         mutex_exit(&cbp->cb_mutex);
 697 #else
 698 
 699         cardbus_err(dip, 8,
 700             "cardbus_unload_cardbus: calling cardbus_unconfigure_node\n");
 701 
 702         rval = cardbus_unconfigure_node(dip, prim_bus, B_TRUE);
 703 
 704         if (rval != NDI_SUCCESS) {
 705                 cardbus_err(dip, 4,
 706                     "cardbus_unload_cardbus: "
 707                     "cardbus_unconfigure_node failed\n");
 708                 number_of_cardbus_cards--;
 709                 cbp->fatal_problem = B_TRUE;
 710                 cmn_err(CE_WARN,
 711                     "cardbus(%s%d): Failed to remove device tree: "
 712                     "Slot disabled",
 713                     ddi_get_name(dip), ddi_get_instance(dip));
 714                 return;
 715         }
 716 
 717         (void) cardbus_unconfigure(cbp);
 718 #endif
 719 
 720         /*
 721          * Inform the lower drivers that the card has been removed
 722          */
 723         if (cbp->cb_ndi_event_hdl != NULL) {
 724                 ddi_eventcookie_t cookie;
 725                 if (ndi_event_retrieve_cookie(cbp->cb_ndi_event_hdl, dip,
 726                     DDI_DEVI_REMOVE_EVENT, &cookie, 0) == NDI_SUCCESS) {
 727                         (void) ndi_event_run_callbacks(cbp->cb_ndi_event_hdl,
 728                             dip, cookie, NULL);
 729                 }
 730         }
 731 
 732         cardbus_revert_properties(dip);
 733 }
 734 
 735 static boolean_t
 736 is_32bit_pccard(dev_info_t *dip)
 737 {
 738         int len;
 739         char bus_type[16];
 740 
 741         len = sizeof (bus_type);
 742         if (ddi_prop_op(DDI_DEV_T_ANY, ddi_get_parent(dip),
 743                 PROP_LEN_AND_VAL_BUF,
 744                 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
 745                 "device_type",
 746                 (caddr_t)&bus_type, &len) != DDI_SUCCESS)
 747                 return (B_FALSE);
 748 
 749         if ((strcmp(bus_type, "pci") != 0) &&
 750             (strcmp(bus_type, "pciex") != 0) &&
 751             (strcmp(bus_type, "cardbus") != 0)) /* not of pci type */
 752                 return (B_FALSE);
 753 
 754         return (B_TRUE);
 755 }
 756 
 757 void
 758 cardbus_save_children(dev_info_t *dip)
 759 {
 760         for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
 761                 cardbus_save_children(ddi_get_child(dip));
 762 
 763                 if (strcmp("pcs", ddi_node_name(dip)) == 0)
 764                         continue;
 765                 if (!is_32bit_pccard(dip))
 766                         continue;
 767                 cardbus_err(dip, 1, "Saving device\n");
 768                 (void) pci_save_config_regs(dip);
 769         }
 770 
 771 }
 772 
 773 void
 774 cardbus_restore_children(dev_info_t *dip)
 775 {
 776         for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
 777                 cardbus_restore_children(ddi_get_child(dip));
 778 
 779                 if (strcmp("pcs", ddi_node_name(dip)) == 0)
 780                         continue;
 781                 if (!is_32bit_pccard(dip))
 782                         continue;
 783                 cardbus_err(dip, 1, "restoring device\n");
 784                 (void) pci_restore_config_regs(dip);
 785         }
 786 
 787 }
 788 
 789 static int
 790 cardbus_convert_properties(dev_info_t *dip)
 791 {
 792         struct pcm_regs *pcic_avail_p, *old_avail_p;
 793         pci_regspec_t *cb_avail_p, *new_avail_p;
 794         pcic_ranges_t *pcic_range_p, *old_range_p;
 795         cardbus_range_t *cb_range_p, *new_range_p;
 796         int range_len, range_entries, i;
 797         int avail_len, avail_entries;
 798 
 799 #if defined(CARDBUS_DEBUG)
 800         cardbus_err(dip, 6, "cardbus_convert_properties\n");
 801 #endif
 802 
 803         if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
 804             "#address-cells", 3) != DDI_SUCCESS) {
 805                 cardbus_err(dip, 1, "cardbus_convert_properties: "
 806                     "failed to update #address-cells property\n");
 807                 return (DDI_FAILURE);
 808         }
 809         if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
 810             "#size-cells", 2) != DDI_SUCCESS) {
 811                 cardbus_err(dip, 1, "cardbus_convert_properties: "
 812                     "failed to update #size-cells property\n");
 813                 return (DDI_FAILURE);
 814         }
 815 
 816         if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, "available",
 817             (caddr_t)&pcic_avail_p, &avail_len) != DDI_PROP_SUCCESS) {
 818                 cardbus_err(dip, 1, "cardbus_convert_properties: "
 819                     "no available property for pcmcia\n");
 820         } else {
 821                 avail_entries = avail_len / sizeof (struct pcm_regs);
 822                 cb_avail_p = kmem_alloc(sizeof (pci_regspec_t) * avail_entries,
 823                     KM_SLEEP);
 824 
 825                 old_avail_p = pcic_avail_p;
 826                 new_avail_p = cb_avail_p;
 827                 for (i = 0; i < avail_entries;
 828                     i++, old_avail_p++, new_avail_p++) {
 829                         new_avail_p->pci_phys_hi = old_avail_p->phys_hi;
 830                         new_avail_p->pci_phys_mid = 0;
 831                         new_avail_p->pci_phys_low = old_avail_p->phys_lo;
 832                         new_avail_p->pci_size_hi = 0;
 833                         new_avail_p->pci_size_low = old_avail_p->phys_len;
 834                 }
 835 
 836                 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
 837                     "available",
 838                     (int *)cb_avail_p,
 839                     (sizeof (pci_regspec_t) * avail_entries)/sizeof (int));
 840 
 841                 kmem_free(pcic_avail_p, avail_len);
 842                 kmem_free(cb_avail_p, sizeof (pci_regspec_t) * avail_entries);
 843         }
 844 
 845         if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, "ranges",
 846             (caddr_t)&pcic_range_p, &range_len) != DDI_PROP_SUCCESS) {
 847                 cardbus_err(dip, 1, "cardbus_convert_properties: "
 848                     "no ranges property for pcmcia\n");
 849         } else {
 850                 range_entries = range_len / sizeof (pcic_ranges_t);
 851                 cb_range_p = kmem_alloc(
 852                     sizeof (cardbus_range_t) * range_entries, KM_SLEEP);
 853 
 854                 old_range_p = pcic_range_p;
 855                 new_range_p = cb_range_p;
 856                 for (i = 0; i < range_entries;
 857                     i++, old_range_p++, new_range_p++) {
 858                         new_range_p->child_hi =
 859                             old_range_p->pcic_range_caddrhi;
 860                         new_range_p->child_mid = 0;
 861                         new_range_p->child_lo =
 862                             old_range_p->pcic_range_caddrlo;
 863                         new_range_p->parent_hi =
 864                             old_range_p->pcic_range_paddrhi;
 865                         new_range_p->parent_mid =
 866                             old_range_p->pcic_range_paddrmid;
 867                         new_range_p->parent_lo =
 868                             old_range_p->pcic_range_paddrlo;
 869                         new_range_p->size_hi = 0;
 870                         new_range_p->size_lo = old_range_p->pcic_range_size;
 871                 }
 872 
 873                 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges",
 874                     (int *)cb_range_p,
 875                     (sizeof (cardbus_range_t) * range_entries)/sizeof (int));
 876 
 877                 kmem_free(pcic_range_p, range_len);
 878                 kmem_free(cb_range_p, sizeof (cardbus_range_t) * range_entries);
 879         }
 880 
 881         return (DDI_SUCCESS);
 882 }
 883 
 884 static void
 885 cardbus_revert_properties(dev_info_t *dip)
 886 {
 887 #if defined(CARDBUS_DEBUG)
 888         cardbus_err(dip, 6, "cardbus_revert_properties\n");
 889 #endif
 890 
 891         (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "#address-cells");
 892 
 893         (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "#size-cells");
 894 
 895         (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "available");
 896 }
 897 
 898 static int
 899 cardbus_prop_op(dev_t dev, dev_info_t *dip, dev_info_t *ch_dip,
 900                 ddi_prop_op_t prop_op, int mod_flags,
 901                 char *name, caddr_t valuep, int *lengthp)
 902 {
 903 #if defined(CARDBUS_DEBUG)
 904         if ((ch_dip != dip) || (cardbus_debug >= 9))
 905                 cardbus_err(dip, 6,
 906                     "cardbus_prop_op(%s) (dip=0x%p, op=%d, name=%s)\n",
 907                     ddi_driver_name(ch_dip), (void *) dip, prop_op, name);
 908 #endif
 909         return (impl_ddi_bus_prop_op(dev, dip, ch_dip, prop_op,
 910             mod_flags, name, valuep, lengthp));
 911 }
 912 
 913 static int
 914 cardbus_ctlops(dev_info_t *dip, dev_info_t *rdip,
 915         ddi_ctl_enum_t ctlop, void *arg, void *result)
 916 {
 917         pci_regspec_t *regs;
 918         int     totreg, reglen;
 919         const char      *dname = ddi_driver_name(dip);
 920 
 921         ASSERT(number_of_cardbus_cards != 0);
 922 
 923         cardbus_err(dip, 6,
 924             "cardbus_ctlops(%p, %p, %d, %p, %p)\n",
 925             (void *)dip, (void *)rdip, ctlop, (void *)arg, (void *)result);
 926 
 927         switch (ctlop) {
 928         case DDI_CTLOPS_UNINITCHILD:
 929                 cardbus_removechild((dev_info_t *)arg);
 930                 return (DDI_SUCCESS);
 931         case DDI_CTLOPS_POWER:
 932                 return (DDI_SUCCESS);
 933 
 934         default:
 935                 /*
 936                  * Do Nothing
 937                  */
 938                 cardbus_err(dip, 8,
 939                     "cardbus_ctlops: Unsupported DDI_CTLOP %d\n", ctlop);
 940                 return (ddi_ctlops(dip, rdip, ctlop, arg, result));
 941 
 942         case DDI_CTLOPS_SIDDEV:         /* see ddi_dev_is_sid(9F) */
 943                 return (DDI_SUCCESS);
 944 
 945         case DDI_CTLOPS_SLAVEONLY:      /* see ddi_slaveonly(9F) */
 946                 return (DDI_FAILURE);   /* cardbus */
 947 
 948         case DDI_CTLOPS_REGSIZE:
 949         case DDI_CTLOPS_NREGS:
 950                 if (rdip == (dev_info_t *)NULL) {
 951                         *(int *)result = 0;
 952                         return (DDI_FAILURE);
 953                 }
 954                 break;
 955 
 956         case DDI_CTLOPS_IOMIN:
 957                 /*
 958                  * If we are using the streaming cache, align at
 959                  * least on a cache line boundary. Otherwise use
 960                  * whatever alignment is passed in.
 961                  */
 962 
 963                 if (arg) {
 964                         int     val = *((int *)result);
 965 
 966 #ifdef  PCI_SBUF_LINE_SIZE
 967                         val = maxbit(val, PCI_SBUF_LINE_SIZE);
 968 #else
 969                         val = maxbit(val, 64);
 970 #endif
 971                         *((int *)result) = val;
 972                 }
 973                 return (DDI_SUCCESS);
 974 
 975         case DDI_CTLOPS_INITCHILD:
 976                 return (cardbus_initchild(rdip, dip, (dev_info_t *)arg,
 977                     result));
 978 
 979         case DDI_CTLOPS_REPORTDEV:
 980                 if (rdip == (dev_info_t *)0)
 981                         return (DDI_FAILURE);
 982 
 983                 if (strcmp("pcs", ddi_node_name(rdip)) == 0)
 984                         cardbus_err(dip, 1,
 985                             "cardbus_ctlops: PCCard socket %d at %s@%s\n",
 986                             ddi_get_instance(rdip),
 987                             dname, ddi_get_name_addr(dip));
 988                 else {
 989                         pci_regspec_t *pci_rp;
 990                         dev_info_t *next;
 991                         int     length;
 992 
 993                         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip,
 994                             DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
 995                             (uint_t *)&length) != DDI_PROP_SUCCESS)
 996                                 return (DDI_FAILURE);
 997 
 998                         if (pci_rp->pci_phys_hi == 0)
 999                                 cardbus_err(dip, 1, "%s%d at %s@%s\n",
1000                                     ddi_driver_name(rdip),
1001                                     ddi_get_instance(rdip),
1002                                     dname, ddi_get_name_addr(dip));
1003                         else {
1004                                 uint8_t bus, device, function;
1005                                 int32_t val32;
1006                                 char    *ptr, buf[128];
1007 
1008                                 bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
1009                                 device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
1010                                 function = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
1011 
1012                                 ptr = buf;
1013                                 (void) sprintf(ptr, "  "
1014                                     "Bus %3d Device %2d Function %2d",
1015                                     bus, device, function);
1016                                 ptr = &ptr[strlen(ptr)];
1017 
1018                                 val32 = ddi_getprop(DDI_DEV_T_ANY, rdip,
1019                                     DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
1020                                     "vendor-id", -1);
1021                                 if (val32 != -1) {
1022                                         (void) sprintf(ptr, " Vendor 0x%04x",
1023                                             val32);
1024                                         ptr = &ptr[strlen(ptr)];
1025                                 }
1026                                 val32 = ddi_getprop(DDI_DEV_T_ANY, rdip,
1027                                     DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
1028                                     "device-id", -1);
1029                                 if (val32 != -1) {
1030                                         (void) sprintf(ptr, " Device 0x%04x",
1031                                             val32);
1032                                         ptr = &ptr[strlen(ptr)];
1033                                 }
1034                                 val32 = ddi_getprop(DDI_DEV_T_ANY, rdip,
1035                                     DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
1036                                     "class-code", -1);
1037                                 if (val32 != -1) {
1038                                         const char      *name;
1039 
1040                                         if ((name = ddi_get_name(rdip)) !=
1041                                             NULL)
1042                                                 (void) sprintf(ptr, " Name %s",
1043                                                     name);
1044                                         else
1045                                                 (void) sprintf(ptr,
1046                                                     " Class 0x%x", val32 >> 8);
1047                                         ptr = &ptr[strlen(ptr)];
1048                                 }
1049 
1050                                 *ptr++ = '\n';
1051                                 ASSERT(((caddr_t)ptr - (caddr_t)buf) <
1052                                     sizeof (buf));
1053                                 *ptr = '\0';
1054 
1055                                 cardbus_err(dip, 1, buf);
1056                         }
1057                         ddi_prop_free(pci_rp);
1058 
1059                         for (next = ddi_get_child(rdip); next;
1060                             next = ddi_get_next_sibling(next))
1061                                 (void) cardbus_ctlops(next, next,
1062                                     DDI_CTLOPS_REPORTDEV, arg, result);
1063                 }
1064                 return (DDI_SUCCESS);
1065         }
1066         *(int *)result = 0;
1067 
1068         if (ddi_getlongprop(DDI_DEV_T_NONE, rdip,
1069             DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg",
1070             (caddr_t)&regs, &reglen) != DDI_SUCCESS)
1071                 return (DDI_FAILURE);
1072 
1073         totreg = reglen / sizeof (pci_regspec_t);
1074         if (ctlop == DDI_CTLOPS_NREGS) {
1075                 cardbus_err(dip, 6,
1076                     "cardbus_ctlops, returning NREGS = %d\n", totreg);
1077                 *(int *)result = totreg;
1078         } else if (ctlop == DDI_CTLOPS_REGSIZE) {
1079                 const int       rn = *(int *)arg;
1080                 if (rn > totreg)
1081                         return (DDI_FAILURE);
1082                 cardbus_err(dip, 6,
1083                     "cardbus_ctlops, returning REGSIZE(%d) = %d\n",
1084                     rn, regs[rn].pci_size_low);
1085                 *(off_t *)result = regs[rn].pci_size_low;
1086         }
1087         kmem_free(regs, reglen);
1088         return (DDI_SUCCESS);
1089 }
1090 
1091 static void
1092 cardbus_init_child_regs(dev_info_t *child)
1093 {
1094         ddi_acc_handle_t config_handle;
1095         uint16_t command_preserve, command;
1096 #if !defined(__i386) && !defined(__amd64)
1097         uint8_t bcr;
1098 #endif
1099         uint8_t header_type;
1100         uint8_t min_gnt, latency_timer;
1101         uint_t n;
1102 
1103         /*
1104          * Map the child configuration space to for initialization.
1105          *
1106          *  Set the latency-timer register to values appropriate
1107          *  for the devices on the bus (based on other devices
1108          *  MIN_GNT and MAX_LAT registers.
1109          *
1110          *  Set the fast back-to-back enable bit in the command
1111          *  register if it's supported and all devices on the bus
1112          *  have the capability.
1113          *
1114          */
1115         if (pci_config_setup(child, &config_handle) != DDI_SUCCESS)
1116                 return;
1117 
1118         cardbus_err(child, 6, "cardbus_init_child_regs()\n");
1119 
1120         /*
1121          * Determine the configuration header type.
1122          */
1123         header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
1124 
1125         /*
1126          * Support for "command-preserve" property.  Note that we
1127          * add PCI_COMM_BACK2BACK_ENAB to the bits to be preserved
1128          * since the obp will set this if the device supports and
1129          * all targets on the same bus support it.  Since psycho
1130          * doesn't support PCI_COMM_BACK2BACK_ENAB, it will never
1131          * be set.  This is just here in case future revs do support
1132          * PCI_COMM_BACK2BACK_ENAB.
1133          */
1134         command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
1135             DDI_PROP_DONTPASS,
1136             "command-preserve", 0);
1137         command = pci_config_get16(config_handle, PCI_CONF_COMM);
1138         command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
1139         command |= (cardbus_command_default & ~command_preserve);
1140         pci_config_put16(config_handle, PCI_CONF_COMM, command);
1141         command = pci_config_get16(config_handle, PCI_CONF_COMM);
1142 
1143 #if !defined(__i386) && !defined(__amd64)
1144         /*
1145          * If the device has a bus control register then program it
1146          * based on the settings in the command register.
1147          */
1148         if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
1149                 bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
1150                 if (cardbus_command_default & PCI_COMM_PARITY_DETECT)
1151                         bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
1152                 if (cardbus_command_default & PCI_COMM_SERR_ENABLE)
1153                         bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
1154                 bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
1155                 pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
1156         }
1157 #endif
1158 
1159         /*
1160          * Initialize cache-line-size configuration register if needed.
1161          */
1162         if (ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
1163             "cache-line-size", 0) == 0) {
1164 
1165                 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
1166                     PCI_CACHE_LINE_SIZE);
1167                 n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
1168                 if (n != 0)
1169                         (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
1170                             "cache-line-size", n);
1171         }
1172 
1173         /*
1174          * Initialize latency timer registers if needed.
1175          */
1176         if (ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
1177             "latency-timer", 0) == 0) {
1178 
1179                 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
1180                         latency_timer = cardbus_latency_timer;
1181                         pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
1182                             latency_timer);
1183                 } else {
1184                         min_gnt = pci_config_get8(config_handle,
1185                             PCI_CONF_MIN_G);
1186 
1187                         /*
1188                          * Cardbus os only 33Mhz
1189                          */
1190                         if (min_gnt != 0) {
1191                                 latency_timer = min_gnt * 8;
1192                         }
1193                 }
1194                 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
1195                     latency_timer);
1196                 n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
1197                 if (n != 0)
1198                         (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
1199                         "latency-timer", n);
1200         }
1201 
1202         pci_config_teardown(&config_handle);
1203 }
1204 
1205 static int
1206 cardbus_initchild(dev_info_t *rdip, dev_info_t *dip, dev_info_t *child,
1207                 void *result)
1208 {
1209         char    name[MAXNAMELEN];
1210         const char      *dname = ddi_driver_name(dip);
1211         const struct cb_ops *cop;
1212 
1213         _NOTE(ARGUNUSED(rdip, result))
1214 
1215         cardbus_err(child, 6, "cardbus_initchild\n");
1216 
1217         /*
1218          * Name the child
1219          */
1220         if (cardbus_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
1221                 return (DDI_FAILURE);
1222 
1223         ddi_set_name_addr(child, name);
1224         ddi_set_parent_data(child, NULL);
1225 
1226         if (ndi_dev_is_persistent_node(child) == 0) {
1227                 /*
1228                  * Try to merge the properties from this prototype
1229                  * node into real h/w nodes.
1230                  */
1231                 if (ndi_merge_node(child, cardbus_name_child) == DDI_SUCCESS) {
1232                         /*
1233                          * Merged ok - return failure to remove the node.
1234                          */
1235                         cardbus_removechild(child);
1236                         return (DDI_FAILURE);
1237                 }
1238                 /*
1239                  * The child was not merged into a h/w node,
1240                  * but there's not much we can do with it other
1241                  * than return failure to cause the node to be removed.
1242                  */
1243                 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
1244                     ddi_driver_name(child), ddi_get_name_addr(child),
1245                     ddi_driver_name(child));
1246                 cardbus_removechild(child);
1247                 return (DDI_NOT_WELL_FORMED);
1248         }
1249         cop = DEVI(dip)->devi_ops->devo_cb_ops;
1250 
1251         if ((cop == NULL) || (!(cop->cb_flag & D_HOTPLUG))) {
1252                 cmn_err(CE_WARN, "%s: driver doesn't support HOTPLUG\n", dname);
1253                 return (DDI_FAILURE);
1254         }
1255 
1256         cardbus_init_child_regs(child);
1257 
1258         /*
1259          * Create ppd if needed.
1260          */
1261         if (ddi_get_parent_data(child) == NULL) {
1262                 struct cardbus_parent_private_data *ppd;
1263 
1264 #ifdef sparc
1265                 ppd = (struct cardbus_parent_private_data *)
1266                     kmem_zalloc(sizeof (struct cardbus_parent_private_data),
1267                     KM_SLEEP);
1268 
1269 #elif defined(__x86) || defined(__amd64)
1270                 ppd = (struct cardbus_parent_private_data *)
1271                     kmem_zalloc(sizeof (struct cardbus_parent_private_data)
1272                     + sizeof (struct intrspec), KM_SLEEP);
1273 
1274                 ppd->ppd.par_intr = (struct intrspec *)(ppd + 1);
1275                 (ppd->ppd.par_intr)->intrspec_pri = 0;
1276                 (ppd->ppd.par_intr)->intrspec_vec = 0;
1277                 (ppd->ppd.par_intr)->intrspec_func = (uint_t (*)()) 0;
1278 #endif
1279 
1280                 if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS,
1281                     "interrupts", -1) != -1)
1282                         ppd->ppd.par_nintr = 1;
1283 
1284                 ppd->code = CB_PPD_CODE;
1285 
1286                 cardbus_err(child, 5,
1287                     "cardbus_initchild: Creating empty ppd\n");
1288                 ppd->ppd.par_nreg = 0;
1289                 ppd->ppd.par_reg = NULL;
1290 
1291                 ddi_set_parent_data(child, (caddr_t)ppd);
1292         }
1293 
1294         return (DDI_SUCCESS);
1295 }
1296 
1297 static int
1298 cardbus_name_child(dev_info_t *child, char *name, int namelen)
1299 {
1300         pci_regspec_t *pci_rp;
1301         char    **unit_addr;
1302         uint_t n;
1303         int     bus, device, func;
1304 
1305         /*
1306          * Pseudo nodes indicate a prototype node with per-instance
1307          * properties to be merged into the real h/w device node.
1308          * The interpretation of the unit-address is DD[,F]
1309          * where DD is the device id and F is the function.
1310          */
1311         if (ndi_dev_is_persistent_node(child) == 0) {
1312                 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
1313                     DDI_PROP_DONTPASS,
1314                     "unit-address", &unit_addr, &n) != DDI_PROP_SUCCESS) {
1315                         cmn_err(CE_WARN, "cannot name node from %s.conf",
1316                             ddi_driver_name(child));
1317                         return (DDI_FAILURE);
1318                 }
1319                 if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
1320                         cmn_err(CE_WARN, "unit-address property in %s.conf"
1321                             " not well-formed", ddi_driver_name(child));
1322                         ddi_prop_free(unit_addr);
1323                         return (DDI_FAILURE);
1324                 }
1325                 (void) snprintf(name, namelen, "%s", *unit_addr);
1326                 ddi_prop_free(unit_addr);
1327                 return (DDI_SUCCESS);
1328         }
1329 
1330         /*
1331          * Get the address portion of the node name based on
1332          * the function and device number.
1333          */
1334         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
1335             "reg", (int **)&pci_rp, &n) != DDI_SUCCESS) {
1336                 return (DDI_FAILURE);
1337         }
1338 
1339         bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
1340         device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
1341         func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
1342         ddi_prop_free(pci_rp);
1343 
1344         if (func != 0)
1345                 (void) snprintf(name, namelen, "%x,%x", device, func);
1346         else
1347                 (void) snprintf(name, namelen, "%x", device);
1348 
1349         cardbus_err(child, 8,
1350             "cardbus_name_child: system init done [%x][%x][%x]"
1351             " for %s [%s] nodeid: %x @%s\n",
1352             bus, device, func,
1353             ddi_get_name(child), ddi_get_name_addr(child),
1354             DEVI(child)->devi_nodeid, name);
1355 
1356         return (DDI_SUCCESS);
1357 }
1358 
1359 static void
1360 cardbus_removechild(dev_info_t *dip)
1361 {
1362         struct cardbus_parent_private_data *ppd;
1363 
1364         ddi_set_name_addr(dip, NULL);
1365         impl_rem_dev_props(dip);
1366         ppd = (struct cardbus_parent_private_data *)ddi_get_parent_data(dip);
1367         if (ppd && (ppd->code == CB_PPD_CODE)) {
1368                 if (ppd->ppd.par_reg && (ppd->ppd.par_nreg > 0))
1369                         kmem_free((caddr_t)ppd->ppd.par_reg,
1370                             ppd->ppd.par_nreg * sizeof (struct regspec));
1371 #ifdef sparc
1372                 kmem_free(ppd, sizeof (struct cardbus_parent_private_data));
1373 #elif defined(__x86) || defined(__amd64)
1374                 kmem_free(ppd, sizeof (struct cardbus_parent_private_data) +
1375                     sizeof (struct intrspec));
1376 #endif
1377                 cardbus_err(dip, 5,
1378                     "cardbus_removechild: ddi_set_parent_data(NULL)\n");
1379                 ddi_set_parent_data(dip, NULL);
1380         }
1381 }
1382 
1383 
1384 static char     cb_bnamestr[] = "binding_name";
1385 static char     cb_venidstr[] = "VendorID";
1386 static char     cb_devidstr[] = "DeviceID";
1387 static char     cb_nnamestr[] = "nodename";
1388 
1389 static cb_props_parse_tree_t cb_props_parse_tree[] = {
1390         { cb_bnamestr, PT_STATE_STRING_VAR },
1391         { cb_venidstr, PT_STATE_HEX_VAR },
1392         { cb_devidstr, PT_STATE_HEX_VAR } };
1393 
1394 static int
1395 check_token(char *token, int *len)
1396 {
1397         int     state = PT_STATE_DEC_VAR;
1398         int     sl = strlen(token), il = 1;
1399         char    c;
1400 
1401         if (token[0] == '0' && token[2] && (token[1] == 'x' || token[1] ==
1402             'X')) {
1403                 state = PT_STATE_HEX_VAR;
1404                 token += 2;
1405         }
1406 
1407         while (c = *token++) {
1408                 if (isdigit(c))
1409                         continue;
1410                 if (c == PARSE_COMMA) {
1411                         il++;
1412                         if (token[0] == '0' && token[2] && isx(token[1])) {
1413                                 state = PT_STATE_HEX_VAR;
1414                                 token += 2;
1415                         }
1416                         continue;
1417                 }
1418                 if (!isxdigit(c)) {
1419                         *len = sl;
1420                         return (PT_STATE_STRING_VAR);
1421                 }
1422                 state = PT_STATE_HEX_VAR;
1423         }
1424         *len = il;
1425         return (state);
1426 }
1427 
1428 
1429 static char *
1430 find_token(char **cp, int *l, char *endc)
1431 {
1432         char    *cpp = *cp;
1433 
1434         while ((**cp && (isalpha(**cp) || isxdigit(**cp) ||
1435             (**cp == PARSE_UNDERSCORE) ||
1436             (**cp == PARSE_COMMA) ||
1437             (**cp == PARSE_DASH)))) {
1438                 (*cp)++;
1439                 (*l)++;
1440         }
1441 
1442         *endc = **cp;
1443         **cp = NULL;
1444 
1445         return (cpp);
1446 }
1447 
1448 static int
1449 parse_token(char *token)
1450 {
1451         cb_props_parse_tree_t *pt = cb_props_parse_tree;
1452         int     k = sizeof (cb_props_parse_tree) /
1453             sizeof (cb_props_parse_tree_t);
1454 
1455         while (k--) {
1456                 if (strcmp((char *)token, pt->token) == 0)
1457                         return (pt->state);
1458                 pt++;
1459         }
1460 
1461         return (PT_STATE_UNKNOWN);
1462 }
1463 
1464 static int
1465 token_to_hex(char *token, unsigned *val, int len)
1466 {
1467         uchar_t c;
1468 
1469         *val = 0;
1470         if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X')) {
1471                 token += 2;
1472         }
1473 
1474         while (*token) {
1475                 if (!isxdigit(*token)) {
1476                         if (*token == PARSE_COMMA) {
1477                                 if (!(--len))
1478                                         return (1);
1479                                 val++;
1480                                 *val = 0;
1481                                 token++;
1482                                 if (token[0] == '0' && (token[1] == 'x' ||
1483                                     token[1] == 'X')) {
1484                                         token += 2;
1485                                 }
1486                                 continue;
1487                         }
1488                         return (0);
1489                 }
1490                 c = toupper(*token);
1491                 if (c >= 'A')
1492                         c = c - 'A' + 10 + '0';
1493                 *val = ((*val * 16) + (c - '0'));
1494                 token++;
1495         }
1496 
1497         return (1);
1498 }
1499 
1500 static int
1501 token_to_dec(char *token, unsigned *val, int len)
1502 {
1503         *val = 0;
1504 
1505         while (*token) {
1506                 if (!isdigit(*token)) {
1507                         if (*token == PARSE_COMMA) {
1508                                 if (!(--len))
1509                                         return (1);
1510                                 val++;
1511                                 *val = 0;
1512                                 token++;
1513                                 continue;
1514                         }
1515                         return (0);
1516                 }
1517                 *val = ((*val * 10) + (*token - '0'));
1518                 token++;
1519         }
1520 
1521         return (1);
1522 }
1523 
1524 static void
1525 cardbus_add_prop(struct cb_deviceset_props *cdsp, int type, char *name,
1526                 caddr_t vp, int len)
1527 {
1528         ddi_prop_t *propp;
1529         int     pnlen = strlen(name) + 1;
1530 
1531         propp = (ddi_prop_t *)kmem_zalloc(sizeof (ddi_prop_t), KM_SLEEP);
1532         propp->prop_name = (char *)kmem_alloc(pnlen, KM_SLEEP);
1533         propp->prop_val = vp;
1534         bcopy(name, propp->prop_name, pnlen);
1535         propp->prop_len = len;
1536         propp->prop_flags = type;
1537         propp->prop_next = cdsp->prop_list;
1538         cdsp->prop_list = propp;
1539 }
1540 
1541 static void
1542 cardbus_add_stringprop(struct cb_deviceset_props *cdsp, char *name,
1543                 char *vp, int len)
1544 {
1545         char    *nstr = kmem_zalloc(len + 1, KM_SLEEP);
1546 
1547         bcopy(vp, nstr, len);
1548         cardbus_add_prop(cdsp, DDI_PROP_TYPE_STRING, name, (caddr_t)nstr,
1549             len + 1);
1550 }
1551 
1552 static void
1553 cardbus_prop_free(ddi_prop_t *propp)
1554 {
1555         if (propp->prop_len) {
1556                 switch (propp->prop_flags) {
1557                 case DDI_PROP_TYPE_STRING:
1558                         kmem_free(propp->prop_val, propp->prop_len);
1559                         break;
1560                 case DDI_PROP_TYPE_INT:
1561                         kmem_free(propp->prop_val,
1562                             propp->prop_len * sizeof (int));
1563                         break;
1564                 }
1565         }
1566         kmem_free(propp->prop_name, strlen(propp->prop_name) + 1);
1567         kmem_free(propp, sizeof (ddi_prop_t *));
1568 }
1569 
1570 static void
1571 cardbus_devprops_free(struct cb_deviceset_props *cbdp)
1572 {
1573         ddi_prop_t *propp, *npropp;
1574 
1575         propp = cbdp->prop_list;
1576         while (propp) {
1577                 npropp = propp->prop_next;
1578                 cardbus_prop_free(propp);
1579                 propp = npropp;
1580         }
1581         if (cbdp->nodename)
1582                 kmem_free(cbdp->nodename, strlen(cbdp->nodename) + 1);
1583         if (cbdp->binding_name)
1584                 kmem_free(cbdp->binding_name, strlen(cbdp->binding_name) +
1585                     1);
1586         kmem_free(cbdp, sizeof (*cbdp));
1587 }
1588 
1589 /*
1590  * Format of "cb-device-init-props" property:
1591  * Anything before the semi-colon is an identifying equate, anything
1592  * after the semi-colon is a setting equate.
1593  *
1594  * "binding_name=xXxXxX VendorID=NNNN DeviceID=NNNN; nodename=NewName
1595  *                                      Prop=PropVal"
1596  *
1597  */
1598 static int
1599 cardbus_parse_devprop(cbus_t *cbp, char *cp)
1600 {
1601         int     state = PT_STATE_TOKEN, qm = 0, em = 0, smc = 0, l = 0;
1602         int     length;
1603         char    *token = "beginning of line";
1604         char    *ptoken = NULL, *quote;
1605         char    eq = NULL;
1606         struct cb_deviceset_props *cdsp;
1607 
1608         cdsp = (struct cb_deviceset_props *)kmem_zalloc(sizeof (*cdsp),
1609             KM_SLEEP);
1610         length = strlen(cp);
1611 
1612         while ((*cp) && (l < length)) {
1613                 /*
1614                  * Check for escaped characters
1615                  */
1616                 if (*cp == PARSE_ESCAPE) {
1617                         char    *cpp = cp, *cppp = cp + 1;
1618 
1619                         em = 1;
1620 
1621                         if (!qm) {
1622                                 cmn_err(CE_CONT, "cardbus_parse_devprop: "
1623                                     "escape not allowed outside "
1624                                     "of quotes at [%s]\n", token);
1625                                 return (DDI_FAILURE);
1626 
1627                         } /* if (!qm) */
1628 
1629                         while (*cppp)
1630                                 *cpp++ = *cppp++;
1631 
1632                         l++;
1633 
1634                         *cpp = NULL;
1635                 } /* PARSE_ESCAPE */
1636 
1637                 /*
1638                  * Check for quoted strings
1639                  */
1640                 if (!em && (*cp == PARSE_QUOTE)) {
1641                         qm ^= 1;
1642                         if (qm) {
1643                                 quote = cp + 1;
1644                         } else {
1645                                 *cp = NULL;
1646                                 if (state == PT_STATE_CHECK) {
1647                                         if (strcmp(token, cb_nnamestr) == 0) {
1648                                                 cdsp->nodename = kmem_alloc(
1649                                                     strlen(quote) + 1,
1650                                                     KM_SLEEP);
1651                                                 (void) strcpy(cdsp->nodename,
1652                                                     quote);
1653                                         } else
1654                                                 cardbus_add_stringprop(cdsp,
1655                                                     token, quote,
1656                                                     strlen(quote));
1657                                 } else if (state != PT_STATE_STRING_VAR) {
1658                                         cmn_err(CE_CONT,
1659                                             "cardbus_parse_devprop: "
1660                                             "unexpected string [%s] after "
1661                                             "[%s]\n", quote, token);
1662                                         return (DDI_FAILURE);
1663                                 } else {
1664                                         if (strcmp(token, cb_bnamestr) == 0) {
1665                                                 cdsp->binding_name = kmem_alloc(
1666                                                     strlen(quote) + 1,
1667                                                     KM_SLEEP);
1668                                                 (void) strcpy(
1669                                                     cdsp->binding_name, quote);
1670                                         }
1671                                 }
1672                                 state = PT_STATE_TOKEN;
1673                         } /* if (qm) */
1674                 } /* PARSE_QUOTE */
1675 
1676                 em = 0;
1677 
1678                 if (!qm && (*cp == PARSE_SEMICOLON)) {
1679                         smc = 1;
1680                 }
1681 
1682                 /*
1683                  * Check for tokens
1684                  */
1685                 else if (!qm && (isalpha(*cp) || isxdigit(*cp))) {
1686                         int     tl;
1687                         unsigned        *intp;
1688                         ptoken = token;
1689                         token = find_token(&cp, &l, &eq);
1690 
1691                         switch (state) {
1692                         case PT_STATE_TOKEN:
1693                                 if (smc) {
1694                                         if (eq == PARSE_EQUALS)
1695                                                 state = PT_STATE_CHECK;
1696                                         else
1697                                                 cardbus_add_prop(cdsp,
1698                                                     DDI_PROP_TYPE_ANY,
1699                                                     token,
1700                                                     NULL, 0);
1701                                 } else if (eq == PARSE_EQUALS)
1702                                         switch (state = parse_token(token)) {
1703                                         case PT_STATE_UNKNOWN:
1704                                                 cmn_err(CE_CONT,
1705                                                     "cardbus_parse_devprop: "
1706                                                     "unknown token [%s]\n",
1707                                                     token);
1708                                                 state = PT_STATE_TOKEN;
1709                                         } /* switch (parse_token) */
1710                                 else
1711                                         state = PT_STATE_TOKEN;
1712                                 break;
1713 
1714                         case PT_STATE_CHECK:
1715                                 switch (check_token(token, &tl)) {
1716                                 case PT_STATE_DEC_VAR:
1717                                         intp = (unsigned *)kmem_alloc(
1718                                             sizeof (int)*tl,
1719                                             KM_SLEEP);
1720                                         if (token_to_dec(token, intp, tl))
1721                                                 cardbus_add_prop(cdsp,
1722                                                     DDI_PROP_TYPE_INT, ptoken,
1723                                                     (caddr_t)intp, tl);
1724                                         else
1725                                                 kmem_free(intp,
1726                                                     sizeof (int)*tl);
1727                                         break;
1728                                 case PT_STATE_HEX_VAR:
1729                                         intp = (unsigned *)kmem_alloc(
1730                                             sizeof (int)*tl,
1731                                             KM_SLEEP);
1732                                         if (token_to_hex(token, intp, tl))
1733                                                 cardbus_add_prop(cdsp,
1734                                                     DDI_PROP_TYPE_INT,
1735                                                     ptoken,
1736                                                     (caddr_t)intp, tl);
1737                                         else
1738                                                 kmem_free(intp,
1739                                                     sizeof (int)*tl);
1740                                         break;
1741                                 case PT_STATE_STRING_VAR:
1742                                         if (strcmp(ptoken, cb_nnamestr) == 0) {
1743                                                 cdsp->nodename = kmem_alloc(
1744                                                     tl + 1, KM_SLEEP);
1745                                                 (void) strcpy(cdsp->nodename,
1746                                                     token);
1747                                         } else
1748                                                 cardbus_add_stringprop(cdsp,
1749                                                     ptoken, token, tl);
1750                                         break;
1751                                 }
1752                                 state = PT_STATE_TOKEN;
1753                                 break;
1754 
1755                         case PT_STATE_HEX_VAR:
1756                                 if (strcmp(ptoken, cb_venidstr) == 0) {
1757                                         uint_t val;
1758                                         if (token_to_hex(token, &val, 1))
1759                                                 cdsp->venid = val;
1760                                 } else if (strcmp(ptoken, cb_devidstr) == 0) {
1761                                         uint_t val;
1762                                         if (token_to_hex(token, &val, 1))
1763                                                 cdsp->devid = val;
1764                                 }
1765                                 state = PT_STATE_TOKEN;
1766                                 break;
1767 
1768                         case PT_STATE_DEC_VAR:
1769                                 if (strcmp(ptoken, cb_venidstr) == 0) {
1770                                         uint_t val;
1771                                         if (token_to_dec(token, &val, 1))
1772                                                 cdsp->venid = val;
1773                                 } else if (strcmp(ptoken, cb_devidstr) == 0) {
1774                                         uint_t val;
1775                                         if (token_to_dec(token, &val, 1))
1776                                                 cdsp->devid = val;
1777                                 }
1778                                 state = PT_STATE_TOKEN;
1779                                 break;
1780 
1781                         case PT_STATE_STRING_VAR:
1782                                 if (strcmp(ptoken, cb_bnamestr) == 0) {
1783                                         cdsp->binding_name = kmem_alloc(
1784                                             strlen(token) + 1, KM_SLEEP);
1785                                         (void) strcpy(cdsp->binding_name,
1786                                             token);
1787                                 }
1788                                 state = PT_STATE_TOKEN;
1789                                 break;
1790 
1791                         default:
1792                                 cmn_err(CE_CONT, "cardbus_parse_devprop: "
1793                                     "unknown state machine state = %d\n",
1794                                     state);
1795 
1796                                 cardbus_devprops_free(cdsp);
1797                                 return (DDI_FAILURE);
1798                         } /* switch (state) */
1799                         if (eq == PARSE_SEMICOLON)
1800                                 smc = 1;
1801                 }
1802                 cp++;
1803                 l++;
1804         } /* while (*cp) */
1805 
1806         if (qm) {
1807                 cmn_err(CE_CONT, "cb_props_parse_line: unterminated "
1808                     "string = [%s]\n", quote);
1809                 cardbus_devprops_free(cdsp);
1810                 return (DDI_FAILURE);
1811         }
1812 
1813         if (state != PT_STATE_TOKEN) {
1814                 cmn_err(CE_CONT, "cardbus_parse_devprop: token [%s] "
1815                     "requires value\n", token);
1816                 cardbus_devprops_free(cdsp);
1817                 return (DDI_FAILURE);
1818         }
1819 
1820         if (cdsp->venid == 0 || cdsp->devid == 0) {
1821                 cmn_err(CE_CONT, "cardbus_parse_devprop: Entry "
1822                     "requires VendorID and DeviceID\n");
1823                 cardbus_devprops_free(cdsp);
1824                 return (DDI_FAILURE);
1825         }
1826 
1827         cdsp->next = cbp->cb_dsp;
1828         cbp->cb_dsp = cdsp;
1829         return (DDI_SUCCESS);
1830 }
1831 
1832 static void
1833 cardbus_device_props(cbus_t *cbp)
1834 {
1835         char    **prop_array;
1836         uint_t i, n;
1837 
1838         if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, cbp->cb_dip,
1839             DDI_PROP_DONTPASS,
1840             "cb-device-init-props", &prop_array,
1841             &n) != DDI_PROP_SUCCESS)
1842                 return;
1843 
1844         for (i = 0; i < n; i++)
1845                 (void) cardbus_parse_devprop(cbp, prop_array[i]);
1846 
1847         ddi_prop_free(prop_array);
1848 }
1849 
1850 static int
1851 cardbus_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
1852                 off_t offset, off_t len, caddr_t *vaddrp)
1853 {
1854         register dev_info_t *pdip = (dev_info_t *)DEVI(dip)->devi_parent;
1855         int     rc;
1856 
1857         cardbus_err(dip, 9,
1858             "cardbus_bus_map(dip=0x%p, rdip=0x%p)\n",
1859             (void *) dip, (void *) rdip);
1860 
1861         if (pdip == NULL)
1862                 return (DDI_FAILURE);
1863 
1864         /* A child has asked us to set something up */
1865         cardbus_err(dip, 9,
1866             "cardbus_bus_map(%s) calling %s - 0x%p, "
1867             "offset 0x%x, len 0x%x\n",
1868             ddi_driver_name(rdip),
1869             ddi_driver_name(pdip),
1870             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_map,
1871             (int)offset, (int)len);
1872 
1873         rc = (DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)
1874             (pdip, rdip, mp, offset, len, vaddrp);
1875         /* rc = ddi_map(dip, mp, offset, len, vaddrp); */
1876 
1877         if (rc != DDI_SUCCESS) {
1878                 cardbus_err(rdip, 8, "cardbus_bus_map failed, rc = %d\n", rc);
1879                 return (DDI_FAILURE);
1880         } else {
1881                 cardbus_err(rdip, 9, "cardbus_bus_map OK\n");
1882                 return (DDI_SUCCESS);
1883         }
1884 }
1885 
1886 static void
1887 pcirp2rp(const pci_regspec_t *pci_rp, struct regspec *rp)
1888 {
1889         /* bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi); */
1890         if (PCI_REG_ADDR_G(pci_rp->pci_phys_hi) ==
1891             PCI_REG_ADDR_G(PCI_ADDR_IO)) {
1892                 /* I/O */
1893                 rp->regspec_bustype = 1;
1894         } else {
1895                 /* memory */
1896                 rp->regspec_bustype = 0;
1897         }
1898         rp->regspec_addr = pci_rp->pci_phys_low;
1899         rp->regspec_size = pci_rp->pci_size_low;
1900 }
1901 
1902 static int
1903 cardbus_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
1904                 int (*waitfp)(caddr_t), caddr_t arg,
1905                 ddi_dma_handle_t *handlep)
1906 {
1907         dev_info_t *pdip = ddi_get_parent(dip);
1908 
1909         cardbus_err(dip, 10,
1910             "cardbus_dma_allochdl(dip=0x%p, rdip=0x%p)\n",
1911             (void *) dip, (void *) rdip);
1912 
1913         if (pdip == NULL)
1914                 return (DDI_FAILURE);
1915 
1916         cardbus_err(dip, 11,
1917             "cardbus_dma_allochdl calling %s - 0x%p\n",
1918             ddi_driver_name(pdip),
1919             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_allochdl);
1920 
1921         return (ddi_dma_allochdl(dip, rdip, attr, waitfp, arg, handlep));
1922 }
1923 
1924 static int
1925 cardbus_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
1926                 ddi_dma_handle_t handle)
1927 {
1928         dev_info_t *pdip = ddi_get_parent(dip);
1929 
1930         cardbus_err(dip, 10,
1931             "cardbus_dma_freehdl(dip=0x%p, rdip=0x%p)\n",
1932             (void *) dip, (void *) rdip);
1933 
1934         if (pdip == NULL)
1935                 return (DDI_FAILURE);
1936 
1937         cardbus_err(dip, 11,
1938             "cardbus_dma_freehdl calling %s - 0x%p\n",
1939             ddi_driver_name(pdip),
1940             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_freehdl);
1941 
1942         return (ddi_dma_freehdl(dip, rdip, handle));
1943 }
1944 
1945 static int
1946 cardbus_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
1947                 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
1948                 ddi_dma_cookie_t *cp, uint_t *ccountp)
1949 {
1950         dev_info_t *pdip = ddi_get_parent(dip);
1951 
1952         cardbus_err(dip, 10,
1953             "cardbus_dma_bindhdl(dip=0x%p, rdip=0x%p)\n",
1954             (void *) dip, (void *) rdip);
1955 
1956         if (pdip == NULL)
1957                 return (DDI_FAILURE);
1958 
1959         cardbus_err(dip, 11,
1960             "cardbus_dma_bindhdl calling %s - 0x%p\n",
1961             ddi_driver_name(pdip),
1962             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_bindhdl);
1963 
1964         return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_bindhdl(pdip,
1965             rdip, handle, dmareq, cp, ccountp));
1966 }
1967 
1968 static int
1969 cardbus_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
1970                 ddi_dma_handle_t handle)
1971 {
1972         dev_info_t *pdip = ddi_get_parent(dip);
1973 
1974         cardbus_err(dip, 10,
1975             "cardbus_dma_unbindhdl(dip=0x%p, rdip=0x%p)\n",
1976             (void *) dip, (void *) rdip);
1977 
1978         if (pdip == NULL)
1979                 return (DDI_FAILURE);
1980 
1981         cardbus_err(dip, 11,
1982             "cardbus_dma_unbindhdl calling %s - 0x%p\n",
1983             ddi_driver_name(pdip),
1984             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_unbindhdl);
1985 
1986         return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_unbindhdl(pdip,
1987             rdip, handle));
1988 }
1989 
1990 static int
1991 cardbus_dma_flush(dev_info_t *dip, dev_info_t *rdip,
1992                 ddi_dma_handle_t handle, off_t off, size_t len,
1993                 uint_t cache_flags)
1994 {
1995         dev_info_t *pdip = ddi_get_parent(dip);
1996 
1997         cardbus_err(dip, 10,
1998             "cardbus_dma_flush(dip=0x%p, rdip=0x%p)\n",
1999             (void *) dip, (void *) rdip);
2000 
2001         if (pdip == NULL)
2002                 return (DDI_FAILURE);
2003 
2004         cardbus_err(dip, 11,
2005             "cardbus_dma_flush calling %s - 0x%p\n",
2006             ddi_driver_name(pdip),
2007             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_flush);
2008 
2009         return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_flush(pdip, rdip,
2010             handle, off, len, cache_flags));
2011 }
2012 
2013 static int
2014 cardbus_dma_win(dev_info_t *dip, dev_info_t *rdip,
2015                 ddi_dma_handle_t handle, uint_t win, off_t *offp,
2016                 size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
2017 {
2018         dev_info_t *pdip = ddi_get_parent(dip);
2019         cardbus_err(dip, 6,
2020             "cardbus_dma_win(dip=0x%p, rdip=0x%p)\n",
2021             (void *) dip, (void *) rdip);
2022 
2023         if (pdip == NULL)
2024                 return (DDI_FAILURE);
2025 
2026         cardbus_err(dip, 8,
2027             "cardbus_dma_win calling %s - 0x%p\n",
2028             ddi_driver_name(pdip),
2029             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_win);
2030 
2031         return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_win(pdip, rdip,
2032             handle, win, offp, lenp, cookiep, ccountp));
2033 }
2034 
2035 static int
2036 cardbus_dma_map(dev_info_t *dip, dev_info_t *rdip,
2037                 struct ddi_dma_req *dmareqp, ddi_dma_handle_t *handlep)
2038 {
2039         dev_info_t *pdip = ddi_get_parent(dip);
2040 
2041         cardbus_err(dip, 10,
2042             "cardbus_dma_map(dip=0x%p, rdip=0x%p)\n",
2043             (void *) dip, (void *) rdip);
2044 
2045         if (pdip == NULL)
2046                 return (DDI_FAILURE);
2047 
2048         cardbus_err(dip, 11,
2049             "cardbus_dma_map calling %s - 0x%p\n",
2050             ddi_driver_name(pdip),
2051             (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_map);
2052 
2053         return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_map(pdip, rdip,
2054             dmareqp, handlep));
2055 }
2056 
2057 static int
2058 cardbus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
2059                 char *eventname, ddi_eventcookie_t *cookiep)
2060 {
2061         cbus_t *cbp;
2062         int     cb_instance;
2063         int     rc;
2064 
2065         /*
2066          * get the soft state structure for the bus instance.
2067          */
2068         cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2069             DDI_PROP_DONTPASS, "cbus-instance", -1);
2070         ASSERT(cb_instance >= 0);
2071         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
2072 
2073         cardbus_err(dip, 6, "cardbus_get_eventcookie %s\n", eventname);
2074 
2075         ASSERT(number_of_cardbus_cards != 0);
2076 
2077         if (cbp->cb_ndi_event_hdl == NULL) {
2078                 /*
2079                  * We can't handle up (probably called at the attachment
2080                  * point) so pass it on up
2081                  */
2082                 dev_info_t *pdip = ddi_get_parent(dip);
2083                 cardbus_err(dip, 8,
2084                     "cardbus_get_eventcookie calling %s - 0x%p\n",
2085                     ddi_driver_name(pdip),
2086                     (void *)
2087                     DEVI(pdip)->devi_ops->devo_bus_ops->bus_get_eventcookie);
2088                 return (DEVI(pdip)->devi_ops->devo_bus_ops->
2089                     bus_get_eventcookie(pdip, rdip, eventname, cookiep));
2090         }
2091 
2092         cardbus_err(dip, 8,
2093             "cardbus_get_eventcookie calling ndi_event_retrieve_cookie\n");
2094 
2095         rc = ndi_event_retrieve_cookie(cbp->cb_ndi_event_hdl, rdip, eventname,
2096             cookiep, NDI_EVENT_NOPASS);
2097 
2098         cardbus_err(dip, 7,
2099             "cardbus_get_eventcookie rc %d cookie %p\n", rc, (void *)*cookiep);
2100         return (rc);
2101 }
2102 
2103 static int
2104 cardbus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
2105                 ddi_eventcookie_t cookie, void (*callback)(dev_info_t *dip,
2106                 ddi_eventcookie_t cookie, void *arg, void *bus_impldata),
2107                 void *arg, ddi_callback_id_t *cb_id)
2108 {
2109         cbus_t *cbp;
2110         int     cb_instance;
2111         int     rc;
2112 
2113         /*
2114          * get the soft state structure for the bus instance.
2115          */
2116         cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2117             DDI_PROP_DONTPASS, "cbus-instance", -1);
2118         ASSERT(cb_instance >= 0);
2119         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
2120 
2121         cardbus_err(dip, 6, "cardbus_add_eventcall\n");
2122 
2123         ASSERT(number_of_cardbus_cards != 0);
2124 
2125         if (cbp->cb_ndi_event_hdl == NULL) {
2126                 /*
2127                  * We can't handle up (probably called at the attachment
2128                  * point) so pass it on up
2129                  */
2130                 dev_info_t *pdip = ddi_get_parent(dip);
2131                 cardbus_err(dip, 8,
2132                     "cardbus_add_eventcall calling %s - 0x%p\n",
2133                     ddi_driver_name(pdip),
2134                     (void *)
2135                     DEVI(pdip)->devi_ops->devo_bus_ops->bus_add_eventcall);
2136                 return (DEVI(pdip)->devi_ops->devo_bus_ops->
2137                     bus_add_eventcall(pdip, rdip, cookie, callback,
2138                     arg, cb_id));
2139         }
2140 
2141         cardbus_err(dip, 8,
2142             "cardbus_add_eventcall calling ndi_event_add_callback\n");
2143 
2144         rc = ndi_event_add_callback(cbp->cb_ndi_event_hdl, rdip, cookie,
2145             callback, arg, NDI_EVENT_NOPASS, cb_id);
2146         cardbus_err(dip, 7,
2147             "cardbus_add_eventcall rc %d cookie %p\n", rc, (void *)cookie);
2148         return (rc);
2149 }
2150 
2151 static int
2152 cardbus_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id)
2153 {
2154         cbus_t *cbp;
2155         int     cb_instance;
2156 
2157         /*
2158          * get the soft state structure for the bus instance.
2159          */
2160         cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2161             DDI_PROP_DONTPASS, "cbus-instance", -1);
2162         ASSERT(cb_instance >= 0);
2163         cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
2164 
2165         cardbus_err(dip, 6, "cardbus_remove_eventcall\n");
2166 
2167         ASSERT(number_of_cardbus_cards != 0);
2168 
2169         if (cbp->cb_ndi_event_hdl == NULL) {
2170                 /*
2171                  * We can't handle up (probably called at the attachment
2172                  * point) so pass it on up
2173                  */
2174                 dev_info_t *pdip = ddi_get_parent(dip);
2175                 cardbus_err(dip, 8,
2176                     "cardbus_remove_eventcall calling %s - 0x%p\n",
2177                     ddi_driver_name(pdip),
2178                     (void *)
2179                     DEVI(pdip)->devi_ops->devo_bus_ops->bus_remove_eventcall);
2180                 return (DEVI(pdip)->devi_ops->devo_bus_ops->
2181                     bus_remove_eventcall(pdip, cb_id));
2182         }
2183 
2184         return (ndi_event_remove_callback(cbp->cb_ndi_event_hdl, cb_id));
2185 }
2186 
2187 static int
2188 cardbus_post_event(dev_info_t *dip, dev_info_t *rdip,
2189                 ddi_eventcookie_t cookie, void *bus_impldata)
2190 {
2191         _NOTE(ARGUNUSED(rdip, cookie, bus_impldata))
2192         cardbus_err(dip, 1, "cardbus_post_event()\n");
2193         return (DDI_FAILURE);
2194 }
2195 
2196 static int cardbus_remove_intr_impl(dev_info_t *dip, dev_info_t *rdip,
2197                 ddi_intr_handle_impl_t *hdlp);
2198 static int cardbus_add_intr_impl(dev_info_t *dip, dev_info_t *rdip,
2199                 ddi_intr_handle_impl_t *hdlp);
2200 static int cardbus_enable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
2201                 ddi_intr_handle_impl_t *hdlp);
2202 static int cardbus_disable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
2203                 ddi_intr_handle_impl_t *hdlp);
2204 
2205 static int
2206 cardbus_get_pil(dev_info_t *dip)
2207 {
2208         return ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2209             "interrupt-priorities", 6);
2210 }
2211 
2212 static int
2213 cardbus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
2214         ddi_intr_handle_impl_t *hdlp, void *result)
2215 {
2216         int ret = DDI_SUCCESS;
2217 
2218 #if defined(CARDBUS_DEBUG)
2219         cardbus_err(dip, 8, "cardbus_intr_ops() intr_op=%d\n", (int)intr_op);
2220 #endif
2221 
2222         switch (intr_op) {
2223         case DDI_INTROP_GETCAP:
2224                 *(int *)result = DDI_INTR_FLAG_LEVEL;
2225                 break;
2226         case DDI_INTROP_ALLOC:
2227                 *(int *)result = hdlp->ih_scratch1;
2228                 break;
2229         case DDI_INTROP_FREE:
2230                 break;
2231         case DDI_INTROP_GETPRI:
2232                 *(int *)result = hdlp->ih_pri ?
2233                     hdlp->ih_pri : cardbus_get_pil(dip);
2234                 break;
2235         case DDI_INTROP_SETPRI:
2236                 break;
2237         case DDI_INTROP_ADDISR:
2238         case DDI_INTROP_REMISR:
2239                 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) {
2240                         cardbus_err(dip, 1, "Only fixed interrupts\n");
2241                         return (DDI_FAILURE);
2242                 }
2243                 break;
2244         case DDI_INTROP_ENABLE:
2245                 ret = cardbus_enable_intr_impl(dip, rdip, hdlp);
2246                 break;
2247         case DDI_INTROP_DISABLE:
2248                 ret = cardbus_disable_intr_impl(dip, rdip, hdlp);
2249                 break;
2250         case DDI_INTROP_NINTRS:
2251         case DDI_INTROP_NAVAIL:
2252 #ifdef sparc
2253                 *(int *)result = i_ddi_get_intx_nintrs(rdip);
2254 #else
2255                 *(int *)result = 1;
2256 #endif
2257                 break;
2258         case DDI_INTROP_SUPPORTED_TYPES:
2259                 *(int *)result = DDI_INTR_TYPE_FIXED;
2260                 break;
2261         default:
2262                 ret = DDI_ENOTSUP;
2263                 break;
2264         }
2265 
2266         return (ret);
2267 }
2268 
2269 static int
2270 cardbus_enable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
2271                 ddi_intr_handle_impl_t *hdlp)
2272 {
2273         anp_t *anp = (anp_t *)ddi_get_driver_private(dip);
2274         set_irq_handler_t sih;
2275         uint_t socket = 0; /* We only support devices */
2276                             /* with one socket per function */
2277 
2278         ASSERT(anp != NULL);
2279 
2280         cardbus_err(dip, 9,
2281             "cardbus_enable_intr_impl, intr=0x%p, arg1=0x%p, arg2=0x%p"
2282             "rdip=0x%p(%s)\n",
2283             (void *) hdlp->ih_cb_func,
2284             hdlp->ih_cb_arg1, hdlp->ih_cb_arg2,
2285             (void *) rdip, ddi_driver_name(rdip));
2286 
2287         if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) {
2288                 cardbus_err(dip, 1, "Only fixed interrupts\n");
2289                 return (DDI_FAILURE);
2290         }
2291 
2292         sih.socket = socket;
2293         sih.handler_id = (unsigned)(long)rdip;
2294         sih.handler = (f_tt *)hdlp->ih_cb_func;
2295         sih.arg1 = hdlp->ih_cb_arg1;
2296         sih.arg2 = hdlp->ih_cb_arg2;
2297         sih.irq = cardbus_get_pil(dip);
2298 
2299         if ((*anp->an_if->pcif_set_interrupt)(dip, &sih) != SUCCESS)
2300                 return (DDI_FAILURE);
2301 
2302         return (DDI_SUCCESS);
2303 }
2304 
2305 static int
2306 cardbus_disable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
2307                 ddi_intr_handle_impl_t *hdlp)
2308 {
2309         anp_t *anp = (anp_t *)ddi_get_driver_private(dip);
2310         clear_irq_handler_t cih;
2311         uint_t socket = 0; /* We only support devices with 1 socket per */
2312                             /* function. */
2313 
2314         ASSERT(anp != NULL);
2315 
2316         cardbus_err(dip, 9,
2317             "cardbus_disable_intr_impl, intr=0x%p, arg1=0x%p, arg2=0x%p"
2318             "rdip=0x%p(%s%d)\n",
2319             (void *) hdlp->ih_cb_func,
2320             hdlp->ih_cb_arg1, hdlp->ih_cb_arg2,
2321             (void *) rdip, ddi_driver_name(rdip), ddi_get_instance(rdip));
2322 
2323         if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) {
2324                 cardbus_err(dip, 1, "Only fixed interrupts\n");
2325                 return (DDI_FAILURE);
2326         }
2327 
2328         cih.socket = socket;
2329         cih.handler_id = (unsigned)(long)rdip;
2330         cih.handler = (f_tt *)hdlp->ih_cb_func;
2331 
2332         if ((*anp->an_if->pcif_clr_interrupt)(dip, &cih) != SUCCESS)
2333                 return (DDI_FAILURE);
2334 
2335         return (DDI_SUCCESS);
2336 }
2337 
2338 #if defined(CARDBUS_DEBUG)
2339 static int      cardbus_do_pprintf = 0;
2340 #endif
2341 
2342 /*PRINTFLIKE3*/
2343 void
2344 cardbus_err(dev_info_t *dip, int level, const char *fmt, ...)
2345 {
2346         if (cardbus_debug && (level <= cardbus_debug)) {
2347                 va_list adx;
2348                 int     instance;
2349                 char    buf[256];
2350                 const char      *name;
2351                 char    *nl = "";
2352 #if !defined(CARDBUS_DEBUG)
2353                 int     ce;
2354                 char    qmark = 0;
2355 
2356                 if (level <= 3)
2357                         ce = CE_WARN;
2358                 else
2359                         ce = CE_CONT;
2360                 if (level == 4)
2361                         qmark = 1;
2362 #endif
2363 
2364                 if (dip) {
2365                         instance = ddi_get_instance(dip);
2366                         /* name = ddi_binding_name(dip); */
2367                         name = ddi_driver_name(dip);
2368                 } else {
2369                         instance = 0;
2370                         name = "";
2371                 }
2372 
2373                 va_start(adx, fmt);
2374                 /* vcmn_err(ce, fmt, adx); */
2375                 /* vprintf(fmt, adx); */
2376                 /* prom_vprintf(fmt, adx); */
2377                 (void) vsprintf(buf, fmt, adx);
2378                 va_end(adx);
2379 
2380                 if (buf[strlen(buf) - 1] != '\n')
2381                         nl = "\n";
2382 
2383 #if defined(CARDBUS_DEBUG)
2384                 if (cardbus_do_pprintf) {
2385                         if (dip) {
2386                                 if (instance >= 0)
2387                                         prom_printf("%s(%d),0x%p: %s%s",
2388                                             name, instance, (void *)dip,
2389                                             buf, nl);
2390                                 else
2391                                         prom_printf("%s,0x%p: %s%s", name,
2392                                             (void *)dip, buf, nl);
2393                         } else
2394                                 prom_printf("%s%s", buf, nl);
2395                 } else {
2396                         if (dip) {
2397                                 if (instance >= 0)
2398                                         cmn_err(CE_CONT, "%s(%d),0x%p: %s%s",
2399                                             name, instance, (void *)dip,
2400                                             buf, nl);
2401                                 else
2402                                         cmn_err(CE_CONT, "%s,0x%p: %s%s",
2403                                             name, (void *)dip, buf, nl);
2404                         } else
2405                                 cmn_err(CE_CONT, "%s%s", buf, nl);
2406                 }
2407 #else
2408                 if (dip)
2409                         cmn_err(ce, qmark ? "?%s%d: %s%s" : "%s%d: %s%s",
2410                             name, instance, buf, nl);
2411                 else
2412                         cmn_err(ce, qmark ? "?%s%s" : "%s%s", buf, nl);
2413 #endif
2414         }
2415 }
2416 
2417 static void cardbus_expand_busrange(dev_info_t *dip)
2418 {
2419         dev_info_t *pdip;
2420         cardbus_bus_range_t *bus_range;
2421         int len;
2422 
2423         pdip = ddi_get_parent(dip);
2424 
2425         if (ddi_getlongprop(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, "bus-range",
2426             (caddr_t)&bus_range, &len) == DDI_PROP_SUCCESS) {
2427                 ndi_ra_request_t req;
2428                 uint64_t next_bus, blen;
2429                 uint32_t ret;
2430                 ddi_acc_handle_t handle;
2431 
2432                 if (bus_range->lo != bus_range->hi)
2433                         cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2434                             "%u -> %u\n", bus_range->lo, bus_range->hi);
2435                 else {
2436 
2437                         bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
2438                         req.ra_addr = bus_range->lo + 1;
2439                         req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
2440                         req.ra_len = 12;
2441 
2442                         while ((req.ra_len > 0) &&
2443                             (ret = ndi_ra_alloc(ddi_get_parent(pdip), &req,
2444                             &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
2445                             NDI_RA_PASS)) != NDI_SUCCESS)
2446                                 req.ra_len--;
2447 
2448                         if (ret != NDI_SUCCESS) {
2449                                 cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2450                                     "fail to allocate bus number\n");
2451                                 goto exit;
2452                         }
2453 
2454                         bus_range->hi = bus_range->lo + req.ra_len;
2455                         if (ndi_prop_update_int_array(DDI_DEV_T_NONE, pdip,
2456                             "bus-range", (int *)bus_range, 2) != DDI_SUCCESS) {
2457                                 cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2458                                     "fail to update bus-range property\n");
2459                                 goto exit;
2460                         }
2461 
2462                         if (pci_config_setup(pdip, &handle) != DDI_SUCCESS) {
2463                                 cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2464                                     "fail to pci_config_setup\n");
2465                                 goto exit;
2466                         }
2467 
2468                         pci_config_put8(handle, PCI_BCNF_SECBUS, bus_range->lo);
2469                         pci_config_put8(handle, PCI_BCNF_SUBBUS, bus_range->hi);
2470 
2471                         cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2472                             "parent dip %u -> %u\n",
2473                             pci_config_get8(handle, PCI_BCNF_SECBUS),
2474                             pci_config_get8(handle, PCI_BCNF_SUBBUS));
2475                         pci_config_teardown(&handle);
2476 
2477                         if (ndi_ra_map_setup(pdip, NDI_RA_TYPE_PCI_BUSNUM)
2478                             != NDI_SUCCESS) {
2479                                 cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2480                                     "fail to ndi_ra_map_setup of bus number\n");
2481                                 goto exit;
2482                         }
2483 
2484                         (void) ndi_ra_free(pdip,
2485                             (uint64_t)bus_range->lo + 1, req.ra_len,
2486                             NDI_RA_TYPE_PCI_BUSNUM, 0);
2487                 }
2488 
2489                 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
2490                 req.ra_len = 2;
2491 
2492                 while ((req.ra_len > 0) &&
2493                     (ret = ndi_ra_alloc(pdip, &req,
2494                     &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
2495                     0)) != NDI_SUCCESS)
2496                         req.ra_len--;
2497 
2498                 cardbus_err(dip, 1, "cardbus_expand_busrange: "
2499                     "cardbus dip base %u length %d\n",
2500                     (int)next_bus, (int)req.ra_len);
2501 
2502                 if (ret != NDI_SUCCESS) {
2503                         cardbus_err(dip, 1, "cardbus_expand_busrange: "
2504                             "fail to allocate bus number of length %d "
2505                             "from parent\n",
2506                             (int)req.ra_len);
2507                         goto exit;
2508                 }
2509 
2510                 if (ndi_ra_map_setup(dip, NDI_RA_TYPE_PCI_BUSNUM)
2511                     != NDI_SUCCESS) {
2512                         cardbus_err(dip, 1, "cardbus_expand_busrange: "
2513                             "fail to ndi_ra_map_setup of bus numbers\n");
2514                         goto exit;
2515                 }
2516 
2517                 (void) ndi_ra_free(dip,
2518                     (uint64_t)next_bus, req.ra_len,
2519                     NDI_RA_TYPE_PCI_BUSNUM, 0);
2520 exit:
2521                 kmem_free(bus_range, len);
2522 
2523         } else
2524                 cardbus_err(pdip, 1, "cardbus_expand_busrange: "
2525                     "parent dip doesn't have busrange prop\n");
2526 }