1 /* $NetBSD: pcmcia.c,v 1.78 2005/12/11 12:23:23 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2004 Charles M. Hannum. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles M. Hannum. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 */ 20 21 /* 22 * Copyright (c) 1997 Marc Horowitz. All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. All advertising materials mentioning features or use of this software 33 * must display the following acknowledgement: 34 * This product includes software developed by Marc Horowitz. 35 * 4. The name of the author may not be used to endorse or promote products 36 * derived from this software without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 39 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 40 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 42 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 44 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 45 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 47 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 */ 49 50 #include <sys/cdefs.h> 51 __KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.78 2005/12/11 12:23:23 christos Exp $"); 52 53 #include "opt_pcmciaverbose.h" 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/device.h> 58 59 #include <dev/pcmcia/pcmciareg.h> 60 #include <dev/pcmcia/pcmciachip.h> 61 #include <dev/pcmcia/pcmciavar.h> 62 #ifdef IT8368E_LEGACY_MODE /* XXX -uch */ 63 #include <arch/hpcmips/dev/it8368var.h> 64 #endif 65 66 #include "locators.h" 67 68 #ifdef PCMCIADEBUG 69 int pcmcia_debug = 0; 70 #define DPRINTF(arg) if (pcmcia_debug) printf arg 71 #else 72 #define DPRINTF(arg) 73 #endif 74 75 #ifdef PCMCIAVERBOSE 76 int pcmcia_verbose = 1; 77 #else 78 int pcmcia_verbose = 0; 79 #endif 80 81 int pcmcia_match(struct device *, struct cfdata *, void *); 82 void pcmcia_attach(struct device *, struct device *, void *); 83 int pcmcia_rescan(struct device *, const char *, const int *); 84 void pcmcia_childdetached(struct device *, struct device *); 85 int pcmcia_print(void *, const char *); 86 87 CFATTACH_DECL2(pcmcia, sizeof(struct pcmcia_softc), 88 pcmcia_match, pcmcia_attach, NULL, NULL, 89 pcmcia_rescan, pcmcia_childdetached); 90 91 int 92 pcmcia_ccr_read(pf, ccr) 93 struct pcmcia_function *pf; 94 int ccr; 95 { 96 97 return (bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh, 98 pf->pf_ccr_offset + ccr * 2)); 99 } 100 101 void 102 pcmcia_ccr_write(pf, ccr, val) 103 struct pcmcia_function *pf; 104 int ccr; 105 int val; 106 { 107 108 if (pf->ccr_mask & (1 << ccr)) { 109 bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh, 110 pf->pf_ccr_offset + ccr * 2, val); 111 } 112 } 113 114 int 115 pcmcia_match(parent, match, aux) 116 struct device *parent; 117 struct cfdata *match; 118 void *aux; 119 { 120 struct pcmciabus_attach_args *paa = aux; 121 122 if (strcmp(paa->paa_busname, match->cf_name)) { 123 return 0; 124 } 125 /* if the autoconfiguration got this far, there's a socket here */ 126 return (1); 127 } 128 129 void 130 pcmcia_attach(parent, self, aux) 131 struct device *parent, *self; 132 void *aux; 133 { 134 struct pcmciabus_attach_args *paa = aux; 135 struct pcmcia_softc *sc = (struct pcmcia_softc *) self; 136 137 printf("\n"); 138 139 sc->pct = paa->pct; 140 sc->pch = paa->pch; 141 sc->iobase = paa->iobase; 142 sc->iosize = paa->iosize; 143 144 sc->ih = NULL; 145 } 146 147 int 148 pcmcia_card_attach(dev) 149 struct device *dev; 150 { 151 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev; 152 struct pcmcia_function *pf; 153 int error; 154 static const int wildcard[PCMCIACF_NLOCS] = { 155 PCMCIACF_FUNCTION_DEFAULT, PCMCIACF_IRQ_DEFAULT 156 }; 157 158 /* 159 * this is here so that when socket_enable calls gettype, trt happens 160 */ 161 SIMPLEQ_FIRST(&sc->card.pf_head) = NULL; 162 163 pcmcia_socket_enable(dev); 164 165 pcmcia_read_cis(sc); 166 pcmcia_check_cis_quirks(sc); 167 168 #if 1 /* XXX remove this, done below ??? */ 169 /* 170 * bail now if the card has no functions, or if there was an error in 171 * the cis. 172 */ 173 if (sc->card.error || 174 SIMPLEQ_EMPTY(&sc->card.pf_head)) { 175 printf("%s: card appears to have bogus CIS\n", 176 sc->dev.dv_xname); 177 error = EIO; 178 goto done; 179 } 180 #endif 181 182 if (pcmcia_verbose) 183 pcmcia_print_cis(sc); 184 185 SIMPLEQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 186 if (SIMPLEQ_EMPTY(&pf->cfe_head)) 187 continue; 188 189 #ifdef DIAGNOSTIC 190 if (pf->child != NULL) { 191 printf("%s: %s still attached to function %d!\n", 192 sc->dev.dv_xname, pf->child->dv_xname, 193 pf->number); 194 panic("pcmcia_card_attach"); 195 } 196 #endif 197 pf->sc = sc; 198 pf->child = NULL; 199 pf->cfe = NULL; 200 pf->pf_ih = NULL; 201 } 202 203 error = pcmcia_rescan(dev, "pcmcia", wildcard); 204 done: 205 pcmcia_socket_disable(dev); 206 return (error); 207 } 208 209 int 210 pcmcia_rescan(struct device *self, const char *ifattr, const int *locators) 211 { 212 struct pcmcia_softc *sc = (struct pcmcia_softc *)self; 213 struct pcmcia_function *pf; 214 struct pcmcia_attach_args paa; 215 int locs[PCMCIACF_NLOCS]; 216 217 if (sc->card.error || 218 SIMPLEQ_EMPTY(&sc->card.pf_head)) { 219 /* XXX silently ignore if no card present? */ 220 return (EIO); 221 } 222 223 SIMPLEQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 224 if (SIMPLEQ_EMPTY(&pf->cfe_head)) 225 continue; 226 227 if ((locators[PCMCIACF_FUNCTION] != PCMCIACF_FUNCTION_DEFAULT) 228 && (locators[PCMCIACF_FUNCTION] != pf->number)) 229 continue; 230 231 if (pf->child) 232 continue; 233 234 locs[PCMCIACF_FUNCTION] = pf->number; 235 locs[PCMCIACF_IRQ] = PCMCIACF_IRQ_DEFAULT; 236 237 paa.manufacturer = sc->card.manufacturer; 238 paa.product = sc->card.product; 239 paa.card = &sc->card; 240 paa.pf = pf; 241 242 pf->child = config_found_sm_loc(self, "pcmcia", locs, &paa, 243 pcmcia_print, 244 config_stdsubmatch); 245 } 246 247 return (0); 248 } 249 250 void 251 pcmcia_card_detach(dev, flags) 252 struct device *dev; 253 int flags; /* DETACH_* flags */ 254 { 255 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev; 256 struct pcmcia_function *pf; 257 int error; 258 259 /* 260 * We are running on either the PCMCIA socket's event thread 261 * or in user context detaching a device by user request. 262 */ 263 SIMPLEQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 264 pf->pf_flags |= PFF_DETACHED; 265 if (SIMPLEQ_EMPTY(&pf->cfe_head)) 266 continue; 267 if (pf->child == NULL) 268 continue; 269 DPRINTF(("%s: detaching %s (function %d)\n", 270 sc->dev.dv_xname, pf->child->dv_xname, pf->number)); 271 if ((error = config_detach(pf->child, flags)) != 0) { 272 printf("%s: error %d detaching %s (function %d)\n", 273 sc->dev.dv_xname, error, pf->child->dv_xname, 274 pf->number); 275 } 276 } 277 278 if (sc->sc_enabled_count != 0) { 279 #ifdef DIAGNOSTIC 280 printf("pcmcia_card_detach: enabled_count should be 0 here??\n"); 281 #endif 282 pcmcia_chip_socket_disable(sc->pct, sc->pch); 283 sc->sc_enabled_count = 0; 284 } 285 } 286 287 void 288 pcmcia_childdetached(struct device *self, struct device *child) 289 { 290 struct pcmcia_softc *sc = (struct pcmcia_softc *)self; 291 struct pcmcia_function *pf; 292 293 SIMPLEQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 294 if (SIMPLEQ_EMPTY(&pf->cfe_head)) 295 continue; 296 if (pf->child == child) { 297 KASSERT(child->dv_locators[PCMCIACF_FUNCTION] 298 == pf->number); 299 pf->child = NULL; 300 return; 301 } 302 } 303 304 printf("%s: pcmcia_childdetached: %s not found\n", 305 self->dv_xname, child->dv_xname); 306 } 307 308 void 309 pcmcia_card_deactivate(dev) 310 struct device *dev; 311 { 312 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev; 313 struct pcmcia_function *pf; 314 315 /* 316 * We're in the chip's card removal interrupt handler. 317 * Deactivate the child driver. The PCMCIA socket's 318 * event thread will run later to finish the detach. 319 */ 320 SIMPLEQ_FOREACH(pf, &sc->card.pf_head, pf_list) { 321 if (SIMPLEQ_EMPTY(&pf->cfe_head)) 322 continue; 323 if (pf->child == NULL) 324 continue; 325 DPRINTF(("%s: deactivating %s (function %d)\n", 326 sc->dev.dv_xname, pf->child->dv_xname, pf->number)); 327 config_deactivate(pf->child); 328 } 329 } 330 331 int 332 pcmcia_print(arg, pnp) 333 void *arg; 334 const char *pnp; 335 { 336 struct pcmcia_attach_args *pa = arg; 337 struct pcmcia_softc *sc = pa->pf->sc; 338 struct pcmcia_card *card = &sc->card; 339 char devinfo[256]; 340 341 if (pnp) 342 aprint_normal("%s", pnp); 343 344 pcmcia_devinfo(card, !!pnp, devinfo, sizeof(devinfo)); 345 346 aprint_normal(" function %d: %s\n", pa->pf->number, devinfo); 347 348 return (UNCONF); 349 } 350 351 void 352 pcmcia_devinfo(card, showhex, cp, cplen) 353 struct pcmcia_card *card; 354 int showhex; 355 char *cp; 356 size_t cplen; 357 { 358 int i, n; 359 360 if (cplen > 1) { 361 *cp++ = '<'; 362 *cp = '\0'; 363 cplen--; 364 } 365 366 for (i = 0; i < 4 && card->cis1_info[i] != NULL && cplen > 1; i++) { 367 n = snprintf(cp, cplen, "%s%s", i ? ", " : "", 368 card->cis1_info[i]); 369 cp += n; 370 if (cplen < n) 371 return; 372 cplen -= n; 373 } 374 375 if (cplen > 1) { 376 *cp++ = '>'; 377 *cp = '\0'; 378 cplen--; 379 } 380 381 if (showhex && cplen > 1) 382 snprintf(cp, cplen, " (manufacturer 0x%04x, product 0x%04x)", 383 card->manufacturer, card->product); 384 } 385 386 const void * 387 pcmcia_product_lookup(pa, tab, nent, ent_size, matchfn) 388 struct pcmcia_attach_args *pa; 389 const void *tab; 390 size_t nent; 391 size_t ent_size; 392 pcmcia_product_match_fn matchfn; 393 { 394 const struct pcmcia_product *pp; 395 int n; 396 int matches; 397 398 #ifdef DIAGNOSTIC 399 if (sizeof *pp > ent_size) 400 panic("pcmcia_product_lookup: bogus ent_size %ld", 401 (long) ent_size); 402 #endif 403 404 for (pp = tab, n = nent; n; pp = (const struct pcmcia_product *) 405 ((const char *)pp + ent_size), n--) { 406 /* see if it matches vendor/product */ 407 matches = 0; 408 if ((pp->pp_vendor != PCMCIA_VENDOR_INVALID && 409 pp->pp_vendor == pa->manufacturer) && 410 (pp->pp_product != PCMCIA_PRODUCT_INVALID && 411 pp->pp_product == pa->product)) 412 matches = 1; 413 if ((pp->pp_cisinfo[0] && pa->card->cis1_info[0] && 414 !strcmp(pp->pp_cisinfo[0], pa->card->cis1_info[0])) && 415 (pp->pp_cisinfo[1] && pa->card->cis1_info[1] && 416 !strcmp(pp->pp_cisinfo[1], pa->card->cis1_info[1])) && 417 (!pp->pp_cisinfo[2] || (pa->card->cis1_info[2] && 418 !strcmp(pp->pp_cisinfo[2], pa->card->cis1_info[2]))) && 419 (!pp->pp_cisinfo[3] || (pa->card->cis1_info[3] && 420 !strcmp(pp->pp_cisinfo[3], pa->card->cis1_info[3])))) 421 matches = 1; 422 423 /* if a separate match function is given, let it override */ 424 if (matchfn) 425 matches = (*matchfn)(pa, pp, matches); 426 427 if (matches) 428 return (pp); 429 } 430 return (0); 431 } 432 433 void 434 pcmcia_socket_settype(dev, type) 435 struct device *dev; 436 int type; 437 { 438 struct pcmcia_softc *sc = (void *)dev; 439 440 pcmcia_chip_socket_settype(sc->pct, sc->pch, type); 441 } 442 443 /* 444 * Initialize a PCMCIA function. May be called as long as the function is 445 * disabled. 446 */ 447 void 448 pcmcia_function_init(pf, cfe) 449 struct pcmcia_function *pf; 450 struct pcmcia_config_entry *cfe; 451 { 452 if (pf->pf_flags & PFF_ENABLED) 453 panic("pcmcia_function_init: function is enabled"); 454 455 /* Remember which configuration entry we are using. */ 456 pf->cfe = cfe; 457 } 458 459 void 460 pcmcia_socket_enable(dev) 461 struct device *dev; 462 { 463 struct pcmcia_softc *sc = (void *)dev; 464 465 if (sc->sc_enabled_count++ == 0) 466 pcmcia_chip_socket_enable(sc->pct, sc->pch); 467 DPRINTF(("%s: ++enabled_count = %d\n", sc->dev.dv_xname, 468 sc->sc_enabled_count)); 469 } 470 471 void 472 pcmcia_socket_disable(dev) 473 struct device *dev; 474 { 475 struct pcmcia_softc *sc = (void *)dev; 476 477 if (--sc->sc_enabled_count == 0) 478 pcmcia_chip_socket_disable(sc->pct, sc->pch); 479 DPRINTF(("%s: --enabled_count = %d\n", sc->dev.dv_xname, 480 sc->sc_enabled_count)); 481 } 482 483 /* Enable a PCMCIA function */ 484 int 485 pcmcia_function_enable(pf) 486 struct pcmcia_function *pf; 487 { 488 struct pcmcia_softc *sc = pf->sc; 489 struct pcmcia_function *tmp; 490 int reg; 491 int error; 492 493 if (pf->cfe == NULL) 494 panic("pcmcia_function_enable: function not initialized"); 495 496 /* 497 * Increase the reference count on the socket, enabling power, if 498 * necessary. 499 */ 500 pcmcia_socket_enable(&sc->dev); 501 pcmcia_socket_settype(&sc->dev, pf->cfe->iftype); 502 503 if (pf->pf_flags & PFF_ENABLED) { 504 /* 505 * Don't do anything if we're already enabled. 506 */ 507 return (0); 508 } 509 510 /* 511 * it's possible for different functions' CCRs to be in the same 512 * underlying page. Check for that. 513 */ 514 515 SIMPLEQ_FOREACH(tmp, &sc->card.pf_head, pf_list) { 516 if ((tmp->pf_flags & PFF_ENABLED) && 517 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) && 518 ((pf->ccr_base + PCMCIA_CCR_SIZE) <= 519 (tmp->ccr_base - tmp->pf_ccr_offset + 520 tmp->pf_ccr_realsize))) { 521 pf->pf_ccrt = tmp->pf_ccrt; 522 pf->pf_ccrh = tmp->pf_ccrh; 523 pf->pf_ccr_realsize = tmp->pf_ccr_realsize; 524 525 /* 526 * pf->pf_ccr_offset = (tmp->pf_ccr_offset - 527 * tmp->ccr_base) + pf->ccr_base; 528 */ 529 pf->pf_ccr_offset = 530 (tmp->pf_ccr_offset + pf->ccr_base) - 531 tmp->ccr_base; 532 pf->pf_ccr_window = tmp->pf_ccr_window; 533 break; 534 } 535 } 536 537 if (tmp == NULL) { 538 error = pcmcia_mem_alloc(pf, PCMCIA_CCR_SIZE, &pf->pf_pcmh); 539 if (error) 540 goto bad; 541 542 error = pcmcia_mem_map(pf, PCMCIA_MEM_ATTR, pf->ccr_base, 543 PCMCIA_CCR_SIZE, &pf->pf_pcmh, &pf->pf_ccr_offset, 544 &pf->pf_ccr_window); 545 if (error) { 546 pcmcia_mem_free(pf, &pf->pf_pcmh); 547 goto bad; 548 } 549 } 550 551 if (pcmcia_mfc(sc) || 1) { 552 pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE0, 553 (pf->pf_mfc_iobase >> 0) & 0xff); 554 pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE1, 555 (pf->pf_mfc_iobase >> 8) & 0xff); 556 pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE2, 557 (pf->pf_mfc_iobase >> 16) & 0xff); 558 pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE3, 559 (pf->pf_mfc_iobase >> 24) & 0xff); 560 pcmcia_ccr_write(pf, PCMCIA_CCR_IOLIMIT, 561 pf->pf_mfc_iomax - pf->pf_mfc_iobase); 562 } 563 564 reg = 0; 565 if (pf->cfe->flags & PCMCIA_CFE_AUDIO) 566 reg |= PCMCIA_CCR_STATUS_AUDIO; 567 pcmcia_ccr_write(pf, PCMCIA_CCR_STATUS, reg); 568 569 pcmcia_ccr_write(pf, PCMCIA_CCR_SOCKETCOPY, 0); 570 571 reg = (pf->cfe->number & PCMCIA_CCR_OPTION_CFINDEX); 572 reg |= PCMCIA_CCR_OPTION_LEVIREQ; 573 if (pcmcia_mfc(sc)) { 574 reg |= (PCMCIA_CCR_OPTION_FUNC_ENABLE | 575 PCMCIA_CCR_OPTION_ADDR_DECODE); 576 if (pf->pf_ih) 577 reg |= PCMCIA_CCR_OPTION_IREQ_ENABLE; 578 579 } 580 pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg); 581 582 #ifdef PCMCIADEBUG 583 if (pcmcia_debug) { 584 SIMPLEQ_FOREACH(tmp, &sc->card.pf_head, pf_list) { 585 printf("%s: function %d CCR at %d offset %lx: " 586 "%x %x %x %x, %x %x %x %x, %x\n", 587 tmp->sc->dev.dv_xname, tmp->number, 588 tmp->pf_ccr_window, 589 (unsigned long) tmp->pf_ccr_offset, 590 pcmcia_ccr_read(tmp, 0), 591 pcmcia_ccr_read(tmp, 1), 592 pcmcia_ccr_read(tmp, 2), 593 pcmcia_ccr_read(tmp, 3), 594 595 pcmcia_ccr_read(tmp, 5), 596 pcmcia_ccr_read(tmp, 6), 597 pcmcia_ccr_read(tmp, 7), 598 pcmcia_ccr_read(tmp, 8), 599 600 pcmcia_ccr_read(tmp, 9)); 601 } 602 } 603 #endif 604 605 #ifdef IT8368E_LEGACY_MODE 606 /* return to I/O mode */ 607 it8368_mode(pf, IT8368_IO_MODE, IT8368_WIDTH_16); 608 #endif 609 610 pf->pf_flags |= PFF_ENABLED; 611 return (0); 612 613 bad: 614 /* 615 * Decrement the reference count, and power down the socket, if 616 * necessary. 617 */ 618 printf("%s: couldn't map the CCR\n", pf->child->dv_xname); 619 pcmcia_socket_disable(&sc->dev); 620 621 return (error); 622 } 623 624 /* Disable PCMCIA function. */ 625 void 626 pcmcia_function_disable(pf) 627 struct pcmcia_function *pf; 628 { 629 struct pcmcia_softc *sc = pf->sc; 630 struct pcmcia_function *tmp; 631 int reg; 632 633 if (pf->cfe == NULL) 634 panic("pcmcia_function_enable: function not initialized"); 635 636 if ((pf->pf_flags & PFF_ENABLED) == 0) { 637 /* 638 * Don't do anything but decrement if we're already disabled. 639 */ 640 goto out; 641 } 642 643 if (pcmcia_mfc(sc) && 644 (pf->pf_flags & PFF_DETACHED) == 0) { 645 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION); 646 reg &= ~(PCMCIA_CCR_OPTION_FUNC_ENABLE| 647 PCMCIA_CCR_OPTION_ADDR_DECODE| 648 PCMCIA_CCR_OPTION_IREQ_ENABLE); 649 pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg); 650 } 651 652 /* 653 * it's possible for different functions' CCRs to be in the same 654 * underlying page. Check for that. Note we mark us as disabled 655 * first to avoid matching ourself. 656 */ 657 658 pf->pf_flags &= ~PFF_ENABLED; 659 SIMPLEQ_FOREACH(tmp, &sc->card.pf_head, pf_list) { 660 if ((tmp->pf_flags & PFF_ENABLED) && 661 (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) && 662 ((pf->ccr_base + PCMCIA_CCR_SIZE) <= 663 (tmp->ccr_base - tmp->pf_ccr_offset + tmp->pf_ccr_realsize))) 664 break; 665 } 666 667 /* Not used by anyone else; unmap the CCR. */ 668 if (tmp == NULL) { 669 pcmcia_mem_unmap(pf, pf->pf_ccr_window); 670 pcmcia_mem_free(pf, &pf->pf_pcmh); 671 } 672 673 out: 674 /* 675 * Decrement the reference count, and power down the socket, if 676 * necessary. 677 */ 678 pcmcia_socket_disable(&sc->dev); 679 } 680 681 int 682 pcmcia_io_map(pf, width, pcihp, windowp) 683 struct pcmcia_function *pf; 684 int width; 685 struct pcmcia_io_handle *pcihp; 686 int *windowp; 687 { 688 struct pcmcia_softc *sc = pf->sc; 689 int error; 690 691 if (pf->pf_flags & PFF_ENABLED) 692 printf("pcmcia_io_map: function is enabled!\n"); 693 694 error = pcmcia_chip_io_map(sc->pct, sc->pch, 695 width, 0, pcihp->size, pcihp, windowp); 696 if (error) 697 return (error); 698 699 /* 700 * XXX in the multifunction multi-iospace-per-function case, this 701 * needs to cooperate with io_alloc to make sure that the spaces 702 * don't overlap, and that the ccr's are set correctly 703 */ 704 705 if (pcmcia_mfc(sc) || 1) { 706 bus_addr_t iobase = pcihp->addr; 707 bus_addr_t iomax = pcihp->addr + pcihp->size - 1; 708 709 DPRINTF(("window iobase %lx iomax %lx\n", (long)iobase, 710 (long)iomax)); 711 if (pf->pf_mfc_iobase == 0) { 712 pf->pf_mfc_iobase = iobase; 713 pf->pf_mfc_iomax = iomax; 714 } else { 715 if (iobase < pf->pf_mfc_iobase) 716 pf->pf_mfc_iobase = iobase; 717 if (iomax > pf->pf_mfc_iomax) 718 pf->pf_mfc_iomax = iomax; 719 } 720 DPRINTF(("function iobase %lx iomax %lx\n", 721 (long)pf->pf_mfc_iobase, (long)pf->pf_mfc_iomax)); 722 } 723 724 return (0); 725 } 726 727 void 728 pcmcia_io_unmap(pf, window) 729 struct pcmcia_function *pf; 730 int window; 731 { 732 struct pcmcia_softc *sc = pf->sc; 733 734 if (pf->pf_flags & PFF_ENABLED) 735 printf("pcmcia_io_unmap: function is enabled!\n"); 736 737 pcmcia_chip_io_unmap(sc->pct, sc->pch, window); 738 } 739 740 void * 741 pcmcia_intr_establish(pf, ipl, ih_fct, ih_arg) 742 struct pcmcia_function *pf; 743 int ipl; 744 int (*ih_fct)(void *); 745 void *ih_arg; 746 { 747 748 if (pf->pf_flags & PFF_ENABLED) 749 printf("pcmcia_intr_establish: function is enabled!\n"); 750 if (pf->pf_ih) 751 panic("pcmcia_intr_establish: already done\n"); 752 753 pf->pf_ih = pcmcia_chip_intr_establish(pf->sc->pct, pf->sc->pch, 754 pf, ipl, ih_fct, ih_arg); 755 if (!pf->pf_ih) 756 printf("%s: interrupt establish failed\n", pf->child->dv_xname); 757 return (pf->pf_ih); 758 } 759 760 void 761 pcmcia_intr_disestablish(pf, ih) 762 struct pcmcia_function *pf; 763 void *ih; 764 { 765 766 if (pf->pf_flags & PFF_ENABLED) 767 printf("pcmcia_intr_disestablish: function is enabled!\n"); 768 if (!pf->pf_ih) 769 panic("pcmcia_intr_distestablish: already done\n"); 770 771 pcmcia_chip_intr_disestablish(pf->sc->pct, pf->sc->pch, ih); 772 pf->pf_ih = 0; 773 } 774 775 int 776 pcmcia_config_alloc(pf, cfe) 777 struct pcmcia_function *pf; 778 struct pcmcia_config_entry *cfe; 779 { 780 int error = 0; 781 int n, m; 782 783 for (n = 0; n < cfe->num_iospace; n++) { 784 bus_addr_t start = cfe->iospace[n].start; 785 bus_size_t length = cfe->iospace[n].length; 786 bus_size_t align = cfe->iomask ? (1 << cfe->iomask) : 787 length; 788 bus_size_t skew = start & (align - 1); 789 790 if ((start - skew) == 0 && align < 0x400) { 791 if (skew) 792 printf("Drats! I need a skew!\n"); 793 start = 0; 794 } 795 796 DPRINTF(("pcmcia_config_alloc: io %d start=%lx length=%lx align=%lx skew=%lx\n", 797 n, (long)start, (long)length, (long)align, (long)skew)); 798 799 error = pcmcia_io_alloc(pf, start, length, align, 800 &cfe->iospace[n].handle); 801 if (error) 802 break; 803 } 804 if (n < cfe->num_iospace) { 805 for (m = 0; m < n; m++) 806 pcmcia_io_free(pf, &cfe->iospace[m].handle); 807 return (error); 808 } 809 810 for (n = 0; n < cfe->num_memspace; n++) { 811 bus_size_t length = cfe->memspace[n].length; 812 813 DPRINTF(("pcmcia_config_alloc: mem %d length %lx\n", n, 814 (long)length)); 815 816 error = pcmcia_mem_alloc(pf, length, &cfe->memspace[n].handle); 817 if (error) 818 break; 819 } 820 if (n < cfe->num_memspace) { 821 for (m = 0; m < cfe->num_iospace; m++) 822 pcmcia_io_free(pf, &cfe->iospace[m].handle); 823 for (m = 0; m < n; m++) 824 pcmcia_mem_free(pf, &cfe->memspace[m].handle); 825 return (error); 826 } 827 828 /* This one's good! */ 829 return (error); 830 } 831 832 void 833 pcmcia_config_free(pf) 834 struct pcmcia_function *pf; 835 { 836 struct pcmcia_config_entry *cfe = pf->cfe; 837 int m; 838 839 for (m = 0; m < cfe->num_iospace; m++) 840 pcmcia_io_free(pf, &cfe->iospace[m].handle); 841 for (m = 0; m < cfe->num_memspace; m++) 842 pcmcia_mem_free(pf, &cfe->memspace[m].handle); 843 } 844 845 int 846 pcmcia_config_map(pf) 847 struct pcmcia_function *pf; 848 { 849 struct pcmcia_config_entry *cfe = pf->cfe; 850 int error = 0; 851 int n, m; 852 853 for (n = 0; n < cfe->num_iospace; n++) { 854 int width; 855 856 if (cfe->flags & PCMCIA_CFE_IO16) 857 width = PCMCIA_WIDTH_AUTO; 858 else 859 width = PCMCIA_WIDTH_IO8; 860 error = pcmcia_io_map(pf, width, &cfe->iospace[n].handle, 861 &cfe->iospace[n].window); 862 if (error) 863 break; 864 } 865 if (n < cfe->num_iospace) { 866 for (m = 0; m < n; m++) 867 pcmcia_io_unmap(pf, cfe->iospace[m].window); 868 return (error); 869 } 870 871 for (n = 0; n < cfe->num_memspace; n++) { 872 bus_size_t length = cfe->memspace[n].length; 873 int width; 874 875 DPRINTF(("pcmcia_config_alloc: mem %d length %lx\n", n, 876 (long)length)); 877 878 /*XXX*/ 879 width = PCMCIA_WIDTH_MEM8|PCMCIA_MEM_COMMON; 880 error = pcmcia_mem_map(pf, width, 0, length, 881 &cfe->memspace[n].handle, &cfe->memspace[n].offset, 882 &cfe->memspace[n].window); 883 if (error) 884 break; 885 } 886 if (n < cfe->num_memspace) { 887 for (m = 0; m < cfe->num_iospace; m++) 888 pcmcia_io_unmap(pf, cfe->iospace[m].window); 889 for (m = 0; m < n; m++) 890 pcmcia_mem_unmap(pf, cfe->memspace[m].window); 891 return (error); 892 } 893 894 /* This one's good! */ 895 return (error); 896 } 897 898 void 899 pcmcia_config_unmap(pf) 900 struct pcmcia_function *pf; 901 { 902 struct pcmcia_config_entry *cfe = pf->cfe; 903 int m; 904 905 for (m = 0; m < cfe->num_iospace; m++) 906 pcmcia_io_unmap(pf, cfe->iospace[m].window); 907 for (m = 0; m < cfe->num_memspace; m++) 908 pcmcia_mem_unmap(pf, cfe->memspace[m].window); 909 } 910 911 int 912 pcmcia_function_configure(pf, validator) 913 struct pcmcia_function *pf; 914 int (*validator)(struct pcmcia_config_entry *); 915 { 916 struct pcmcia_config_entry *cfe; 917 int error = ENOENT; 918 919 SIMPLEQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { 920 error = validator(cfe); 921 if (error) 922 continue; 923 error = pcmcia_config_alloc(pf, cfe); 924 if (!error) 925 break; 926 } 927 if (!cfe) { 928 DPRINTF(("pcmcia_function_configure: no config entry found, error=%d\n", 929 error)); 930 return (error); 931 } 932 933 /* Remember which configuration entry we are using. */ 934 pf->cfe = cfe; 935 936 error = pcmcia_config_map(pf); 937 if (error) { 938 DPRINTF(("pcmcia_function_configure: map failed, error=%d\n", 939 error)); 940 return (error); 941 } 942 943 return (0); 944 } 945 946 void 947 pcmcia_function_unconfigure(pf) 948 struct pcmcia_function *pf; 949 { 950 951 pcmcia_config_unmap(pf); 952 pcmcia_config_free(pf); 953 } 954