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