58#define DPRINTF(arg) if (pccard_debug) printf arg 59#define DEVPRINTF(arg) if (pccard_debug) device_printf arg 60#define PRVERBOSE(arg) printf arg 61#define DEVPRVERBOSE(arg) device_printf arg 62#else 63#define DPRINTF(arg) 64#define DEVPRINTF(arg) 65#define PRVERBOSE(arg) if (bootverbose) printf arg 66#define DEVPRVERBOSE(arg) if (bootverbose) device_printf arg 67#endif 68 69static int pccard_ccr_read(struct pccard_function *pf, int ccr); 70static void pccard_ccr_write(struct pccard_function *pf, int ccr, int val); 71static int pccard_attach_card(device_t dev); 72static int pccard_detach_card(device_t dev, int flags); 73static int pccard_card_gettype(device_t dev, int *type); 74static void pccard_function_init(struct pccard_function *pf); 75static void pccard_function_free(struct pccard_function *pf); 76static int pccard_function_enable(struct pccard_function *pf); 77static void pccard_function_disable(struct pccard_function *pf); 78static int pccard_compat_do_probe(device_t bus, device_t dev); 79static int pccard_compat_do_attach(device_t bus, device_t dev); 80static int pccard_add_children(device_t dev, int busno); 81static int pccard_probe(device_t dev); 82static int pccard_attach(device_t dev); 83static int pccard_detach(device_t dev); 84static void pccard_print_resources(struct resource_list *rl, 85 const char *name, int type, int count, const char *format); 86static int pccard_print_child(device_t dev, device_t child); 87static int pccard_set_resource(device_t dev, device_t child, int type, 88 int rid, u_long start, u_long count); 89static int pccard_get_resource(device_t dev, device_t child, int type, 90 int rid, u_long *startp, u_long *countp); 91static void pccard_delete_resource(device_t dev, device_t child, int type, 92 int rid); 93static int pccard_set_res_flags(device_t dev, device_t child, int type, 94 int rid, u_int32_t flags); 95static int pccard_set_memory_offset(device_t dev, device_t child, int rid, 96 u_int32_t offset, u_int32_t *deltap); 97static int pccard_read_ivar(device_t bus, device_t child, int which, 98 u_char *result); 99static void pccard_driver_added(device_t dev, driver_t *driver); 100static struct resource *pccard_alloc_resource(device_t dev, 101 device_t child, int type, int *rid, u_long start, 102 u_long end, u_long count, u_int flags); 103static int pccard_release_resource(device_t dev, device_t child, int type, 104 int rid, struct resource *r); 105static void pccard_child_detached(device_t parent, device_t dev); 106static void pccard_intr(void *arg); 107static int pccard_setup_intr(device_t dev, device_t child, 108 struct resource *irq, int flags, driver_intr_t *intr, 109 void *arg, void **cookiep); 110static int pccard_teardown_intr(device_t dev, device_t child, 111 struct resource *r, void *cookie); 112 113static int 114pccard_ccr_read(struct pccard_function *pf, int ccr) 115{ 116 return (bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh, 117 pf->pf_ccr_offset + ccr)); 118} 119 120static void 121pccard_ccr_write(struct pccard_function *pf, int ccr, int val) 122{ 123 if ((pf->ccr_mask) & (1 << (ccr / 2))) { 124 bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh, 125 pf->pf_ccr_offset + ccr, val); 126 } 127} 128 129static int 130pccard_attach_card(device_t dev) 131{ 132 struct pccard_softc *sc = PCCARD_SOFTC(dev); 133 struct pccard_function *pf; 134 struct pccard_ivar *ivar; 135 device_t child; 136 137 /* 138 * this is here so that when socket_enable calls gettype, trt happens 139 */ 140 STAILQ_INIT(&sc->card.pf_head); 141 142 DEVPRINTF((dev, "chip_socket_enable\n")); 143 POWER_ENABLE_SOCKET(device_get_parent(dev), dev); 144 145 DEVPRINTF((dev, "read_cis\n")); 146 pccard_read_cis(sc); 147 148 DEVPRINTF((dev, "check_cis_quirks\n")); 149 pccard_check_cis_quirks(dev); 150 151 /* 152 * bail now if the card has no functions, or if there was an error in 153 * the cis. 154 */ 155 156 if (sc->card.error) { 157 device_printf (dev, "CARD ERROR!\n"); 158 return (1); 159 } 160 if (STAILQ_EMPTY(&sc->card.pf_head)) { 161 device_printf (dev, "Card has no functions!\n"); 162 return (1); 163 } 164 165 if (bootverbose || pccard_debug) 166 pccard_print_cis(dev); 167 168 DEVPRINTF((dev, "functions scanning\n")); 169 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 170 if (STAILQ_EMPTY(&pf->cfe_head)) 171 continue; 172 173 pf->sc = sc; 174 pf->cfe = NULL; 175 pf->dev = NULL; 176 } 177 178 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 179 if (STAILQ_EMPTY(&pf->cfe_head)) 180 continue; 181 /* 182 * In NetBSD, the drivers are responsible for activating 183 * each function of a card. I think that in FreeBSD we 184 * want to activate them enough for the usual bus_*_resource 185 * routines will do the right thing. This many mean a 186 * departure from the current NetBSD model. 187 * 188 * This could get really ugly for multifunction cards. But 189 * it might also just fall out of the FreeBSD resource model. 190 * 191 */ 192 ivar = malloc(sizeof(struct pccard_ivar), M_DEVBUF, 193 M_WAITOK | M_ZERO); 194 child = device_add_child(dev, NULL, -1); 195 device_set_ivars(child, ivar); 196 ivar->fcn = pf; 197 pf->dev = child; 198 /* 199 * XXX We might want to move the next two lines into 200 * XXX the pccard interface layer. For the moment, this 201 * XXX is OK, but some drivers want to pick the config 202 * XXX entry to use as well as some address tweaks (mostly 203 * XXX due to bugs in decode logic that makes some 204 * XXX addresses illegal or broken). 205 */ 206 pccard_function_init(pf); 207 if (sc->sc_enabled_count == 0) 208 POWER_ENABLE_SOCKET(device_get_parent(dev), dev); 209 if (pccard_function_enable(pf) == 0 && 210 device_probe_and_attach(child) == 0) { 211 DEVPRINTF((sc->dev, "function %d CCR at %d " 212 "offset %x: %x %x %x %x, %x %x %x %x, %x\n", 213 pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, 214 pccard_ccr_read(pf, 0x00), 215 pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), 216 pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), 217 pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), 218 pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12))); 219 } else { 220 if (pf->cfe != NULL) 221 pccard_function_disable(pf); 222 } 223 } 224 if (sc->sc_enabled_count == 0) 225 pccard_detach_card(dev, 0); 226 return (0); 227} 228 229static int 230pccard_detach_card(device_t dev, int flags) 231{ 232 struct pccard_softc *sc = PCCARD_SOFTC(dev); 233 struct pccard_function *pf; 234 struct pccard_config_entry *cfe; 235 236 /* 237 * We are running on either the PCCARD socket's event thread 238 * or in user context detaching a device by user request. 239 */ 240 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 241 int state = device_get_state(pf->dev); 242 243 if (state == DS_ATTACHED || state == DS_BUSY) 244 device_detach(pf->dev); 245 if (pf->cfe != NULL) 246 pccard_function_disable(pf); 247 pccard_function_free(pf); 248 if (pf->dev != NULL) 249 device_delete_child(dev, pf->dev); 250 } 251 if (sc->sc_enabled_count == 0) 252 POWER_DISABLE_SOCKET(device_get_parent(dev), dev); 253 254 while (NULL != (pf = STAILQ_FIRST(&sc->card.pf_head))) { 255 while (NULL != (cfe = STAILQ_FIRST(&pf->cfe_head))) { 256 STAILQ_REMOVE_HEAD(&pf->cfe_head, cfe_list); 257 free(cfe, M_DEVBUF); 258 } 259 STAILQ_REMOVE_HEAD(&sc->card.pf_head, pf_list); 260 free(pf, M_DEVBUF); 261 } 262 return (0); 263} 264 265const struct pccard_product * 266pccard_product_lookup(device_t dev, const struct pccard_product *tab, 267 size_t ent_size, pccard_product_match_fn matchfn) 268{ 269 const struct pccard_product *ent; 270 int matches; 271 u_int32_t fcn; 272 u_int32_t vendor; 273 u_int32_t prod; 274 char *vendorstr; 275 char *prodstr; 276 277#ifdef DIAGNOSTIC 278 if (sizeof *ent > ent_size) 279 panic("pccard_product_lookup: bogus ent_size %ld", 280 (long) ent_size); 281#endif 282 if (pccard_get_vendor(dev, &vendor)) 283 return (NULL); 284 if (pccard_get_product(dev, &prod)) 285 return (NULL); 286 if (pccard_get_function_number(dev, &fcn)) 287 return (NULL); 288 if (pccard_get_vendor_str(dev, &vendorstr)) 289 return (NULL); 290 if (pccard_get_product_str(dev, &prodstr)) 291 return (NULL); 292 for (ent = tab; ent->pp_name != NULL; ent = 293 (const struct pccard_product *) ((const char *) ent + ent_size)) { 294 matches = 1; 295 if (ent->pp_vendor == PCCARD_VENDOR_ANY && 296 ent->pp_product == PCCARD_VENDOR_ANY && 297 ent->pp_cis[0] == NULL && 298 ent->pp_cis[1] == NULL) { 299 device_printf(dev, 300 "Total wildcard entry ignored for %s\n", 301 ent->pp_name); 302 continue; 303 } 304 if (matches && ent->pp_vendor != PCCARD_VENDOR_ANY && 305 vendor != ent->pp_vendor) 306 matches = 0; 307 if (matches && ent->pp_product != PCCARD_PRODUCT_ANY && 308 prod != ent->pp_product) 309 matches = 0; 310 if (matches && fcn != ent->pp_expfunc) 311 matches = 0; 312 if (matches && ent->pp_cis[0] && 313 strcmp(ent->pp_cis[0], vendorstr) != 0) 314 matches = 0; 315 if (matches && ent->pp_cis[1] && 316 strcmp(ent->pp_cis[1], prodstr) != 0) 317 matches = 0; 318 /* XXX need to match cis[2] and cis[3] also XXX */ 319 if (matchfn != NULL) 320 matches = (*matchfn)(dev, ent, matches); 321 if (matches) 322 return (ent); 323 } 324 return (NULL); 325} 326 327static int 328pccard_card_gettype(device_t dev, int *type) 329{ 330 struct pccard_softc *sc = PCCARD_SOFTC(dev); 331 struct pccard_function *pf; 332 333 /* 334 * set the iftype to memory if this card has no functions (not yet 335 * probed), or only one function, and that is not initialized yet or 336 * that is memory. 337 */ 338 pf = STAILQ_FIRST(&sc->card.pf_head); 339 if (pf == NULL || 340 (STAILQ_NEXT(pf, pf_list) == NULL && 341 (pf->cfe == NULL || pf->cfe->iftype == PCCARD_IFTYPE_MEMORY))) 342 *type = PCCARD_IFTYPE_MEMORY; 343 else 344 *type = PCCARD_IFTYPE_IO; 345 return (0); 346} 347 348/* 349 * Initialize a PCCARD function. May be called as long as the function is 350 * disabled. 351 * 352 * Note: pccard_function_init should not keep resources allocated. It should 353 * only set them up ala isa pnp, set the values in the rl lists, and return. 354 * Any resource held after pccard_function_init is called is a bug. However, 355 * the bus routines to get the resources also assume that pccard_function_init 356 * does this, so they need to be fixed too. 357 */ 358static void 359pccard_function_init(struct pccard_function *pf) 360{ 361 struct pccard_config_entry *cfe; 362 int i; 363 struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); 364 struct resource_list *rl = &devi->resources; 365 struct resource_list_entry *rle; 366 struct resource *r = 0; 367 device_t bus; 368 int start; 369 int end; 370 int spaces; 371 372 if (pf->pf_flags & PFF_ENABLED) { 373 printf("pccard_function_init: function is enabled"); 374 return; 375 } 376 bus = device_get_parent(pf->dev); 377 /* Remember which configuration entry we are using. */ 378 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { 379 for (i = 0; i < cfe->num_iospace; i++) 380 cfe->iores[i] = NULL; 381 cfe->irqres = NULL; 382 spaces = 0; 383 for (i = 0; i < cfe->num_iospace; i++) { 384 start = cfe->iospace[i].start; 385 if (start) 386 end = start + cfe->iospace[i].length - 1; 387 else 388 end = ~0; 389 cfe->iorid[i] = i; 390 DEVPRINTF((bus, "I/O rid %d start %x end %x\n", 391 i, start, end)); 392 r = cfe->iores[i] = bus_alloc_resource(bus, 393 SYS_RES_IOPORT, &cfe->iorid[i], start, end, 394 cfe->iospace[i].length, 395 rman_make_alignment_flags(cfe->iospace[i].length)); 396 if (cfe->iores[i] == NULL) 397 goto not_this_one; 398 resource_list_add(rl, SYS_RES_IOPORT, cfe->iorid[i], 399 rman_get_start(r), rman_get_end(r), 400 cfe->iospace[i].length); 401 rle = resource_list_find(rl, SYS_RES_IOPORT, 402 cfe->iorid[i]); 403 rle->res = r; 404 spaces++; 405 } 406 if (cfe->num_memspace > 0) { 407 /* 408 * Not implement yet, Fix me. 409 */ 410 DEVPRINTF((bus, "Memory space not yet implemented.\n")); 411 } 412 if (spaces == 0) { 413 DEVPRINTF((bus, "Neither memory nor I/O mampped\n")); 414 goto not_this_one; 415 } 416 if (cfe->irqmask) { 417 cfe->irqrid = 0; 418 r = cfe->irqres = bus_alloc_resource(bus, SYS_RES_IRQ, 419 &cfe->irqrid, 0, ~0, 1, 0); 420 if (cfe->irqres == NULL) 421 goto not_this_one; 422 resource_list_add(rl, SYS_RES_IRQ, cfe->irqrid, 423 rman_get_start(r), rman_get_end(r), 1); 424 rle = resource_list_find(rl, SYS_RES_IRQ, 425 cfe->irqrid); 426 rle->res = r; 427 } 428 /* If we get to here, we've allocated all we need */ 429 pf->cfe = cfe; 430 break; 431 not_this_one:; 432 DEVPRVERBOSE((bus, "Allocation failed for cfe %d\n", 433 cfe->number)); 434 /* 435 * Release resources that we partially allocated 436 * from this config entry. 437 */ 438 for (i = 0; i < cfe->num_iospace; i++) { 439 if (cfe->iores[i] != NULL) { 440 bus_release_resource(bus, SYS_RES_IOPORT, 441 cfe->iorid[i], cfe->iores[i]); 442 rle = resource_list_find(rl, SYS_RES_IOPORT, 443 cfe->iorid[i]); 444 rle->res = NULL; 445 resource_list_delete(rl, SYS_RES_IOPORT, 446 cfe->iorid[i]); 447 } 448 cfe->iores[i] = NULL; 449 } 450 if (cfe->irqmask && cfe->irqres != NULL) { 451 bus_release_resource(bus, SYS_RES_IRQ, 452 cfe->irqrid, cfe->irqres); 453 rle = resource_list_find(rl, SYS_RES_IRQ, 454 cfe->irqrid); 455 rle->res = NULL; 456 resource_list_delete(rl, SYS_RES_IRQ, cfe->irqrid); 457 cfe->irqres = NULL; 458 } 459 } 460} 461 462/* 463 * Free resources allocated by pccard_function_init(), May be called as long 464 * as the function is disabled. 465 * 466 * NOTE: This function should be unnecessary. pccard_function_init should 467 * never keep resources initialized. 468 */ 469static void 470pccard_function_free(struct pccard_function *pf) 471{ 472 struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); 473 struct resource_list_entry *rle; 474 475 if (pf->pf_flags & PFF_ENABLED) { 476 printf("pccard_function_init: function is enabled"); 477 return; 478 } 479 480 SLIST_FOREACH(rle, &devi->resources, link) { 481 if (rle->res) { 482 if (rle->res->r_dev != pf->sc->dev) 483 device_printf(pf->sc->dev, 484 "function_free: Resource still owned by " 485 "child, oops. " 486 "(type=%d, rid=%d, addr=%lx)\n", 487 rle->type, rle->rid, 488 rman_get_start(rle->res)); 489 BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev), 490 rle->res->r_dev, rle->type, rle->rid, rle->res); 491 rle->res = NULL; 492 } 493 } 494 resource_list_free(&devi->resources); 495} 496 497/* Enable a PCCARD function */ 498static int 499pccard_function_enable(struct pccard_function *pf) 500{ 501 struct pccard_function *tmp; 502 int reg; 503 device_t dev = pf->sc->dev; 504 505 if (pf->cfe == NULL) { 506 DEVPRVERBOSE((dev, "No config entry could be allocated.\n")); 507 return (ENOMEM); 508 } 509 510 /* 511 * Increase the reference count on the socket, enabling power, if 512 * necessary. 513 */ 514 pf->sc->sc_enabled_count++; 515 516 if (pf->pf_flags & PFF_ENABLED) { 517 /* 518 * Don't do anything if we're already enabled. 519 */ 520 return (0); 521 } 522 523 /* 524 * it's possible for different functions' CCRs to be in the same 525 * underlying page. Check for that. 526 */ 527 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 528 if ((tmp->pf_flags & PFF_ENABLED) && 529 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) && 530 ((pf->ccr_base + PCCARD_CCR_SIZE) <= 531 (tmp->ccr_base - tmp->pf_ccr_offset + 532 tmp->pf_ccr_realsize))) { 533 pf->pf_ccrt = tmp->pf_ccrt; 534 pf->pf_ccrh = tmp->pf_ccrh; 535 pf->pf_ccr_realsize = tmp->pf_ccr_realsize; 536 537 /* 538 * pf->pf_ccr_offset = (tmp->pf_ccr_offset - 539 * tmp->ccr_base) + pf->ccr_base; 540 */ 541 /* pf->pf_ccr_offset = 542 (tmp->pf_ccr_offset + pf->ccr_base) - 543 tmp->ccr_base; */ 544 pf->pf_ccr_window = tmp->pf_ccr_window; 545 break; 546 } 547 } 548 if (tmp == NULL) { 549 pf->ccr_rid = 0; 550 pf->ccr_res = bus_alloc_resource(dev, SYS_RES_MEMORY, 551 &pf->ccr_rid, 0, ~0, 1 << 10, RF_ACTIVE); 552 if (!pf->ccr_res) 553 goto bad; 554 DEVPRINTF((dev, "ccr_res == %lx-%lx, base=%lx\n", 555 rman_get_start(pf->ccr_res), rman_get_end(pf->ccr_res), 556 pf->ccr_base)); 557 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY, 558 pf->ccr_rid, PCCARD_A_MEM_ATTR); 559 CARD_SET_MEMORY_OFFSET(device_get_parent(dev), dev, 560 pf->ccr_rid, pf->ccr_base, &pf->pf_ccr_offset); 561 pf->pf_ccrt = rman_get_bustag(pf->ccr_res); 562 pf->pf_ccrh = rman_get_bushandle(pf->ccr_res); 563 pf->pf_ccr_realsize = 1; 564 } 565 566 reg = (pf->cfe->number & PCCARD_CCR_OPTION_CFINDEX); 567 reg |= PCCARD_CCR_OPTION_LEVIREQ; 568 if (pccard_mfc(pf->sc)) { 569 reg |= (PCCARD_CCR_OPTION_FUNC_ENABLE | 570 PCCARD_CCR_OPTION_ADDR_DECODE); 571 /* PCCARD_CCR_OPTION_IRQ_ENABLE set elsewhere as needed */ 572 } 573 pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg); 574 575 reg = 0; 576 if ((pf->cfe->flags & PCCARD_CFE_IO16) == 0) 577 reg |= PCCARD_CCR_STATUS_IOIS8; 578 if (pf->cfe->flags & PCCARD_CFE_AUDIO) 579 reg |= PCCARD_CCR_STATUS_AUDIO; 580 pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg); 581 582 pccard_ccr_write(pf, PCCARD_CCR_SOCKETCOPY, 0); 583 584 if (pccard_mfc(pf->sc)) { 585 long tmp, iosize; 586 587 tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; 588 /* round up to nearest (2^n)-1 */ 589 for (iosize = 1; iosize < tmp; iosize <<= 1) 590 ; 591 iosize--; 592 593 pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, 594 pf->pf_mfc_iobase & 0xff); 595 pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, 596 (pf->pf_mfc_iobase >> 8) & 0xff); 597 pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); 598 pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); 599 600 pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); 601 } 602 603#ifdef PCCARDDEBUG 604 if (pccard_debug) { 605 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 606 device_printf(tmp->sc->dev, 607 "function %d CCR at %d offset %x: " 608 "%x %x %x %x, %x %x %x %x, %x\n", 609 tmp->number, tmp->pf_ccr_window, 610 tmp->pf_ccr_offset, 611 pccard_ccr_read(tmp, 0x00), 612 pccard_ccr_read(tmp, 0x02), 613 pccard_ccr_read(tmp, 0x04), 614 pccard_ccr_read(tmp, 0x06), 615 pccard_ccr_read(tmp, 0x0A), 616 pccard_ccr_read(tmp, 0x0C), 617 pccard_ccr_read(tmp, 0x0E), 618 pccard_ccr_read(tmp, 0x10), 619 pccard_ccr_read(tmp, 0x12)); 620 } 621 } 622#endif 623 pf->pf_flags |= PFF_ENABLED; 624 return (0); 625 626 bad: 627 /* 628 * Decrement the reference count, and power down the socket, if 629 * necessary. 630 */ 631 pf->sc->sc_enabled_count--; 632 DEVPRINTF((dev, "bad --enabled_count = %d\n", pf->sc->sc_enabled_count)); 633 634 return (1); 635} 636 637/* Disable PCCARD function. */ 638static void 639pccard_function_disable(struct pccard_function *pf) 640{ 641 struct pccard_function *tmp; 642 device_t dev = pf->sc->dev; 643 644 if (pf->cfe == NULL) 645 panic("pccard_function_disable: function not initialized"); 646 647 if ((pf->pf_flags & PFF_ENABLED) == 0) { 648 /* 649 * Don't do anything if we're already disabled. 650 */ 651 return; 652 } 653 654 if (pf->intr_handler != NULL) { 655 struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); 656 struct resource_list_entry *rle = 657 resource_list_find(&devi->resources, SYS_RES_IRQ, 0); 658 BUS_TEARDOWN_INTR(dev, pf->dev, rle->res, 659 pf->intr_handler_cookie); 660 } 661 662 /* 663 * it's possible for different functions' CCRs to be in the same 664 * underlying page. Check for that. Note we mark us as disabled 665 * first to avoid matching ourself. 666 */ 667 668 pf->pf_flags &= ~PFF_ENABLED; 669 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 670 if ((tmp->pf_flags & PFF_ENABLED) && 671 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) && 672 ((pf->ccr_base + PCCARD_CCR_SIZE) <= 673 (tmp->ccr_base - tmp->pf_ccr_offset + 674 tmp->pf_ccr_realsize))) 675 break; 676 } 677 678 /* Not used by anyone else; unmap the CCR. */ 679 if (tmp == NULL) { 680 bus_release_resource(dev, SYS_RES_MEMORY, pf->ccr_rid, 681 pf->ccr_res); 682 pf->ccr_res = NULL; 683 } 684 685 /* 686 * Decrement the reference count, and power down the socket, if 687 * necessary. 688 */ 689 pf->sc->sc_enabled_count--; 690} 691 692#if 0 693/* XXX These functions are needed, but not like this XXX */ 694int 695pccard_io_map(struct pccard_function *pf, int width, bus_addr_t offset, 696 bus_size_t size, struct pccard_io_handle *pcihp, int *windowp) 697{ 698 int reg; 699 700 if (pccard_chip_io_map(pf->sc->pct, pf->sc->pch, width, offset, size, 701 pcihp, windowp)) 702 return (1); 703 704 /* 705 * XXX in the multifunction multi-iospace-per-function case, this 706 * needs to cooperate with io_alloc to make sure that the spaces 707 * don't overlap, and that the ccr's are set correctly 708 */ 709 710 if (pccard_mfc(pf->sc)) { 711 long tmp, iosize; 712 713 if (pf->pf_mfc_iomax == 0) { 714 pf->pf_mfc_iobase = pcihp->addr + offset; 715 pf->pf_mfc_iomax = pf->pf_mfc_iobase + size; 716 } else { 717 /* this makes the assumption that nothing overlaps */ 718 if (pf->pf_mfc_iobase > pcihp->addr + offset) 719 pf->pf_mfc_iobase = pcihp->addr + offset; 720 if (pf->pf_mfc_iomax < pcihp->addr + offset + size) 721 pf->pf_mfc_iomax = pcihp->addr + offset + size; 722 } 723 724 tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; 725 /* round up to nearest (2^n)-1 */ 726 for (iosize = 1; iosize >= tmp; iosize <<= 1) 727 ; 728 iosize--; 729 730 pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, 731 pf->pf_mfc_iobase & 0xff); 732 pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, 733 (pf->pf_mfc_iobase >> 8) & 0xff); 734 pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); 735 pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); 736 737 pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); 738 739 reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION); 740 reg |= PCCARD_CCR_OPTION_ADDR_DECODE; 741 pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg); 742 } 743 return (0); 744} 745 746void 747pccard_io_unmap(struct pccard_function *pf, int window) 748{ 749 750 pccard_chip_io_unmap(pf->sc->pct, pf->sc->pch, window); 751 752 /* XXX Anything for multi-function cards? */ 753} 754#endif 755 756/* 757 * simulate the old "probe" routine. In the new world order, the driver 758 * needs to grab devices while in the old they were assigned to the device by 759 * the pccardd process. These symbols are exported to the upper layers. 760 */ 761static int 762pccard_compat_do_probe(device_t bus, device_t dev) 763{ 764 return (CARD_COMPAT_MATCH(dev)); 765} 766 767static int 768pccard_compat_do_attach(device_t bus, device_t dev) 769{ 770 int err; 771 772 err = CARD_COMPAT_PROBE(dev); 773 if (err == 0) 774 err = CARD_COMPAT_ATTACH(dev); 775 return (err); 776} 777 778#define PCCARD_NPORT 2 779#define PCCARD_NMEM 5 780#define PCCARD_NIRQ 1 781#define PCCARD_NDRQ 0 782 783static int 784pccard_add_children(device_t dev, int busno) 785{ 786 /* Call parent to scan for any current children */ 787 return (0); 788} 789 790static int 791pccard_probe(device_t dev) 792{ 793 device_set_desc(dev, "16-bit PCCard bus"); 794 return (pccard_add_children(dev, device_get_unit(dev))); 795} 796 797static int 798pccard_attach(device_t dev) 799{ 800 struct pccard_softc *sc = PCCARD_SOFTC(dev); 801 802 sc->dev = dev; 803 sc->sc_enabled_count = 0; 804 return (bus_generic_attach(dev)); 805} 806 807static int 808pccard_detach(device_t dev) 809{ 810 pccard_detach_card(dev, 0); 811 return 0; 812} 813 814static int 815pccard_suspend(device_t self) 816{ 817 pccard_detach_card(self, 0); 818 return (0); 819} 820 821static 822int 823pccard_resume(device_t self) 824{ 825 return (0); 826} 827 828static void 829pccard_print_resources(struct resource_list *rl, const char *name, int type, 830 int count, const char *format) 831{ 832 struct resource_list_entry *rle; 833 int printed; 834 int i; 835 836 printed = 0; 837 for (i = 0; i < count; i++) { 838 rle = resource_list_find(rl, type, i); 839 if (rle != NULL) { 840 if (printed == 0) 841 printf(" %s ", name); 842 else if (printed > 0) 843 printf(","); 844 printed++; 845 printf(format, rle->start); 846 if (rle->count > 1) { 847 printf("-"); 848 printf(format, rle->start + rle->count - 1); 849 } 850 } else if (i > 3) { 851 /* check the first few regardless */ 852 break; 853 } 854 } 855} 856 857static int 858pccard_print_child(device_t dev, device_t child) 859{ 860 struct pccard_ivar *devi = PCCARD_IVAR(child); 861 struct resource_list *rl = &devi->resources; 862 int retval = 0; 863 864 retval += bus_print_child_header(dev, child); 865 retval += printf(" at"); 866 867 if (devi != NULL) { 868 pccard_print_resources(rl, "port", SYS_RES_IOPORT, 869 PCCARD_NPORT, "%#lx"); 870 pccard_print_resources(rl, "iomem", SYS_RES_MEMORY, 871 PCCARD_NMEM, "%#lx"); 872 pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ, 873 "%ld"); 874 pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ, 875 "%ld"); 876 retval += printf(" function %d config %d", devi->fcn->number, 877 devi->fcn->cfe->number); 878 } 879 880 retval += bus_print_child_footer(dev, child); 881 882 return (retval); 883} 884 885static int 886pccard_set_resource(device_t dev, device_t child, int type, int rid, 887 u_long start, u_long count) 888{ 889 struct pccard_ivar *devi = PCCARD_IVAR(child); 890 struct resource_list *rl = &devi->resources; 891 892 if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY 893 && type != SYS_RES_IRQ && type != SYS_RES_DRQ) 894 return (EINVAL); 895 if (rid < 0) 896 return (EINVAL); 897 if (type == SYS_RES_IOPORT && rid >= PCCARD_NPORT) 898 return (EINVAL); 899 if (type == SYS_RES_MEMORY && rid >= PCCARD_NMEM) 900 return (EINVAL); 901 if (type == SYS_RES_IRQ && rid >= PCCARD_NIRQ) 902 return (EINVAL); 903 if (type == SYS_RES_DRQ && rid >= PCCARD_NDRQ) 904 return (EINVAL); 905 906 resource_list_add(rl, type, rid, start, start + count - 1, count); 907 if (NULL != resource_list_alloc(rl, device_get_parent(dev), dev, 908 type, &rid, start, start + count - 1, count, 0)) 909 return 0; 910 else 911 return ENOMEM; 912} 913 914static int 915pccard_get_resource(device_t dev, device_t child, int type, int rid, 916 u_long *startp, u_long *countp) 917{ 918 struct pccard_ivar *devi = PCCARD_IVAR(child); 919 struct resource_list *rl = &devi->resources; 920 struct resource_list_entry *rle; 921 922 rle = resource_list_find(rl, type, rid); 923 if (rle == NULL) 924 return (ENOENT); 925 926 if (startp != NULL) 927 *startp = rle->start; 928 if (countp != NULL) 929 *countp = rle->count; 930 931 return (0); 932} 933 934static void 935pccard_delete_resource(device_t dev, device_t child, int type, int rid) 936{ 937 struct pccard_ivar *devi = PCCARD_IVAR(child); 938 struct resource_list *rl = &devi->resources; 939 resource_list_delete(rl, type, rid); 940} 941 942static int 943pccard_set_res_flags(device_t dev, device_t child, int type, int rid, 944 u_int32_t flags) 945{ 946 return (CARD_SET_RES_FLAGS(device_get_parent(dev), child, type, 947 rid, flags)); 948} 949 950static int 951pccard_set_memory_offset(device_t dev, device_t child, int rid, 952 u_int32_t offset, u_int32_t *deltap) 953 954{ 955 return (CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid, 956 offset, deltap)); 957} 958 959static int 960pccard_read_ivar(device_t bus, device_t child, int which, u_char *result) 961{ 962 struct pccard_ivar *devi = PCCARD_IVAR(child); 963 struct pccard_function *func = devi->fcn; 964 struct pccard_softc *sc = PCCARD_SOFTC(bus); 965 966 /* PCCARD_IVAR_ETHADDR unhandled from oldcard */ 967 switch (which) { 968 default: 969 case PCCARD_IVAR_ETHADDR: 970 bcopy(func->pf_funce_lan_nid, result, ETHER_ADDR_LEN); 971 break; 972 case PCCARD_IVAR_VENDOR: 973 *(u_int32_t *) result = sc->card.manufacturer; 974 break; 975 case PCCARD_IVAR_PRODUCT: 976 *(u_int32_t *) result = sc->card.product; 977 break; 978 case PCCARD_IVAR_PRODEXT: 979 *(u_int16_t *) result = sc->card.prodext; 980 break; 981 case PCCARD_IVAR_FUNCTION: 982 *(u_int32_t *) result = func->function; 983 break; 984 case PCCARD_IVAR_FUNCTION_NUMBER: 985 if (!func) { 986 device_printf(bus, "No function number, bug!\n"); 987 return (ENOENT); 988 } 989 *(u_int32_t *) result = func->number; 990 break; 991 case PCCARD_IVAR_VENDOR_STR: 992 *(char **) result = sc->card.cis1_info[0]; 993 break; 994 case PCCARD_IVAR_PRODUCT_STR: 995 *(char **) result = sc->card.cis1_info[1]; 996 break; 997 case PCCARD_IVAR_CIS3_STR: 998 *(char **) result = sc->card.cis1_info[2]; 999 break; 1000 case PCCARD_IVAR_CIS4_STR: 1001 *(char **) result = sc->card.cis1_info[2]; 1002 break; 1003 } 1004 return (0); 1005} 1006 1007static void 1008pccard_driver_added(device_t dev, driver_t *driver) 1009{ 1010 struct pccard_softc *sc = PCCARD_SOFTC(dev); 1011 struct pccard_function *pf; 1012 device_t child; 1013 1014 if (sc->sc_enabled_count == 0) { 1015 CARD_REPROBE_CARD(device_get_parent(dev), dev); 1016 return; 1017 } 1018 1019 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 1020 if (STAILQ_EMPTY(&pf->cfe_head)) 1021 continue; 1022 child = pf->dev; 1023 if (device_get_state(child) != DS_NOTPRESENT) 1024 continue; 1025 if (pccard_function_enable(pf) == 0 && 1026 device_probe_and_attach(child) == 0) { 1027 DEVPRINTF((sc->dev, "function %d CCR at %d " 1028 "offset %x: %x %x %x %x, %x %x %x %x, %x\n", 1029 pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, 1030 pccard_ccr_read(pf, 0x00), 1031 pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), 1032 pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), 1033 pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), 1034 pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12))); 1035 } else { 1036 if (pf->cfe != NULL) 1037 pccard_function_disable(pf); 1038 } 1039 } 1040 return; 1041} 1042 1043static struct resource * 1044pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, 1045 u_long start, u_long end, u_long count, u_int flags) 1046{ 1047 struct pccard_ivar *dinfo; 1048 struct resource_list_entry *rle = 0; 1049 int passthrough = (device_get_parent(child) != dev); 1050 1051 if (passthrough) { 1052 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 1053 type, rid, start, end, count, flags)); 1054 } 1055 1056 dinfo = device_get_ivars(child); 1057 rle = resource_list_find(&dinfo->resources, type, *rid); 1058 1059 if (!rle) 1060 return NULL; /* no resource of that type/rid */ 1061 1062 if (!rle->res) { 1063 device_printf(dev, "WARNING: Resource not reserved by pccard bus\n"); 1064 return NULL; 1065 } else { 1066 if (rle->res->r_dev != dev) 1067 return (NULL); 1068 bus_release_resource(dev, type, *rid, rle->res); 1069 rle->res = NULL; 1070 switch(type) { 1071 case SYS_RES_IOPORT: 1072 case SYS_RES_MEMORY: 1073 if (!(flags & RF_ALIGNMENT_MASK)) 1074 flags |= rman_make_alignment_flags(rle->count); 1075 break; 1076 case SYS_RES_IRQ: 1077 flags |= RF_SHAREABLE; 1078 break; 1079 } 1080 rle->res = resource_list_alloc(&dinfo->resources, dev, child, 1081 type, rid, rle->start, rle->end, rle->count, flags); 1082 return (rle->res); 1083 } 1084} 1085 1086static int 1087pccard_release_resource(device_t dev, device_t child, int type, int rid, 1088 struct resource *r) 1089{ 1090 struct pccard_ivar *dinfo; 1091 int passthrough = (device_get_parent(child) != dev); 1092 struct resource_list_entry *rle = 0; 1093 int ret; 1094 int flags; 1095 1096 if (passthrough) 1097 return BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 1098 type, rid, r); 1099 1100 dinfo = device_get_ivars(child); 1101 1102 rle = resource_list_find(&dinfo->resources, type, rid); 1103 1104 if (!rle) { 1105 device_printf(dev, "Allocated resource not found, " 1106 "%d %x %lx %lx\n", 1107 type, rid, rman_get_start(r), rman_get_size(r)); 1108 return ENOENT; 1109 } 1110 if (!rle->res) { 1111 device_printf(dev, "Allocated resource not recorded\n"); 1112 return ENOENT; 1113 } 1114 1115 ret = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 1116 type, rid, r); 1117 switch(type) { 1118 case SYS_RES_IOPORT: 1119 case SYS_RES_MEMORY: 1120 flags = rman_make_alignment_flags(rle->count); 1121 break; 1122 case SYS_RES_IRQ: 1123 flags = RF_SHAREABLE; 1124 break; 1125 default: 1126 flags = 0; 1127 } 1128 rle->res = bus_alloc_resource(dev, type, &rid, 1129 rle->start, rle->end, rle->count, flags); 1130 if (rle->res == NULL) 1131 device_printf(dev, "release_resource: " 1132 "unable to reaquire resource\n"); 1133 return ret; 1134} 1135 1136static void 1137pccard_child_detached(device_t parent, device_t dev) 1138{ 1139 struct pccard_ivar *ivar = PCCARD_IVAR(dev); 1140 struct pccard_function *pf = ivar->fcn; 1141 1142 pccard_function_disable(pf); 1143} 1144 1145static void 1146pccard_intr(void *arg) 1147{ 1148 struct pccard_function *pf = (struct pccard_function*) arg; 1149 int reg; 1150 1151 if (pf->intr_handler == NULL) 1152 return; 1153 1154 /* 1155 * XXX The CCR_STATUS register bits used here are 1156 * only valid for multi function cards. 1157 */ 1158 reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS); 1159 if (reg & PCCARD_CCR_STATUS_INTR) { 1160 pccard_ccr_write(pf, PCCARD_CCR_STATUS, 1161 reg & ~PCCARD_CCR_STATUS_INTR); 1162 pf->intr_handler(pf->intr_handler_arg); 1163 } 1164} 1165 1166static int 1167pccard_setup_intr(device_t dev, device_t child, struct resource *irq, 1168 int flags, driver_intr_t *intr, void *arg, void **cookiep) 1169{ 1170 struct pccard_ivar *ivar = PCCARD_IVAR(child); 1171 struct pccard_function *func = ivar->fcn; 1172 int err; 1173 1174 if (func->intr_handler != NULL) 1175 panic("Only one interrupt handler per function allowed\n"); 1176 err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr, 1177 func, cookiep); 1178 if (err != 0) 1179 return (err); 1180 func->intr_handler = intr; 1181 func->intr_handler_arg = arg; 1182 func->intr_handler_cookie = *cookiep; 1183 /* XXX Not sure this is right to write to ccr */ 1184 pccard_ccr_write(func, PCCARD_CCR_OPTION, 1185 pccard_ccr_read(func, PCCARD_CCR_OPTION) | 1186 PCCARD_CCR_OPTION_IREQ_ENABLE); 1187 return (0); 1188} 1189 1190static int 1191pccard_teardown_intr(device_t dev, device_t child, struct resource *r, 1192 void *cookie) 1193{ 1194 struct pccard_ivar *ivar = PCCARD_IVAR(child); 1195 struct pccard_function *func = ivar->fcn; 1196 int ret; 1197 1198 /* XXX Not sure this is right to write to ccr */ 1199 pccard_ccr_write(func, PCCARD_CCR_OPTION, 1200 pccard_ccr_read(func, PCCARD_CCR_OPTION) & 1201 ~PCCARD_CCR_OPTION_IREQ_ENABLE); 1202 ret = bus_generic_teardown_intr(dev, child, r, cookie); 1203 if (ret == 0) { 1204 func->intr_handler = NULL; 1205 func->intr_handler_arg = NULL; 1206 func->intr_handler_cookie = NULL; 1207 } 1208 1209 return (ret); 1210} 1211 1212static device_method_t pccard_methods[] = { 1213 /* Device interface */ 1214 DEVMETHOD(device_probe, pccard_probe), 1215 DEVMETHOD(device_attach, pccard_attach), 1216 DEVMETHOD(device_detach, pccard_detach), 1217 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1218 DEVMETHOD(device_suspend, pccard_suspend), 1219 DEVMETHOD(device_resume, pccard_resume), 1220 1221 /* Bus interface */ 1222 DEVMETHOD(bus_print_child, pccard_print_child), 1223 DEVMETHOD(bus_driver_added, pccard_driver_added), 1224 DEVMETHOD(bus_child_detached, pccard_child_detached), 1225 DEVMETHOD(bus_alloc_resource, pccard_alloc_resource), 1226 DEVMETHOD(bus_release_resource, pccard_release_resource), 1227 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1228 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1229 DEVMETHOD(bus_setup_intr, pccard_setup_intr), 1230 DEVMETHOD(bus_teardown_intr, pccard_teardown_intr), 1231 DEVMETHOD(bus_set_resource, pccard_set_resource), 1232 DEVMETHOD(bus_get_resource, pccard_get_resource), 1233 DEVMETHOD(bus_delete_resource, pccard_delete_resource), 1234 DEVMETHOD(bus_read_ivar, pccard_read_ivar), 1235 1236 /* Card Interface */ 1237 DEVMETHOD(card_set_res_flags, pccard_set_res_flags), 1238 DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset), 1239 DEVMETHOD(card_get_type, pccard_card_gettype), 1240 DEVMETHOD(card_attach_card, pccard_attach_card), 1241 DEVMETHOD(card_detach_card, pccard_detach_card), 1242 DEVMETHOD(card_compat_do_probe, pccard_compat_do_probe), 1243 DEVMETHOD(card_compat_do_attach, pccard_compat_do_attach), 1244 1245 { 0, 0 } 1246}; 1247 1248static driver_t pccard_driver = { 1249 "pccard", 1250 pccard_methods, 1251 sizeof(struct pccard_softc) 1252}; 1253 1254devclass_t pccard_devclass; 1255 1256DRIVER_MODULE(pccard, pcic, pccard_driver, pccard_devclass, 0, 0); 1257DRIVER_MODULE(pccard, pc98pcic, pccard_driver, pccard_devclass, 0, 0); 1258DRIVER_MODULE(pccard, pccbb, pccard_driver, pccard_devclass, 0, 0); 1259DRIVER_MODULE(pccard, tcic, pccard_driver, pccard_devclass, 0, 0); 1260MODULE_VERSION(pccard, 1); 1261/*MODULE_DEPEND(pccard, pcic, 1, 1, 1);*/
| 72#define DPRINTF(arg) if (pccard_debug) printf arg 73#define DEVPRINTF(arg) if (pccard_debug) device_printf arg 74#define PRVERBOSE(arg) printf arg 75#define DEVPRVERBOSE(arg) device_printf arg 76#else 77#define DPRINTF(arg) 78#define DEVPRINTF(arg) 79#define PRVERBOSE(arg) if (bootverbose) printf arg 80#define DEVPRVERBOSE(arg) if (bootverbose) device_printf arg 81#endif 82 83static int pccard_ccr_read(struct pccard_function *pf, int ccr); 84static void pccard_ccr_write(struct pccard_function *pf, int ccr, int val); 85static int pccard_attach_card(device_t dev); 86static int pccard_detach_card(device_t dev, int flags); 87static int pccard_card_gettype(device_t dev, int *type); 88static void pccard_function_init(struct pccard_function *pf); 89static void pccard_function_free(struct pccard_function *pf); 90static int pccard_function_enable(struct pccard_function *pf); 91static void pccard_function_disable(struct pccard_function *pf); 92static int pccard_compat_do_probe(device_t bus, device_t dev); 93static int pccard_compat_do_attach(device_t bus, device_t dev); 94static int pccard_add_children(device_t dev, int busno); 95static int pccard_probe(device_t dev); 96static int pccard_attach(device_t dev); 97static int pccard_detach(device_t dev); 98static void pccard_print_resources(struct resource_list *rl, 99 const char *name, int type, int count, const char *format); 100static int pccard_print_child(device_t dev, device_t child); 101static int pccard_set_resource(device_t dev, device_t child, int type, 102 int rid, u_long start, u_long count); 103static int pccard_get_resource(device_t dev, device_t child, int type, 104 int rid, u_long *startp, u_long *countp); 105static void pccard_delete_resource(device_t dev, device_t child, int type, 106 int rid); 107static int pccard_set_res_flags(device_t dev, device_t child, int type, 108 int rid, u_int32_t flags); 109static int pccard_set_memory_offset(device_t dev, device_t child, int rid, 110 u_int32_t offset, u_int32_t *deltap); 111static int pccard_read_ivar(device_t bus, device_t child, int which, 112 u_char *result); 113static void pccard_driver_added(device_t dev, driver_t *driver); 114static struct resource *pccard_alloc_resource(device_t dev, 115 device_t child, int type, int *rid, u_long start, 116 u_long end, u_long count, u_int flags); 117static int pccard_release_resource(device_t dev, device_t child, int type, 118 int rid, struct resource *r); 119static void pccard_child_detached(device_t parent, device_t dev); 120static void pccard_intr(void *arg); 121static int pccard_setup_intr(device_t dev, device_t child, 122 struct resource *irq, int flags, driver_intr_t *intr, 123 void *arg, void **cookiep); 124static int pccard_teardown_intr(device_t dev, device_t child, 125 struct resource *r, void *cookie); 126 127static int 128pccard_ccr_read(struct pccard_function *pf, int ccr) 129{ 130 return (bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh, 131 pf->pf_ccr_offset + ccr)); 132} 133 134static void 135pccard_ccr_write(struct pccard_function *pf, int ccr, int val) 136{ 137 if ((pf->ccr_mask) & (1 << (ccr / 2))) { 138 bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh, 139 pf->pf_ccr_offset + ccr, val); 140 } 141} 142 143static int 144pccard_attach_card(device_t dev) 145{ 146 struct pccard_softc *sc = PCCARD_SOFTC(dev); 147 struct pccard_function *pf; 148 struct pccard_ivar *ivar; 149 device_t child; 150 151 /* 152 * this is here so that when socket_enable calls gettype, trt happens 153 */ 154 STAILQ_INIT(&sc->card.pf_head); 155 156 DEVPRINTF((dev, "chip_socket_enable\n")); 157 POWER_ENABLE_SOCKET(device_get_parent(dev), dev); 158 159 DEVPRINTF((dev, "read_cis\n")); 160 pccard_read_cis(sc); 161 162 DEVPRINTF((dev, "check_cis_quirks\n")); 163 pccard_check_cis_quirks(dev); 164 165 /* 166 * bail now if the card has no functions, or if there was an error in 167 * the cis. 168 */ 169 170 if (sc->card.error) { 171 device_printf (dev, "CARD ERROR!\n"); 172 return (1); 173 } 174 if (STAILQ_EMPTY(&sc->card.pf_head)) { 175 device_printf (dev, "Card has no functions!\n"); 176 return (1); 177 } 178 179 if (bootverbose || pccard_debug) 180 pccard_print_cis(dev); 181 182 DEVPRINTF((dev, "functions scanning\n")); 183 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 184 if (STAILQ_EMPTY(&pf->cfe_head)) 185 continue; 186 187 pf->sc = sc; 188 pf->cfe = NULL; 189 pf->dev = NULL; 190 } 191 192 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 193 if (STAILQ_EMPTY(&pf->cfe_head)) 194 continue; 195 /* 196 * In NetBSD, the drivers are responsible for activating 197 * each function of a card. I think that in FreeBSD we 198 * want to activate them enough for the usual bus_*_resource 199 * routines will do the right thing. This many mean a 200 * departure from the current NetBSD model. 201 * 202 * This could get really ugly for multifunction cards. But 203 * it might also just fall out of the FreeBSD resource model. 204 * 205 */ 206 ivar = malloc(sizeof(struct pccard_ivar), M_DEVBUF, 207 M_WAITOK | M_ZERO); 208 child = device_add_child(dev, NULL, -1); 209 device_set_ivars(child, ivar); 210 ivar->fcn = pf; 211 pf->dev = child; 212 /* 213 * XXX We might want to move the next two lines into 214 * XXX the pccard interface layer. For the moment, this 215 * XXX is OK, but some drivers want to pick the config 216 * XXX entry to use as well as some address tweaks (mostly 217 * XXX due to bugs in decode logic that makes some 218 * XXX addresses illegal or broken). 219 */ 220 pccard_function_init(pf); 221 if (sc->sc_enabled_count == 0) 222 POWER_ENABLE_SOCKET(device_get_parent(dev), dev); 223 if (pccard_function_enable(pf) == 0 && 224 device_probe_and_attach(child) == 0) { 225 DEVPRINTF((sc->dev, "function %d CCR at %d " 226 "offset %x: %x %x %x %x, %x %x %x %x, %x\n", 227 pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, 228 pccard_ccr_read(pf, 0x00), 229 pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), 230 pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), 231 pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), 232 pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12))); 233 } else { 234 if (pf->cfe != NULL) 235 pccard_function_disable(pf); 236 } 237 } 238 if (sc->sc_enabled_count == 0) 239 pccard_detach_card(dev, 0); 240 return (0); 241} 242 243static int 244pccard_detach_card(device_t dev, int flags) 245{ 246 struct pccard_softc *sc = PCCARD_SOFTC(dev); 247 struct pccard_function *pf; 248 struct pccard_config_entry *cfe; 249 250 /* 251 * We are running on either the PCCARD socket's event thread 252 * or in user context detaching a device by user request. 253 */ 254 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 255 int state = device_get_state(pf->dev); 256 257 if (state == DS_ATTACHED || state == DS_BUSY) 258 device_detach(pf->dev); 259 if (pf->cfe != NULL) 260 pccard_function_disable(pf); 261 pccard_function_free(pf); 262 if (pf->dev != NULL) 263 device_delete_child(dev, pf->dev); 264 } 265 if (sc->sc_enabled_count == 0) 266 POWER_DISABLE_SOCKET(device_get_parent(dev), dev); 267 268 while (NULL != (pf = STAILQ_FIRST(&sc->card.pf_head))) { 269 while (NULL != (cfe = STAILQ_FIRST(&pf->cfe_head))) { 270 STAILQ_REMOVE_HEAD(&pf->cfe_head, cfe_list); 271 free(cfe, M_DEVBUF); 272 } 273 STAILQ_REMOVE_HEAD(&sc->card.pf_head, pf_list); 274 free(pf, M_DEVBUF); 275 } 276 return (0); 277} 278 279const struct pccard_product * 280pccard_product_lookup(device_t dev, const struct pccard_product *tab, 281 size_t ent_size, pccard_product_match_fn matchfn) 282{ 283 const struct pccard_product *ent; 284 int matches; 285 u_int32_t fcn; 286 u_int32_t vendor; 287 u_int32_t prod; 288 char *vendorstr; 289 char *prodstr; 290 291#ifdef DIAGNOSTIC 292 if (sizeof *ent > ent_size) 293 panic("pccard_product_lookup: bogus ent_size %ld", 294 (long) ent_size); 295#endif 296 if (pccard_get_vendor(dev, &vendor)) 297 return (NULL); 298 if (pccard_get_product(dev, &prod)) 299 return (NULL); 300 if (pccard_get_function_number(dev, &fcn)) 301 return (NULL); 302 if (pccard_get_vendor_str(dev, &vendorstr)) 303 return (NULL); 304 if (pccard_get_product_str(dev, &prodstr)) 305 return (NULL); 306 for (ent = tab; ent->pp_name != NULL; ent = 307 (const struct pccard_product *) ((const char *) ent + ent_size)) { 308 matches = 1; 309 if (ent->pp_vendor == PCCARD_VENDOR_ANY && 310 ent->pp_product == PCCARD_VENDOR_ANY && 311 ent->pp_cis[0] == NULL && 312 ent->pp_cis[1] == NULL) { 313 device_printf(dev, 314 "Total wildcard entry ignored for %s\n", 315 ent->pp_name); 316 continue; 317 } 318 if (matches && ent->pp_vendor != PCCARD_VENDOR_ANY && 319 vendor != ent->pp_vendor) 320 matches = 0; 321 if (matches && ent->pp_product != PCCARD_PRODUCT_ANY && 322 prod != ent->pp_product) 323 matches = 0; 324 if (matches && fcn != ent->pp_expfunc) 325 matches = 0; 326 if (matches && ent->pp_cis[0] && 327 strcmp(ent->pp_cis[0], vendorstr) != 0) 328 matches = 0; 329 if (matches && ent->pp_cis[1] && 330 strcmp(ent->pp_cis[1], prodstr) != 0) 331 matches = 0; 332 /* XXX need to match cis[2] and cis[3] also XXX */ 333 if (matchfn != NULL) 334 matches = (*matchfn)(dev, ent, matches); 335 if (matches) 336 return (ent); 337 } 338 return (NULL); 339} 340 341static int 342pccard_card_gettype(device_t dev, int *type) 343{ 344 struct pccard_softc *sc = PCCARD_SOFTC(dev); 345 struct pccard_function *pf; 346 347 /* 348 * set the iftype to memory if this card has no functions (not yet 349 * probed), or only one function, and that is not initialized yet or 350 * that is memory. 351 */ 352 pf = STAILQ_FIRST(&sc->card.pf_head); 353 if (pf == NULL || 354 (STAILQ_NEXT(pf, pf_list) == NULL && 355 (pf->cfe == NULL || pf->cfe->iftype == PCCARD_IFTYPE_MEMORY))) 356 *type = PCCARD_IFTYPE_MEMORY; 357 else 358 *type = PCCARD_IFTYPE_IO; 359 return (0); 360} 361 362/* 363 * Initialize a PCCARD function. May be called as long as the function is 364 * disabled. 365 * 366 * Note: pccard_function_init should not keep resources allocated. It should 367 * only set them up ala isa pnp, set the values in the rl lists, and return. 368 * Any resource held after pccard_function_init is called is a bug. However, 369 * the bus routines to get the resources also assume that pccard_function_init 370 * does this, so they need to be fixed too. 371 */ 372static void 373pccard_function_init(struct pccard_function *pf) 374{ 375 struct pccard_config_entry *cfe; 376 int i; 377 struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); 378 struct resource_list *rl = &devi->resources; 379 struct resource_list_entry *rle; 380 struct resource *r = 0; 381 device_t bus; 382 int start; 383 int end; 384 int spaces; 385 386 if (pf->pf_flags & PFF_ENABLED) { 387 printf("pccard_function_init: function is enabled"); 388 return; 389 } 390 bus = device_get_parent(pf->dev); 391 /* Remember which configuration entry we are using. */ 392 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { 393 for (i = 0; i < cfe->num_iospace; i++) 394 cfe->iores[i] = NULL; 395 cfe->irqres = NULL; 396 spaces = 0; 397 for (i = 0; i < cfe->num_iospace; i++) { 398 start = cfe->iospace[i].start; 399 if (start) 400 end = start + cfe->iospace[i].length - 1; 401 else 402 end = ~0; 403 cfe->iorid[i] = i; 404 DEVPRINTF((bus, "I/O rid %d start %x end %x\n", 405 i, start, end)); 406 r = cfe->iores[i] = bus_alloc_resource(bus, 407 SYS_RES_IOPORT, &cfe->iorid[i], start, end, 408 cfe->iospace[i].length, 409 rman_make_alignment_flags(cfe->iospace[i].length)); 410 if (cfe->iores[i] == NULL) 411 goto not_this_one; 412 resource_list_add(rl, SYS_RES_IOPORT, cfe->iorid[i], 413 rman_get_start(r), rman_get_end(r), 414 cfe->iospace[i].length); 415 rle = resource_list_find(rl, SYS_RES_IOPORT, 416 cfe->iorid[i]); 417 rle->res = r; 418 spaces++; 419 } 420 if (cfe->num_memspace > 0) { 421 /* 422 * Not implement yet, Fix me. 423 */ 424 DEVPRINTF((bus, "Memory space not yet implemented.\n")); 425 } 426 if (spaces == 0) { 427 DEVPRINTF((bus, "Neither memory nor I/O mampped\n")); 428 goto not_this_one; 429 } 430 if (cfe->irqmask) { 431 cfe->irqrid = 0; 432 r = cfe->irqres = bus_alloc_resource(bus, SYS_RES_IRQ, 433 &cfe->irqrid, 0, ~0, 1, 0); 434 if (cfe->irqres == NULL) 435 goto not_this_one; 436 resource_list_add(rl, SYS_RES_IRQ, cfe->irqrid, 437 rman_get_start(r), rman_get_end(r), 1); 438 rle = resource_list_find(rl, SYS_RES_IRQ, 439 cfe->irqrid); 440 rle->res = r; 441 } 442 /* If we get to here, we've allocated all we need */ 443 pf->cfe = cfe; 444 break; 445 not_this_one:; 446 DEVPRVERBOSE((bus, "Allocation failed for cfe %d\n", 447 cfe->number)); 448 /* 449 * Release resources that we partially allocated 450 * from this config entry. 451 */ 452 for (i = 0; i < cfe->num_iospace; i++) { 453 if (cfe->iores[i] != NULL) { 454 bus_release_resource(bus, SYS_RES_IOPORT, 455 cfe->iorid[i], cfe->iores[i]); 456 rle = resource_list_find(rl, SYS_RES_IOPORT, 457 cfe->iorid[i]); 458 rle->res = NULL; 459 resource_list_delete(rl, SYS_RES_IOPORT, 460 cfe->iorid[i]); 461 } 462 cfe->iores[i] = NULL; 463 } 464 if (cfe->irqmask && cfe->irqres != NULL) { 465 bus_release_resource(bus, SYS_RES_IRQ, 466 cfe->irqrid, cfe->irqres); 467 rle = resource_list_find(rl, SYS_RES_IRQ, 468 cfe->irqrid); 469 rle->res = NULL; 470 resource_list_delete(rl, SYS_RES_IRQ, cfe->irqrid); 471 cfe->irqres = NULL; 472 } 473 } 474} 475 476/* 477 * Free resources allocated by pccard_function_init(), May be called as long 478 * as the function is disabled. 479 * 480 * NOTE: This function should be unnecessary. pccard_function_init should 481 * never keep resources initialized. 482 */ 483static void 484pccard_function_free(struct pccard_function *pf) 485{ 486 struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); 487 struct resource_list_entry *rle; 488 489 if (pf->pf_flags & PFF_ENABLED) { 490 printf("pccard_function_init: function is enabled"); 491 return; 492 } 493 494 SLIST_FOREACH(rle, &devi->resources, link) { 495 if (rle->res) { 496 if (rle->res->r_dev != pf->sc->dev) 497 device_printf(pf->sc->dev, 498 "function_free: Resource still owned by " 499 "child, oops. " 500 "(type=%d, rid=%d, addr=%lx)\n", 501 rle->type, rle->rid, 502 rman_get_start(rle->res)); 503 BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev), 504 rle->res->r_dev, rle->type, rle->rid, rle->res); 505 rle->res = NULL; 506 } 507 } 508 resource_list_free(&devi->resources); 509} 510 511/* Enable a PCCARD function */ 512static int 513pccard_function_enable(struct pccard_function *pf) 514{ 515 struct pccard_function *tmp; 516 int reg; 517 device_t dev = pf->sc->dev; 518 519 if (pf->cfe == NULL) { 520 DEVPRVERBOSE((dev, "No config entry could be allocated.\n")); 521 return (ENOMEM); 522 } 523 524 /* 525 * Increase the reference count on the socket, enabling power, if 526 * necessary. 527 */ 528 pf->sc->sc_enabled_count++; 529 530 if (pf->pf_flags & PFF_ENABLED) { 531 /* 532 * Don't do anything if we're already enabled. 533 */ 534 return (0); 535 } 536 537 /* 538 * it's possible for different functions' CCRs to be in the same 539 * underlying page. Check for that. 540 */ 541 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 542 if ((tmp->pf_flags & PFF_ENABLED) && 543 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) && 544 ((pf->ccr_base + PCCARD_CCR_SIZE) <= 545 (tmp->ccr_base - tmp->pf_ccr_offset + 546 tmp->pf_ccr_realsize))) { 547 pf->pf_ccrt = tmp->pf_ccrt; 548 pf->pf_ccrh = tmp->pf_ccrh; 549 pf->pf_ccr_realsize = tmp->pf_ccr_realsize; 550 551 /* 552 * pf->pf_ccr_offset = (tmp->pf_ccr_offset - 553 * tmp->ccr_base) + pf->ccr_base; 554 */ 555 /* pf->pf_ccr_offset = 556 (tmp->pf_ccr_offset + pf->ccr_base) - 557 tmp->ccr_base; */ 558 pf->pf_ccr_window = tmp->pf_ccr_window; 559 break; 560 } 561 } 562 if (tmp == NULL) { 563 pf->ccr_rid = 0; 564 pf->ccr_res = bus_alloc_resource(dev, SYS_RES_MEMORY, 565 &pf->ccr_rid, 0, ~0, 1 << 10, RF_ACTIVE); 566 if (!pf->ccr_res) 567 goto bad; 568 DEVPRINTF((dev, "ccr_res == %lx-%lx, base=%lx\n", 569 rman_get_start(pf->ccr_res), rman_get_end(pf->ccr_res), 570 pf->ccr_base)); 571 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY, 572 pf->ccr_rid, PCCARD_A_MEM_ATTR); 573 CARD_SET_MEMORY_OFFSET(device_get_parent(dev), dev, 574 pf->ccr_rid, pf->ccr_base, &pf->pf_ccr_offset); 575 pf->pf_ccrt = rman_get_bustag(pf->ccr_res); 576 pf->pf_ccrh = rman_get_bushandle(pf->ccr_res); 577 pf->pf_ccr_realsize = 1; 578 } 579 580 reg = (pf->cfe->number & PCCARD_CCR_OPTION_CFINDEX); 581 reg |= PCCARD_CCR_OPTION_LEVIREQ; 582 if (pccard_mfc(pf->sc)) { 583 reg |= (PCCARD_CCR_OPTION_FUNC_ENABLE | 584 PCCARD_CCR_OPTION_ADDR_DECODE); 585 /* PCCARD_CCR_OPTION_IRQ_ENABLE set elsewhere as needed */ 586 } 587 pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg); 588 589 reg = 0; 590 if ((pf->cfe->flags & PCCARD_CFE_IO16) == 0) 591 reg |= PCCARD_CCR_STATUS_IOIS8; 592 if (pf->cfe->flags & PCCARD_CFE_AUDIO) 593 reg |= PCCARD_CCR_STATUS_AUDIO; 594 pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg); 595 596 pccard_ccr_write(pf, PCCARD_CCR_SOCKETCOPY, 0); 597 598 if (pccard_mfc(pf->sc)) { 599 long tmp, iosize; 600 601 tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; 602 /* round up to nearest (2^n)-1 */ 603 for (iosize = 1; iosize < tmp; iosize <<= 1) 604 ; 605 iosize--; 606 607 pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, 608 pf->pf_mfc_iobase & 0xff); 609 pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, 610 (pf->pf_mfc_iobase >> 8) & 0xff); 611 pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); 612 pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); 613 614 pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); 615 } 616 617#ifdef PCCARDDEBUG 618 if (pccard_debug) { 619 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 620 device_printf(tmp->sc->dev, 621 "function %d CCR at %d offset %x: " 622 "%x %x %x %x, %x %x %x %x, %x\n", 623 tmp->number, tmp->pf_ccr_window, 624 tmp->pf_ccr_offset, 625 pccard_ccr_read(tmp, 0x00), 626 pccard_ccr_read(tmp, 0x02), 627 pccard_ccr_read(tmp, 0x04), 628 pccard_ccr_read(tmp, 0x06), 629 pccard_ccr_read(tmp, 0x0A), 630 pccard_ccr_read(tmp, 0x0C), 631 pccard_ccr_read(tmp, 0x0E), 632 pccard_ccr_read(tmp, 0x10), 633 pccard_ccr_read(tmp, 0x12)); 634 } 635 } 636#endif 637 pf->pf_flags |= PFF_ENABLED; 638 return (0); 639 640 bad: 641 /* 642 * Decrement the reference count, and power down the socket, if 643 * necessary. 644 */ 645 pf->sc->sc_enabled_count--; 646 DEVPRINTF((dev, "bad --enabled_count = %d\n", pf->sc->sc_enabled_count)); 647 648 return (1); 649} 650 651/* Disable PCCARD function. */ 652static void 653pccard_function_disable(struct pccard_function *pf) 654{ 655 struct pccard_function *tmp; 656 device_t dev = pf->sc->dev; 657 658 if (pf->cfe == NULL) 659 panic("pccard_function_disable: function not initialized"); 660 661 if ((pf->pf_flags & PFF_ENABLED) == 0) { 662 /* 663 * Don't do anything if we're already disabled. 664 */ 665 return; 666 } 667 668 if (pf->intr_handler != NULL) { 669 struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); 670 struct resource_list_entry *rle = 671 resource_list_find(&devi->resources, SYS_RES_IRQ, 0); 672 BUS_TEARDOWN_INTR(dev, pf->dev, rle->res, 673 pf->intr_handler_cookie); 674 } 675 676 /* 677 * it's possible for different functions' CCRs to be in the same 678 * underlying page. Check for that. Note we mark us as disabled 679 * first to avoid matching ourself. 680 */ 681 682 pf->pf_flags &= ~PFF_ENABLED; 683 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 684 if ((tmp->pf_flags & PFF_ENABLED) && 685 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) && 686 ((pf->ccr_base + PCCARD_CCR_SIZE) <= 687 (tmp->ccr_base - tmp->pf_ccr_offset + 688 tmp->pf_ccr_realsize))) 689 break; 690 } 691 692 /* Not used by anyone else; unmap the CCR. */ 693 if (tmp == NULL) { 694 bus_release_resource(dev, SYS_RES_MEMORY, pf->ccr_rid, 695 pf->ccr_res); 696 pf->ccr_res = NULL; 697 } 698 699 /* 700 * Decrement the reference count, and power down the socket, if 701 * necessary. 702 */ 703 pf->sc->sc_enabled_count--; 704} 705 706#if 0 707/* XXX These functions are needed, but not like this XXX */ 708int 709pccard_io_map(struct pccard_function *pf, int width, bus_addr_t offset, 710 bus_size_t size, struct pccard_io_handle *pcihp, int *windowp) 711{ 712 int reg; 713 714 if (pccard_chip_io_map(pf->sc->pct, pf->sc->pch, width, offset, size, 715 pcihp, windowp)) 716 return (1); 717 718 /* 719 * XXX in the multifunction multi-iospace-per-function case, this 720 * needs to cooperate with io_alloc to make sure that the spaces 721 * don't overlap, and that the ccr's are set correctly 722 */ 723 724 if (pccard_mfc(pf->sc)) { 725 long tmp, iosize; 726 727 if (pf->pf_mfc_iomax == 0) { 728 pf->pf_mfc_iobase = pcihp->addr + offset; 729 pf->pf_mfc_iomax = pf->pf_mfc_iobase + size; 730 } else { 731 /* this makes the assumption that nothing overlaps */ 732 if (pf->pf_mfc_iobase > pcihp->addr + offset) 733 pf->pf_mfc_iobase = pcihp->addr + offset; 734 if (pf->pf_mfc_iomax < pcihp->addr + offset + size) 735 pf->pf_mfc_iomax = pcihp->addr + offset + size; 736 } 737 738 tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; 739 /* round up to nearest (2^n)-1 */ 740 for (iosize = 1; iosize >= tmp; iosize <<= 1) 741 ; 742 iosize--; 743 744 pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, 745 pf->pf_mfc_iobase & 0xff); 746 pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, 747 (pf->pf_mfc_iobase >> 8) & 0xff); 748 pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); 749 pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); 750 751 pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); 752 753 reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION); 754 reg |= PCCARD_CCR_OPTION_ADDR_DECODE; 755 pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg); 756 } 757 return (0); 758} 759 760void 761pccard_io_unmap(struct pccard_function *pf, int window) 762{ 763 764 pccard_chip_io_unmap(pf->sc->pct, pf->sc->pch, window); 765 766 /* XXX Anything for multi-function cards? */ 767} 768#endif 769 770/* 771 * simulate the old "probe" routine. In the new world order, the driver 772 * needs to grab devices while in the old they were assigned to the device by 773 * the pccardd process. These symbols are exported to the upper layers. 774 */ 775static int 776pccard_compat_do_probe(device_t bus, device_t dev) 777{ 778 return (CARD_COMPAT_MATCH(dev)); 779} 780 781static int 782pccard_compat_do_attach(device_t bus, device_t dev) 783{ 784 int err; 785 786 err = CARD_COMPAT_PROBE(dev); 787 if (err == 0) 788 err = CARD_COMPAT_ATTACH(dev); 789 return (err); 790} 791 792#define PCCARD_NPORT 2 793#define PCCARD_NMEM 5 794#define PCCARD_NIRQ 1 795#define PCCARD_NDRQ 0 796 797static int 798pccard_add_children(device_t dev, int busno) 799{ 800 /* Call parent to scan for any current children */ 801 return (0); 802} 803 804static int 805pccard_probe(device_t dev) 806{ 807 device_set_desc(dev, "16-bit PCCard bus"); 808 return (pccard_add_children(dev, device_get_unit(dev))); 809} 810 811static int 812pccard_attach(device_t dev) 813{ 814 struct pccard_softc *sc = PCCARD_SOFTC(dev); 815 816 sc->dev = dev; 817 sc->sc_enabled_count = 0; 818 return (bus_generic_attach(dev)); 819} 820 821static int 822pccard_detach(device_t dev) 823{ 824 pccard_detach_card(dev, 0); 825 return 0; 826} 827 828static int 829pccard_suspend(device_t self) 830{ 831 pccard_detach_card(self, 0); 832 return (0); 833} 834 835static 836int 837pccard_resume(device_t self) 838{ 839 return (0); 840} 841 842static void 843pccard_print_resources(struct resource_list *rl, const char *name, int type, 844 int count, const char *format) 845{ 846 struct resource_list_entry *rle; 847 int printed; 848 int i; 849 850 printed = 0; 851 for (i = 0; i < count; i++) { 852 rle = resource_list_find(rl, type, i); 853 if (rle != NULL) { 854 if (printed == 0) 855 printf(" %s ", name); 856 else if (printed > 0) 857 printf(","); 858 printed++; 859 printf(format, rle->start); 860 if (rle->count > 1) { 861 printf("-"); 862 printf(format, rle->start + rle->count - 1); 863 } 864 } else if (i > 3) { 865 /* check the first few regardless */ 866 break; 867 } 868 } 869} 870 871static int 872pccard_print_child(device_t dev, device_t child) 873{ 874 struct pccard_ivar *devi = PCCARD_IVAR(child); 875 struct resource_list *rl = &devi->resources; 876 int retval = 0; 877 878 retval += bus_print_child_header(dev, child); 879 retval += printf(" at"); 880 881 if (devi != NULL) { 882 pccard_print_resources(rl, "port", SYS_RES_IOPORT, 883 PCCARD_NPORT, "%#lx"); 884 pccard_print_resources(rl, "iomem", SYS_RES_MEMORY, 885 PCCARD_NMEM, "%#lx"); 886 pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ, 887 "%ld"); 888 pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ, 889 "%ld"); 890 retval += printf(" function %d config %d", devi->fcn->number, 891 devi->fcn->cfe->number); 892 } 893 894 retval += bus_print_child_footer(dev, child); 895 896 return (retval); 897} 898 899static int 900pccard_set_resource(device_t dev, device_t child, int type, int rid, 901 u_long start, u_long count) 902{ 903 struct pccard_ivar *devi = PCCARD_IVAR(child); 904 struct resource_list *rl = &devi->resources; 905 906 if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY 907 && type != SYS_RES_IRQ && type != SYS_RES_DRQ) 908 return (EINVAL); 909 if (rid < 0) 910 return (EINVAL); 911 if (type == SYS_RES_IOPORT && rid >= PCCARD_NPORT) 912 return (EINVAL); 913 if (type == SYS_RES_MEMORY && rid >= PCCARD_NMEM) 914 return (EINVAL); 915 if (type == SYS_RES_IRQ && rid >= PCCARD_NIRQ) 916 return (EINVAL); 917 if (type == SYS_RES_DRQ && rid >= PCCARD_NDRQ) 918 return (EINVAL); 919 920 resource_list_add(rl, type, rid, start, start + count - 1, count); 921 if (NULL != resource_list_alloc(rl, device_get_parent(dev), dev, 922 type, &rid, start, start + count - 1, count, 0)) 923 return 0; 924 else 925 return ENOMEM; 926} 927 928static int 929pccard_get_resource(device_t dev, device_t child, int type, int rid, 930 u_long *startp, u_long *countp) 931{ 932 struct pccard_ivar *devi = PCCARD_IVAR(child); 933 struct resource_list *rl = &devi->resources; 934 struct resource_list_entry *rle; 935 936 rle = resource_list_find(rl, type, rid); 937 if (rle == NULL) 938 return (ENOENT); 939 940 if (startp != NULL) 941 *startp = rle->start; 942 if (countp != NULL) 943 *countp = rle->count; 944 945 return (0); 946} 947 948static void 949pccard_delete_resource(device_t dev, device_t child, int type, int rid) 950{ 951 struct pccard_ivar *devi = PCCARD_IVAR(child); 952 struct resource_list *rl = &devi->resources; 953 resource_list_delete(rl, type, rid); 954} 955 956static int 957pccard_set_res_flags(device_t dev, device_t child, int type, int rid, 958 u_int32_t flags) 959{ 960 return (CARD_SET_RES_FLAGS(device_get_parent(dev), child, type, 961 rid, flags)); 962} 963 964static int 965pccard_set_memory_offset(device_t dev, device_t child, int rid, 966 u_int32_t offset, u_int32_t *deltap) 967 968{ 969 return (CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid, 970 offset, deltap)); 971} 972 973static int 974pccard_read_ivar(device_t bus, device_t child, int which, u_char *result) 975{ 976 struct pccard_ivar *devi = PCCARD_IVAR(child); 977 struct pccard_function *func = devi->fcn; 978 struct pccard_softc *sc = PCCARD_SOFTC(bus); 979 980 /* PCCARD_IVAR_ETHADDR unhandled from oldcard */ 981 switch (which) { 982 default: 983 case PCCARD_IVAR_ETHADDR: 984 bcopy(func->pf_funce_lan_nid, result, ETHER_ADDR_LEN); 985 break; 986 case PCCARD_IVAR_VENDOR: 987 *(u_int32_t *) result = sc->card.manufacturer; 988 break; 989 case PCCARD_IVAR_PRODUCT: 990 *(u_int32_t *) result = sc->card.product; 991 break; 992 case PCCARD_IVAR_PRODEXT: 993 *(u_int16_t *) result = sc->card.prodext; 994 break; 995 case PCCARD_IVAR_FUNCTION: 996 *(u_int32_t *) result = func->function; 997 break; 998 case PCCARD_IVAR_FUNCTION_NUMBER: 999 if (!func) { 1000 device_printf(bus, "No function number, bug!\n"); 1001 return (ENOENT); 1002 } 1003 *(u_int32_t *) result = func->number; 1004 break; 1005 case PCCARD_IVAR_VENDOR_STR: 1006 *(char **) result = sc->card.cis1_info[0]; 1007 break; 1008 case PCCARD_IVAR_PRODUCT_STR: 1009 *(char **) result = sc->card.cis1_info[1]; 1010 break; 1011 case PCCARD_IVAR_CIS3_STR: 1012 *(char **) result = sc->card.cis1_info[2]; 1013 break; 1014 case PCCARD_IVAR_CIS4_STR: 1015 *(char **) result = sc->card.cis1_info[2]; 1016 break; 1017 } 1018 return (0); 1019} 1020 1021static void 1022pccard_driver_added(device_t dev, driver_t *driver) 1023{ 1024 struct pccard_softc *sc = PCCARD_SOFTC(dev); 1025 struct pccard_function *pf; 1026 device_t child; 1027 1028 if (sc->sc_enabled_count == 0) { 1029 CARD_REPROBE_CARD(device_get_parent(dev), dev); 1030 return; 1031 } 1032 1033 STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 1034 if (STAILQ_EMPTY(&pf->cfe_head)) 1035 continue; 1036 child = pf->dev; 1037 if (device_get_state(child) != DS_NOTPRESENT) 1038 continue; 1039 if (pccard_function_enable(pf) == 0 && 1040 device_probe_and_attach(child) == 0) { 1041 DEVPRINTF((sc->dev, "function %d CCR at %d " 1042 "offset %x: %x %x %x %x, %x %x %x %x, %x\n", 1043 pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, 1044 pccard_ccr_read(pf, 0x00), 1045 pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), 1046 pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), 1047 pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), 1048 pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12))); 1049 } else { 1050 if (pf->cfe != NULL) 1051 pccard_function_disable(pf); 1052 } 1053 } 1054 return; 1055} 1056 1057static struct resource * 1058pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, 1059 u_long start, u_long end, u_long count, u_int flags) 1060{ 1061 struct pccard_ivar *dinfo; 1062 struct resource_list_entry *rle = 0; 1063 int passthrough = (device_get_parent(child) != dev); 1064 1065 if (passthrough) { 1066 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 1067 type, rid, start, end, count, flags)); 1068 } 1069 1070 dinfo = device_get_ivars(child); 1071 rle = resource_list_find(&dinfo->resources, type, *rid); 1072 1073 if (!rle) 1074 return NULL; /* no resource of that type/rid */ 1075 1076 if (!rle->res) { 1077 device_printf(dev, "WARNING: Resource not reserved by pccard bus\n"); 1078 return NULL; 1079 } else { 1080 if (rle->res->r_dev != dev) 1081 return (NULL); 1082 bus_release_resource(dev, type, *rid, rle->res); 1083 rle->res = NULL; 1084 switch(type) { 1085 case SYS_RES_IOPORT: 1086 case SYS_RES_MEMORY: 1087 if (!(flags & RF_ALIGNMENT_MASK)) 1088 flags |= rman_make_alignment_flags(rle->count); 1089 break; 1090 case SYS_RES_IRQ: 1091 flags |= RF_SHAREABLE; 1092 break; 1093 } 1094 rle->res = resource_list_alloc(&dinfo->resources, dev, child, 1095 type, rid, rle->start, rle->end, rle->count, flags); 1096 return (rle->res); 1097 } 1098} 1099 1100static int 1101pccard_release_resource(device_t dev, device_t child, int type, int rid, 1102 struct resource *r) 1103{ 1104 struct pccard_ivar *dinfo; 1105 int passthrough = (device_get_parent(child) != dev); 1106 struct resource_list_entry *rle = 0; 1107 int ret; 1108 int flags; 1109 1110 if (passthrough) 1111 return BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 1112 type, rid, r); 1113 1114 dinfo = device_get_ivars(child); 1115 1116 rle = resource_list_find(&dinfo->resources, type, rid); 1117 1118 if (!rle) { 1119 device_printf(dev, "Allocated resource not found, " 1120 "%d %x %lx %lx\n", 1121 type, rid, rman_get_start(r), rman_get_size(r)); 1122 return ENOENT; 1123 } 1124 if (!rle->res) { 1125 device_printf(dev, "Allocated resource not recorded\n"); 1126 return ENOENT; 1127 } 1128 1129 ret = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 1130 type, rid, r); 1131 switch(type) { 1132 case SYS_RES_IOPORT: 1133 case SYS_RES_MEMORY: 1134 flags = rman_make_alignment_flags(rle->count); 1135 break; 1136 case SYS_RES_IRQ: 1137 flags = RF_SHAREABLE; 1138 break; 1139 default: 1140 flags = 0; 1141 } 1142 rle->res = bus_alloc_resource(dev, type, &rid, 1143 rle->start, rle->end, rle->count, flags); 1144 if (rle->res == NULL) 1145 device_printf(dev, "release_resource: " 1146 "unable to reaquire resource\n"); 1147 return ret; 1148} 1149 1150static void 1151pccard_child_detached(device_t parent, device_t dev) 1152{ 1153 struct pccard_ivar *ivar = PCCARD_IVAR(dev); 1154 struct pccard_function *pf = ivar->fcn; 1155 1156 pccard_function_disable(pf); 1157} 1158 1159static void 1160pccard_intr(void *arg) 1161{ 1162 struct pccard_function *pf = (struct pccard_function*) arg; 1163 int reg; 1164 1165 if (pf->intr_handler == NULL) 1166 return; 1167 1168 /* 1169 * XXX The CCR_STATUS register bits used here are 1170 * only valid for multi function cards. 1171 */ 1172 reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS); 1173 if (reg & PCCARD_CCR_STATUS_INTR) { 1174 pccard_ccr_write(pf, PCCARD_CCR_STATUS, 1175 reg & ~PCCARD_CCR_STATUS_INTR); 1176 pf->intr_handler(pf->intr_handler_arg); 1177 } 1178} 1179 1180static int 1181pccard_setup_intr(device_t dev, device_t child, struct resource *irq, 1182 int flags, driver_intr_t *intr, void *arg, void **cookiep) 1183{ 1184 struct pccard_ivar *ivar = PCCARD_IVAR(child); 1185 struct pccard_function *func = ivar->fcn; 1186 int err; 1187 1188 if (func->intr_handler != NULL) 1189 panic("Only one interrupt handler per function allowed\n"); 1190 err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr, 1191 func, cookiep); 1192 if (err != 0) 1193 return (err); 1194 func->intr_handler = intr; 1195 func->intr_handler_arg = arg; 1196 func->intr_handler_cookie = *cookiep; 1197 /* XXX Not sure this is right to write to ccr */ 1198 pccard_ccr_write(func, PCCARD_CCR_OPTION, 1199 pccard_ccr_read(func, PCCARD_CCR_OPTION) | 1200 PCCARD_CCR_OPTION_IREQ_ENABLE); 1201 return (0); 1202} 1203 1204static int 1205pccard_teardown_intr(device_t dev, device_t child, struct resource *r, 1206 void *cookie) 1207{ 1208 struct pccard_ivar *ivar = PCCARD_IVAR(child); 1209 struct pccard_function *func = ivar->fcn; 1210 int ret; 1211 1212 /* XXX Not sure this is right to write to ccr */ 1213 pccard_ccr_write(func, PCCARD_CCR_OPTION, 1214 pccard_ccr_read(func, PCCARD_CCR_OPTION) & 1215 ~PCCARD_CCR_OPTION_IREQ_ENABLE); 1216 ret = bus_generic_teardown_intr(dev, child, r, cookie); 1217 if (ret == 0) { 1218 func->intr_handler = NULL; 1219 func->intr_handler_arg = NULL; 1220 func->intr_handler_cookie = NULL; 1221 } 1222 1223 return (ret); 1224} 1225 1226static device_method_t pccard_methods[] = { 1227 /* Device interface */ 1228 DEVMETHOD(device_probe, pccard_probe), 1229 DEVMETHOD(device_attach, pccard_attach), 1230 DEVMETHOD(device_detach, pccard_detach), 1231 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1232 DEVMETHOD(device_suspend, pccard_suspend), 1233 DEVMETHOD(device_resume, pccard_resume), 1234 1235 /* Bus interface */ 1236 DEVMETHOD(bus_print_child, pccard_print_child), 1237 DEVMETHOD(bus_driver_added, pccard_driver_added), 1238 DEVMETHOD(bus_child_detached, pccard_child_detached), 1239 DEVMETHOD(bus_alloc_resource, pccard_alloc_resource), 1240 DEVMETHOD(bus_release_resource, pccard_release_resource), 1241 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1242 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1243 DEVMETHOD(bus_setup_intr, pccard_setup_intr), 1244 DEVMETHOD(bus_teardown_intr, pccard_teardown_intr), 1245 DEVMETHOD(bus_set_resource, pccard_set_resource), 1246 DEVMETHOD(bus_get_resource, pccard_get_resource), 1247 DEVMETHOD(bus_delete_resource, pccard_delete_resource), 1248 DEVMETHOD(bus_read_ivar, pccard_read_ivar), 1249 1250 /* Card Interface */ 1251 DEVMETHOD(card_set_res_flags, pccard_set_res_flags), 1252 DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset), 1253 DEVMETHOD(card_get_type, pccard_card_gettype), 1254 DEVMETHOD(card_attach_card, pccard_attach_card), 1255 DEVMETHOD(card_detach_card, pccard_detach_card), 1256 DEVMETHOD(card_compat_do_probe, pccard_compat_do_probe), 1257 DEVMETHOD(card_compat_do_attach, pccard_compat_do_attach), 1258 1259 { 0, 0 } 1260}; 1261 1262static driver_t pccard_driver = { 1263 "pccard", 1264 pccard_methods, 1265 sizeof(struct pccard_softc) 1266}; 1267 1268devclass_t pccard_devclass; 1269 1270DRIVER_MODULE(pccard, pcic, pccard_driver, pccard_devclass, 0, 0); 1271DRIVER_MODULE(pccard, pc98pcic, pccard_driver, pccard_devclass, 0, 0); 1272DRIVER_MODULE(pccard, pccbb, pccard_driver, pccard_devclass, 0, 0); 1273DRIVER_MODULE(pccard, tcic, pccard_driver, pccard_devclass, 0, 0); 1274MODULE_VERSION(pccard, 1); 1275/*MODULE_DEPEND(pccard, pcic, 1, 1, 1);*/
|