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