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