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