Home | History | Annotate | Line # | Download | only in cardbus
cardbus.c revision 1.28
      1 /*	$NetBSD: cardbus.c,v 1.28 2000/10/12 12:42:03 wiz Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997, 1998, 1999 and 2000
      5  *     HAYAKAWA Koichi.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by HAYAKAWA Koichi.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission.
     20  *
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     25  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     26  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     30  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     32  * POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 #include "opt_cardbus.h"
     36 
     37 #include <sys/types.h>
     38 #include <sys/param.h>
     39 #include <sys/systm.h>
     40 #include <sys/device.h>
     41 #include <sys/malloc.h>
     42 #include <sys/kernel.h>
     43 #include <sys/syslog.h>
     44 #include <sys/proc.h>
     45 
     46 #include <machine/bus.h>
     47 
     48 #include <dev/cardbus/cardbusvar.h>
     49 #include <dev/cardbus/cardbusdevs.h>
     50 
     51 #include <dev/cardbus/cardbus_exrom.h>
     52 
     53 #include <dev/pci/pcivar.h>	/* XXX */
     54 #include <dev/pci/pcireg.h>	/* XXX */
     55 
     56 #include <dev/pcmcia/pcmciareg.h>
     57 
     58 #if defined CARDBUS_DEBUG
     59 #define STATIC
     60 #define DPRINTF(a) printf a
     61 #else
     62 #define STATIC static
     63 #define DPRINTF(a)
     64 #endif
     65 
     66 
     67 STATIC void cardbusattach __P((struct device *, struct device *, void *));
     68 /* STATIC int cardbusprint __P((void *, const char *)); */
     69 int cardbus_attach_card __P((struct cardbus_softc *));
     70 
     71 STATIC int cardbusmatch __P((struct device *, struct cfdata *, void *));
     72 static int cardbussubmatch __P((struct device *, struct cfdata *, void *));
     73 static int cardbusprint __P((void *, const char *));
     74 
     75 typedef void (*tuple_decode_func)(u_int8_t*, int, void*);
     76 
     77 static int decode_tuples __P((u_int8_t *, int, tuple_decode_func, void*));
     78 #ifdef CARDBUS_DEBUG
     79 static void print_tuple __P((u_int8_t*, int, void*));
     80 #endif
     81 
     82 static int cardbus_read_tuples __P((struct cardbus_attach_args *,
     83 				    cardbusreg_t, u_int8_t *, size_t));
     84 
     85 static void enable_function __P((struct cardbus_softc *, int, int));
     86 static void disable_function __P((struct cardbus_softc *, int));
     87 
     88 
     89 struct cfattach cardbus_ca = {
     90 	sizeof(struct cardbus_softc), cardbusmatch, cardbusattach
     91 };
     92 
     93 #ifndef __NetBSD_Version__
     94 struct cfdriver cardbus_cd = {
     95 	NULL, "cardbus", DV_DULL
     96 };
     97 #endif
     98 
     99 
    100 STATIC int
    101 cardbusmatch(parent, cf, aux)
    102      struct device *parent;
    103      struct cfdata *cf;
    104      void *aux;
    105 {
    106   struct cbslot_attach_args *cba = aux;
    107 
    108   if (strcmp(cba->cba_busname, cf->cf_driver->cd_name)) {
    109     DPRINTF(("cardbusmatch: busname differs %s <=> %s\n",
    110 	     cba->cba_busname, cf->cf_driver->cd_name));
    111     return 0;
    112   }
    113 
    114   return 1;
    115 }
    116 
    117 
    118 
    119 STATIC void
    120 cardbusattach(parent, self, aux)
    121      struct device *parent;
    122      struct device *self;
    123      void *aux;
    124 {
    125   struct cardbus_softc *sc = (void *)self;
    126   struct cbslot_attach_args *cba = aux;
    127   int cdstatus;
    128 
    129   sc->sc_bus = cba->cba_bus;
    130   sc->sc_device = 0;
    131   sc->sc_intrline = cba->cba_intrline;
    132   sc->sc_cacheline = cba->cba_cacheline;
    133   sc->sc_lattimer = cba->cba_lattimer;
    134 
    135   printf(": bus %d device %d", sc->sc_bus, sc->sc_device);
    136   printf(" cacheline 0x%x, lattimer 0x%x\n", sc->sc_cacheline,sc->sc_lattimer);
    137 
    138   sc->sc_iot = cba->cba_iot;	/* CardBus I/O space tag */
    139   sc->sc_memt = cba->cba_memt;	/* CardBus MEM space tag */
    140   sc->sc_dmat = cba->cba_dmat;	/* DMA tag */
    141   sc->sc_cc = cba->cba_cc;
    142   sc->sc_cf = cba->cba_cf;
    143 
    144 #if rbus
    145   sc->sc_rbus_iot = cba->cba_rbus_iot;
    146   sc->sc_rbus_memt = cba->cba_rbus_memt;
    147 #endif
    148 
    149   sc->sc_funcs = NULL;
    150 
    151   cdstatus = 0;
    152 }
    153 
    154 static int
    155 cardbus_read_tuples(ca, cis_ptr, tuples, len)
    156      struct cardbus_attach_args *ca;
    157      cardbusreg_t cis_ptr;
    158      u_int8_t *tuples;
    159      size_t len;
    160 {
    161     struct cardbus_softc *sc = ca->ca_ct->ct_sc;
    162     cardbus_chipset_tag_t cc = ca->ca_ct->ct_cc;
    163     cardbus_function_tag_t cf = ca->ca_ct->ct_cf;
    164     cardbustag_t tag = ca->ca_tag;
    165     cardbusreg_t command;
    166     int found = 0;
    167 
    168     int i, j;
    169     int cardbus_space = cis_ptr & CARDBUS_CIS_ASIMASK;
    170     bus_space_handle_t bar_memh;
    171     bus_size_t bar_size;
    172     bus_addr_t bar_addr;
    173 
    174     int reg;
    175 
    176     memset(tuples, 0, len);
    177 
    178     cis_ptr = cis_ptr & CARDBUS_CIS_ADDRMASK;
    179 
    180     switch(cardbus_space) {
    181     case CARDBUS_CIS_ASI_TUPLE:
    182 	DPRINTF(("%s: reading CIS data from configuration space\n",
    183 		 sc->sc_dev.dv_xname));
    184 	for (i = cis_ptr, j = 0; i < 0xff; i += 4) {
    185 	    u_int32_t e = (cf->cardbus_conf_read)(cc, tag, i);
    186 	    tuples[j] = 0xff & e;
    187 	    e >>= 8;
    188 	    tuples[j + 1] = 0xff & e;
    189 	    e >>= 8;
    190 	    tuples[j + 2] = 0xff & e;
    191 	    e >>= 8;
    192 	    tuples[j + 3] = 0xff & e;
    193 	    j += 4;
    194 	}
    195 	found++;
    196 	break;
    197 
    198     case CARDBUS_CIS_ASI_BAR0:
    199     case CARDBUS_CIS_ASI_BAR1:
    200     case CARDBUS_CIS_ASI_BAR2:
    201     case CARDBUS_CIS_ASI_BAR3:
    202     case CARDBUS_CIS_ASI_BAR4:
    203     case CARDBUS_CIS_ASI_BAR5:
    204     case CARDBUS_CIS_ASI_ROM:
    205 	if(cardbus_space == CARDBUS_CIS_ASI_ROM) {
    206 	    reg = CARDBUS_ROM_REG;
    207 	    DPRINTF(("%s: reading CIS data from ROM\n",
    208 		     sc->sc_dev.dv_xname));
    209 	} else {
    210 	    reg = CARDBUS_BASE0_REG + (cardbus_space - 1) * 4;
    211 	    DPRINTF(("%s: reading CIS data from BAR%d\n",
    212 		     sc->sc_dev.dv_xname, cardbus_space - 1));
    213 	}
    214 
    215 	/* XXX zero register so mapreg_map doesn't get confused by old
    216            contents */
    217 	cardbus_conf_write(cc, cf, tag, reg, 0);
    218 	if(Cardbus_mapreg_map(ca->ca_ct, reg,
    219 			      CARDBUS_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
    220 			      0,
    221 			      NULL, &bar_memh, &bar_addr, &bar_size)) {
    222 	    printf("%s: failed to map memory\n", sc->sc_dev.dv_xname);
    223 	    return 1;
    224 	}
    225 
    226 
    227 	if(cardbus_space == CARDBUS_CIS_ASI_ROM) {
    228 	    cardbusreg_t exrom;
    229 	    int save;
    230 	    struct cardbus_rom_image_head rom_image;
    231 	    struct cardbus_rom_image *p;
    232 
    233 	    save = splhigh();
    234 	    /* enable rom address decoder */
    235 	    exrom = cardbus_conf_read(cc, cf, tag, reg);
    236 	    cardbus_conf_write(cc, cf, tag, reg, exrom | 1);
    237 
    238 	    command = cardbus_conf_read(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG);
    239 	    cardbus_conf_write(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG,
    240 			       command | CARDBUS_COMMAND_MEM_ENABLE);
    241 
    242 	    if(cardbus_read_exrom(ca->ca_memt, bar_memh, &rom_image))
    243 		goto out;
    244 
    245 	    for(p = SIMPLEQ_FIRST(&rom_image);
    246 		p;
    247 		p = SIMPLEQ_NEXT(p, next)) {
    248 		if(p->rom_image == CARDBUS_CIS_ASI_ROM_IMAGE(cis_ptr)) {
    249 		    bus_space_read_region_1(p->romt, p->romh,
    250 					    CARDBUS_CIS_ADDR(cis_ptr),
    251 					    tuples, 256);
    252 		    found++;
    253 		}
    254 		break;
    255 	    }
    256 	    while((p = SIMPLEQ_FIRST(&rom_image)) != NULL) {
    257 		SIMPLEQ_REMOVE_HEAD(&rom_image, p, next);
    258 		free(p, M_DEVBUF);
    259 	    }
    260 	out:
    261 	    exrom = cardbus_conf_read(cc, cf, tag, reg);
    262 	    cardbus_conf_write(cc, cf, tag, reg, exrom & ~1);
    263 	    splx(save);
    264 	} else {
    265 	    command = cardbus_conf_read(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG);
    266 	    cardbus_conf_write(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG,
    267 			       command | CARDBUS_COMMAND_MEM_ENABLE);
    268 	    /* XXX byte order? */
    269 	    bus_space_read_region_1(ca->ca_memt, bar_memh,
    270 				    cis_ptr, tuples, 256);
    271 	    found++;
    272 	}
    273 	command = cardbus_conf_read(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG);
    274 	cardbus_conf_write(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG,
    275 			   command & ~CARDBUS_COMMAND_MEM_ENABLE);
    276 	cardbus_conf_write(cc, cf, tag, reg, 0);
    277 #if 0
    278 	/* XXX unmap memory */
    279 	(*ca->ca_ct->ct_cf->cardbus_space_free)(ca->ca_ct,
    280 						ca->ca_ct->ct_sc->sc_rbus_memt,
    281 						bar_memh, bar_size);
    282 #endif
    283 	break;
    284 
    285 #ifdef DIAGNOSTIC
    286     default:
    287 	panic("%s: bad CIS space (%d)", sc->sc_dev.dv_xname, cardbus_space);
    288 #endif
    289     }
    290     return !found;
    291 }
    292 
    293 static void
    294 parse_tuple(u_int8_t *tuple, int len, void *data)
    295 {
    296 #ifdef CARDBUS_DEBUG
    297     static const char __func__[] = "parse_tuple";
    298 #endif
    299     struct cardbus_cis_info *cis = data;
    300     int bar_index;
    301     int i;
    302     char *p;
    303     switch(tuple[0]) {
    304     case PCMCIA_CISTPL_MANFID:
    305 	if(tuple[1] != 5) {
    306 	    DPRINTF(("%s: wrong length manufacturer id (%d)\n",
    307 		     __func__, tuple[1]));
    308 	    break;
    309 	}
    310 	cis->manufacturer = tuple[2] | (tuple[3] << 8);
    311 	cis->product = tuple[4] | (tuple[5] << 8);
    312 	break;
    313     case PCMCIA_CISTPL_VERS_1:
    314 	memcpy(cis->cis1_info_buf, tuple + 2, tuple[1]);
    315 	i = 0;
    316 	p = cis->cis1_info_buf + 2;
    317 	while(i < sizeof(cis->cis1_info) / sizeof(cis->cis1_info[0])) {
    318 	    cis->cis1_info[i++] = p;
    319 	    while(*p != '\0' && *p != '\xff')
    320 		p++;
    321 	    if(*p == '\xff')
    322 		break;
    323 	    p++;
    324 	}
    325 	break;
    326     case PCMCIA_CISTPL_BAR:
    327 	if(tuple[1] != 6) {
    328 	    DPRINTF(("%s: BAR with short length (%d)\n", __func__, tuple[1]));
    329 	    break;
    330 	}
    331 	bar_index = tuple[2] & 7;
    332 	if(bar_index == 0) {
    333 	    DPRINTF(("%s: invalid ASI in BAR tuple\n", __func__));
    334 	    break;
    335 	}
    336 	bar_index--;
    337 	cis->bar[bar_index].flags = tuple[2];
    338 	cis->bar[bar_index].size = (tuple[4] << 0) |
    339 				    (tuple[5] << 8) |
    340 				    (tuple[6] << 16) |
    341 				    (tuple[7] << 24);
    342 	break;
    343     case PCMCIA_CISTPL_FUNCID:
    344 	cis->funcid = tuple[2];
    345 	break;
    346 
    347     case PCMCIA_CISTPL_FUNCE:
    348 	switch(cis->funcid) {
    349 	case PCMCIA_FUNCTION_SERIAL:
    350 	    if(tuple[1] >= 2 &&
    351 	       tuple[2] == 0 /* XXX PCMCIA_TPLFE_TYPE_SERIAL_??? */) {
    352 		cis->funce.serial.uart_type = tuple[3] & 0x1f;
    353 		cis->funce.serial.uart_present = 1;
    354 	    }
    355 	    break;
    356 	case PCMCIA_FUNCTION_NETWORK:
    357 	    if(tuple[1] >= 8 && tuple[2] == PCMCIA_TPLFE_TYPE_LAN_NID) {
    358 		if(tuple[3] > sizeof(cis->funce.network.netid)) {
    359 		    DPRINTF(("%s: unknown network id type (len = %d)\n",
    360 			     __func__, tuple[3]));
    361 		} else {
    362 		    cis->funce.network.netid_present = 1;
    363 		    memcpy(cis->funce.network.netid,
    364 			   tuple + 4, tuple[3]);
    365 		}
    366 	    }
    367 	    break;
    368 	}
    369 	break;
    370     }
    371 }
    372 
    373 /*
    374  * int cardbus_attach_card(struct cardbus_softc *sc)
    375  *
    376  *    This function attaches the card on the slot: turns on power,
    377  *    reads and analyses tuple, sets configuration index.
    378  *
    379  *    This function returns the number of recognised device functions.
    380  *    If no functions are recognised, return 0.
    381  */
    382 int
    383 cardbus_attach_card(sc)
    384      struct cardbus_softc *sc;
    385 {
    386   cardbus_chipset_tag_t cc;
    387   cardbus_function_tag_t cf;
    388   int cdstatus;
    389   cardbustag_t tag;
    390   cardbusreg_t id, class, cis_ptr;
    391   cardbusreg_t bhlc;
    392   u_int8_t tuple[2048];
    393   int function, nfunction;
    394   struct cardbus_devfunc **previous_next = &(sc->sc_funcs);
    395   struct device *csc;
    396   int no_work_funcs = 0;
    397   cardbus_devfunc_t ct;
    398 
    399   cc = sc->sc_cc;
    400   cf = sc->sc_cf;
    401 
    402   DPRINTF(("cardbus_attach_card: cb%d start\n", sc->sc_dev.dv_unit));
    403 
    404   /* inspect initial voltage */
    405   if (0 == (cdstatus = (cf->cardbus_ctrl)(cc, CARDBUS_CD))) {
    406     DPRINTF(("cardbusattach: no CardBus card on cb%d\n", sc->sc_dev.dv_unit));
    407     return 0;
    408   }
    409 
    410   enable_function(sc, cdstatus, 8); /* XXX use fake function 8 to
    411 				       keep power on during whole
    412 				       configuration */
    413   function = 0;
    414 
    415   tag = cardbus_make_tag(cc, cf, sc->sc_bus, sc->sc_device, function);
    416 
    417   /*
    418    * Wait until power comes up.  Maxmum 500 ms.
    419    */
    420   {
    421     int i;
    422     for (i = 0; i < 5; ++i) {
    423       id = cardbus_conf_read(cc, cf, tag, CARDBUS_ID_REG);
    424       if (id != 0xffffffff && id != 0) {
    425 	break;
    426       }
    427       if (cold) {		/* before kernel thread invoked */
    428 	delay(100*1000);
    429       } else {			/* thread context */
    430 	if (tsleep((void *)sc, PCATCH, "cardbus", hz/10) != EWOULDBLOCK) {
    431 	  break;
    432 	}
    433       }
    434     }
    435     if (i == 5) {
    436       return 0;
    437     }
    438   }
    439 
    440   bhlc = cardbus_conf_read(cc, cf, tag, CARDBUS_BHLC_REG);
    441   if (CARDBUS_LATTIMER(bhlc) < 0x10) {
    442     bhlc &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
    443     bhlc |= (0x10 << CARDBUS_LATTIMER_SHIFT);
    444     cardbus_conf_write(cc, cf, tag, CARDBUS_BHLC_REG, bhlc);
    445   }
    446 
    447   nfunction = CARDBUS_HDRTYPE_MULTIFN(bhlc) ? 8 : 1;
    448 
    449   for(function = 0; function < nfunction; function++) {
    450     struct cardbus_attach_args ca;
    451 
    452     tag = cardbus_make_tag(cc, cf, sc->sc_bus, sc->sc_device, function);
    453 
    454     id = cardbus_conf_read(cc, cf, tag, CARDBUS_ID_REG);
    455     class = cardbus_conf_read(cc, cf, tag, CARDBUS_CLASS_REG);
    456     cis_ptr = cardbus_conf_read(cc, cf, tag, CARDBUS_CIS_REG);
    457 
    458     /* Invalid vendor ID value? */
    459     if (CARDBUS_VENDOR(id) == CARDBUS_VENDOR_INVALID) {
    460       continue;
    461     }
    462 
    463     DPRINTF(("cardbus_attach_card: Vendor 0x%x, Product 0x%x, CIS 0x%x\n",
    464 	     CARDBUS_VENDOR(id), CARDBUS_PRODUCT(id), cis_ptr));
    465 
    466     enable_function(sc, cdstatus, function);
    467 
    468     /* clean up every BAR */
    469     cardbus_conf_write(cc, cf, tag, CARDBUS_BASE0_REG, 0);
    470     cardbus_conf_write(cc, cf, tag, CARDBUS_BASE1_REG, 0);
    471     cardbus_conf_write(cc, cf, tag, CARDBUS_BASE2_REG, 0);
    472     cardbus_conf_write(cc, cf, tag, CARDBUS_BASE3_REG, 0);
    473     cardbus_conf_write(cc, cf, tag, CARDBUS_BASE4_REG, 0);
    474     cardbus_conf_write(cc, cf, tag, CARDBUS_BASE5_REG, 0);
    475     cardbus_conf_write(cc, cf, tag, CARDBUS_ROM_REG, 0);
    476 
    477     /*
    478      * We need to allocate the ct here, since we might
    479      * need it when reading the CIS
    480      */
    481     if (NULL == (ct = (cardbus_devfunc_t)malloc(sizeof(struct cardbus_devfunc),
    482 						M_DEVBUF, M_NOWAIT))) {
    483       panic("no room for cardbus_tag");
    484     }
    485 
    486     ct->ct_cc = sc->sc_cc;
    487     ct->ct_cf = sc->sc_cf;
    488     ct->ct_bus = sc->sc_bus;
    489     ct->ct_dev = sc->sc_device;
    490     ct->ct_func = function;
    491     ct->ct_sc = sc;
    492     ct->ct_next = NULL;
    493     *previous_next = ct;
    494 
    495     memset(&ca, 0, sizeof(ca));
    496 
    497     ca.ca_unit = sc->sc_dev.dv_unit;
    498     ca.ca_ct = ct;
    499 
    500     ca.ca_iot = sc->sc_iot;
    501     ca.ca_memt = sc->sc_memt;
    502     ca.ca_dmat = sc->sc_dmat;
    503 
    504     ca.ca_tag = tag;
    505     ca.ca_device = sc->sc_device;
    506     ca.ca_function = function;
    507     ca.ca_id = id;
    508     ca.ca_class = class;
    509 
    510     ca.ca_intrline = sc->sc_intrline;
    511 
    512     bzero(tuple, 2048);
    513 
    514     if(cardbus_read_tuples(&ca, cis_ptr, tuple, sizeof(tuple))) {
    515       printf("cardbus_attach_card: failed to read CIS\n");
    516     } else {
    517 #ifdef CARDBUS_DEBUG
    518       decode_tuples(tuple, 2048, print_tuple, NULL);
    519 #endif
    520       decode_tuples(tuple, 2048, parse_tuple, &ca.ca_cis);
    521     }
    522 
    523     if (NULL == (csc = config_found_sm((void *)sc, &ca, cardbusprint, cardbussubmatch))) {
    524       /* do not match */
    525       disable_function(sc, function);
    526       free(ct, M_DEVBUF);
    527       *previous_next = NULL;
    528     } else {
    529       /* found */
    530       previous_next = &(ct->ct_next);
    531       ct->ct_device = csc;
    532       ++no_work_funcs;
    533     }
    534   }
    535   /*
    536    * XXX power down pseudo function 8 (this will power down the card
    537    * if no functions were attached).
    538    */
    539   disable_function(sc, 8);
    540 
    541   return no_work_funcs;
    542 }
    543 
    544 
    545 static int
    546 cardbussubmatch(parent, cf, aux)
    547      struct device *parent;
    548      struct cfdata *cf;
    549      void *aux;
    550 {
    551   struct cardbus_attach_args *ca = aux;
    552 
    553   if (cf->cardbuscf_dev != CARDBUS_UNK_DEV &&
    554       cf->cardbuscf_dev != ca->ca_unit) {
    555     return 0;
    556   }
    557   if (cf->cardbuscf_function != CARDBUS_UNK_FUNCTION &&
    558       cf->cardbuscf_function != ca->ca_function) {
    559     return 0;
    560   }
    561 
    562   return ((*cf->cf_attach->ca_match)(parent, cf, aux));
    563 }
    564 
    565 
    566 
    567 static int
    568 cardbusprint(aux, pnp)
    569      void *aux;
    570      const char *pnp;
    571 {
    572     struct cardbus_attach_args *ca = aux;
    573     char devinfo[256];
    574     int i;
    575     if (pnp) {
    576 	pci_devinfo(ca->ca_id, ca->ca_class, 1, devinfo);
    577 	for (i = 0; i < 4; i++) {
    578 	    if (ca->ca_cis.cis1_info[i] == NULL)
    579 		break;
    580 	    if (i)
    581 		printf(", ");
    582 	    printf("%s", ca->ca_cis.cis1_info[i]);
    583 	}
    584 	if (i)
    585 	    printf(" ");
    586 	printf("(manufacturer 0x%x, product 0x%x)", ca->ca_cis.manufacturer,
    587 	       ca->ca_cis.product);
    588 	printf(" %s at %s", devinfo, pnp);
    589     }
    590     printf(" dev %d function %d", ca->ca_device, ca->ca_function);
    591 
    592     return UNCONF;
    593 }
    594 
    595 
    596 
    597 
    598 
    599 
    600 /*
    601  * void cardbus_detach_card(struct cardbus_softc *sc)
    602  *
    603  *    This function detaches the card on the slot: detach device data
    604  *    structure and turns off the power.
    605  *
    606  *    This function must not be called under interrupt context.
    607  */
    608 void
    609 cardbus_detach_card(sc)
    610      struct cardbus_softc *sc;
    611 {
    612     struct cardbus_devfunc *ct, *ct_next, **prev_next;
    613 
    614     prev_next = &(sc->sc_funcs->ct_next);
    615 
    616     for (ct = sc->sc_funcs; ct != NULL; ct = ct_next) {
    617 	struct device *fndev = ct->ct_device;
    618 	ct_next = ct->ct_next;
    619 
    620 	DPRINTF(("%s: detaching %s\n", sc->sc_dev.dv_xname, fndev->dv_xname));
    621 	/* call device detach function */
    622 
    623 	if (0 != config_detach(fndev, 0)) {
    624 	    printf("%s: cannot detaching dev %s, function %d\n",
    625 		   sc->sc_dev.dv_xname, fndev->dv_xname, ct->ct_func);
    626 	    prev_next = &(ct->ct_next);
    627 	} else {
    628 	    sc->sc_poweron_func &= ~(1 << ct->ct_func);
    629 	    *prev_next = ct->ct_next;
    630 	    free(ct, M_DEVBUF);
    631 	}
    632     }
    633 
    634     sc->sc_poweron_func = 0;
    635     sc->sc_cf->cardbus_power(sc->sc_cc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
    636 }
    637 
    638 
    639 
    640 
    641 /*
    642  * void *cardbus_intr_establish(cc, cf, irq, level, func, arg)
    643  *   Interrupt handler of pccard.
    644  *  args:
    645  *   cardbus_chipset_tag_t *cc
    646  *   int irq:
    647  */
    648 void *
    649 cardbus_intr_establish(cc, cf, irq, level, func, arg)
    650      cardbus_chipset_tag_t cc;
    651      cardbus_function_tag_t cf;
    652      cardbus_intr_handle_t irq;
    653      int level;
    654      int (*func) __P((void *));
    655      void *arg;
    656 {
    657   DPRINTF(("- cardbus_intr_establish: irq %d\n", irq));
    658 
    659   return (*cf->cardbus_intr_establish)(cc, irq, level, func, arg);
    660 }
    661 
    662 
    663 
    664 /*
    665  * void cardbus_intr_disestablish(cc, cf, handler)
    666  *   Interrupt handler of pccard.
    667  *  args:
    668  *   cardbus_chipset_tag_t *cc
    669  */
    670 void
    671 cardbus_intr_disestablish(cc, cf, handler)
    672      cardbus_chipset_tag_t cc;
    673      cardbus_function_tag_t cf;
    674      void *handler;
    675 {
    676   DPRINTF(("- pccard_intr_disestablish\n"));
    677 
    678  (*cf->cardbus_intr_disestablish)(cc, handler);
    679   return;
    680 }
    681 
    682 
    683 
    684 /* XXX this should be merged with cardbus_function_{enable,disable},
    685    but we don't have a ct when these functions are called */
    686 
    687 static void
    688 enable_function(sc, cdstatus, function)
    689      struct cardbus_softc *sc;
    690      int cdstatus;
    691      int function;
    692 {
    693 
    694     if (sc->sc_poweron_func == 0) {
    695 	/* switch to 3V and/or wait for power to stabilize */
    696 	if (cdstatus & CARDBUS_3V_CARD) {
    697 	    sc->sc_cf->cardbus_power(sc->sc_cc, CARDBUS_VCC_3V);
    698 	} else {
    699 	    /* No cards other than 3.3V cards. */
    700 	    return;
    701 	}
    702 	(sc->sc_cf->cardbus_ctrl)(sc->sc_cc, CARDBUS_RESET);
    703     }
    704     sc->sc_poweron_func |= (1 << function);
    705 }
    706 
    707 static void
    708 disable_function(sc, function)
    709      struct cardbus_softc *sc;
    710      int function;
    711 {
    712 
    713     sc->sc_poweron_func &= ~(1 << function);
    714     if (sc->sc_poweron_func == 0) {
    715 	/* power-off because no functions are enabled */
    716 	sc->sc_cf->cardbus_power(sc->sc_cc, CARDBUS_VCC_0V);
    717     }
    718 }
    719 
    720 /*
    721  * int cardbus_function_enable(struct cardbus_softc *sc, int func)
    722  *
    723  *   This function enables a function on a card.  When no power is
    724  *  applied on the card, power will be applied on it.
    725  */
    726 int
    727 cardbus_function_enable(sc, func)
    728      struct cardbus_softc *sc;
    729      int func;
    730 {
    731   cardbus_chipset_tag_t cc = sc->sc_cc;
    732   cardbus_function_tag_t cf = sc->sc_cf;
    733   cardbusreg_t command;
    734   cardbustag_t tag;
    735 
    736   DPRINTF(("entering cardbus_function_enable...  "));
    737 
    738   /* entering critical area */
    739 
    740   enable_function(sc, CARDBUS_3V_CARD, func); /* XXX: sc_vold should be used */
    741 
    742   /* exiting critical area */
    743 
    744   tag = cardbus_make_tag(cc, cf, sc->sc_bus, sc->sc_device, func);
    745 
    746   command = cardbus_conf_read(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG);
    747   command |= (CARDBUS_COMMAND_MEM_ENABLE | CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MASTER_ENABLE); /* XXX: good guess needed */
    748 
    749   cardbus_conf_write(cc, cf, tag, CARDBUS_COMMAND_STATUS_REG, command);
    750 
    751   cardbus_free_tag(cc, cf, tag);
    752 
    753   DPRINTF(("%x\n", sc->sc_poweron_func));
    754 
    755   return 0;
    756 }
    757 
    758 
    759 /*
    760  * int cardbus_function_disable(struct cardbus_softc *, int func)
    761  *
    762  *   This function disable a function on a card.  When no functions are
    763  *  enabled, it turns off the power.
    764  */
    765 int
    766 cardbus_function_disable(sc, func)
    767      struct cardbus_softc *sc;
    768      int func;
    769 {
    770 
    771   DPRINTF(("entering cardbus_function_disable...  "));
    772 
    773   disable_function(sc, func);
    774 
    775   return 0;
    776 }
    777 
    778 
    779 /*
    780  * int cardbus_get_capability(cardbus_chipset_tag_t cc,
    781  *	cardbus_function_tag_t cf, cardbustag_t tag, int capid, int *offset,
    782  *	cardbusreg_t *value)
    783  *
    784  *	Find the specified PCI capability.
    785  */
    786 int
    787 cardbus_get_capability(cc, cf, tag, capid, offset, value)
    788 	cardbus_chipset_tag_t cc;
    789 	cardbus_function_tag_t cf;
    790 	cardbustag_t tag;
    791 	int capid;
    792 	int *offset;
    793 	cardbusreg_t *value;
    794 {
    795 	cardbusreg_t reg;
    796 	unsigned int ofs;
    797 
    798 	reg = cardbus_conf_read(cc, cf, tag, PCI_COMMAND_STATUS_REG);
    799 	if (!(reg & PCI_STATUS_CAPLIST_SUPPORT))
    800 		return (0);
    801 
    802 	ofs = PCI_CAPLIST_PTR(cardbus_conf_read(cc, cf, tag,
    803 	    PCI_CAPLISTPTR_REG));
    804 	while (ofs != 0) {
    805 #ifdef DIAGNOSTIC
    806 		if ((ofs & 3) || (ofs < 0x40))
    807 			panic("cardbus_get_capability");
    808 #endif
    809 		reg = cardbus_conf_read(cc, cf, tag, ofs);
    810 		if (PCI_CAPLIST_CAP(reg) == capid) {
    811 			if (offset)
    812 				*offset = ofs;
    813 			if (value)
    814 				*value = reg;
    815 			return (1);
    816 		}
    817 		ofs = PCI_CAPLIST_NEXT(reg);
    818 	}
    819 
    820 	return (0);
    821 }
    822 
    823 
    824 /*
    825  * below this line, there are some functions for decoding tuples.
    826  * They should go out from this file.
    827  */
    828 
    829 static u_int8_t *
    830 decode_tuple __P((u_int8_t *tuple, tuple_decode_func func, void *data));
    831 
    832 static int
    833 decode_tuples(tuple, buflen, func, data)
    834      u_int8_t *tuple;
    835      int buflen;
    836      tuple_decode_func func;
    837      void *data;
    838 {
    839   u_int8_t *tp = tuple;
    840 
    841   if (PCMCIA_CISTPL_LINKTARGET != *tuple) {
    842     DPRINTF(("WRONG TUPLE: 0x%x\n", *tuple));
    843     return 0;
    844   }
    845 
    846   while (NULL != (tp = decode_tuple(tp, func, data))) {
    847     if (tuple + buflen < tp) {
    848       break;
    849     }
    850   }
    851 
    852   return 1;
    853 }
    854 
    855 
    856 static u_int8_t *
    857 decode_tuple(tuple, func, data)
    858      u_int8_t *tuple;
    859      tuple_decode_func func;
    860      void *data;
    861 {
    862     u_int8_t type;
    863     u_int8_t len;
    864 
    865     type = tuple[0];
    866     len = tuple[1] + 2;
    867 
    868     (*func)(tuple, len, data);
    869 
    870     if (PCMCIA_CISTPL_END == type) {
    871 	return NULL;
    872     }
    873 
    874     return tuple + len;
    875 }
    876 
    877 
    878 #ifdef CARDBUS_DEBUG
    879 static char *tuple_name __P((int type));
    880 
    881 static char *
    882 tuple_name(type)
    883      int type;
    884 {
    885   static char *tuple_name_s [] = {
    886     "TPL_NULL", "TPL_DEVICE", "Reserved", "Reserved", /* 0-3 */
    887     "CONFIG_CB", "CFTABLE_ENTRY_CB", "Reserved", "BAR", /* 4-7 */
    888     "Reserved", "Reserved", "Reserved", "Reserved", /* 8-B */
    889     "Reserved", "Reserved", "Reserved", "Reserved", /* C-F */
    890     "CHECKSUM", "LONGLINK_A", "LONGLINK_C", "LINKTARGET",	/* 10-13 */
    891     "NO_LINK", "VERS_1", "ALTSTR", "DEVICE_A",
    892     "JEDEC_C", "JEDEC_A", "CONFIG", "CFTABLE_ENTRY",
    893     "DEVICE_OC", "DEVICE_OA", "DEVICE_GEO", "DEVICE_GEO_A",
    894     "MANFID", "FUNCID", "FUNCE", "SWIL", /* 20-23 */
    895     "Reserved", "Reserved", "Reserved", "Reserved", /* 24-27 */
    896     "Reserved", "Reserved", "Reserved", "Reserved", /* 28-2B */
    897     "Reserved", "Reserved", "Reserved", "Reserved", /* 2C-2F */
    898     "Reserved", "Reserved", "Reserved", "Reserved", /* 30-33 */
    899     "Reserved", "Reserved", "Reserved", "Reserved", /* 34-37 */
    900     "Reserved", "Reserved", "Reserved", "Reserved", /* 38-3B */
    901     "Reserved", "Reserved", "Reserved", "Reserved", /* 3C-3F */
    902     "VERS_2", "FORMAT", "GEOMETRY", "BYTEORDER",
    903     "DATE", "BATTERY", "ORG"
    904   };
    905 #define NAME_LEN(x) (sizeof x / sizeof(x[0]))
    906 
    907   if (type > 0 && type < NAME_LEN(tuple_name_s)) {
    908     return tuple_name_s[type];
    909   } else if (0xff == type) {
    910     return "END";
    911   } else {
    912     return "Reserved";
    913   }
    914 }
    915 
    916 static void
    917 print_tuple(tuple, len, data)
    918      u_int8_t *tuple;
    919      int len;
    920      void *data;
    921 {
    922     int i;
    923 
    924     printf("tuple: %s len %d\n", tuple_name(tuple[0]), len);
    925 
    926     for (i = 0; i < len; ++i) {
    927 	if (i % 16 == 0) {
    928 	    printf("  0x%2x:", i);
    929 	}
    930 	printf(" %x",tuple[i]);
    931 	if (i % 16 == 15) {
    932 	    printf("\n");
    933 	}
    934     }
    935     if (i % 16 != 0) {
    936 	printf("\n");
    937     }
    938 }
    939 
    940 #endif
    941