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