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