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