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