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