[BACK]Return to pcmcia_cis.c CVS log [TXT][DIR] Up to [local] / sys / dev / pcmcia

Annotation of sys/dev/pcmcia/pcmcia_cis.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pcmcia_cis.c,v 1.13 2005/08/01 21:58:01 fgsch Exp $   */
                      2: /*     $NetBSD: pcmcia_cis.c,v 1.9 1998/08/22 23:41:48 msaitoh Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (c) 1997 Marc Horowitz.  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 Marc Horowitz.
                     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:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: #include <sys/types.h>
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/device.h>
                     37: #include <sys/malloc.h>
                     38:
                     39: #include <dev/pcmcia/pcmciareg.h>
                     40: #include <dev/pcmcia/pcmciachip.h>
                     41: #include <dev/pcmcia/pcmciavar.h>
                     42:
                     43: #ifdef PCMCIACISDEBUG
                     44: #define        DPRINTF(arg) printf arg
                     45: #else
                     46: #define        DPRINTF(arg)
                     47: #endif
                     48:
                     49: #define        PCMCIA_CIS_SIZE         1024
                     50:
                     51: struct cis_state {
                     52:        int     count;
                     53:        int     gotmfc;
                     54:        struct pcmcia_config_entry temp_cfe;
                     55:        struct pcmcia_config_entry *default_cfe;
                     56:        struct pcmcia_card *card;
                     57:        struct pcmcia_function *pf;
                     58: };
                     59:
                     60: int    pcmcia_parse_cis_tuple(struct pcmcia_tuple *, void *);
                     61:
                     62: void
                     63: pcmcia_read_cis(sc)
                     64:        struct pcmcia_softc *sc;
                     65: {
                     66:        struct cis_state state;
                     67:
                     68:        memset(&state, 0, sizeof state);
                     69:
                     70:        state.card = &sc->card;
                     71:
                     72:        state.card->error = 0;
                     73:        state.card->cis1_major = -1;
                     74:        state.card->cis1_minor = -1;
                     75:        state.card->cis1_info[0] = NULL;
                     76:        state.card->cis1_info[1] = NULL;
                     77:        state.card->cis1_info[2] = NULL;
                     78:        state.card->cis1_info[3] = NULL;
                     79:        state.card->manufacturer = PCMCIA_VENDOR_INVALID;
                     80:        state.card->product = PCMCIA_PRODUCT_INVALID;
                     81:        SIMPLEQ_INIT(&state.card->pf_head);
                     82:
                     83:        state.pf = NULL;
                     84:
                     85:        if (pcmcia_scan_cis((struct device *)sc, pcmcia_parse_cis_tuple,
                     86:            &state) == -1)
                     87:                state.card->error++;
                     88: }
                     89:
                     90: int
                     91: pcmcia_scan_cis(dev, fct, arg)
                     92:        struct device *dev;
                     93:        int (*fct)(struct pcmcia_tuple *, void *);
                     94:        void *arg;
                     95: {
                     96:        struct pcmcia_softc *sc = (struct pcmcia_softc *) dev;
                     97:        pcmcia_chipset_tag_t pct;
                     98:        pcmcia_chipset_handle_t pch;
                     99:        int window;
                    100:        struct pcmcia_mem_handle pcmh;
                    101:        struct pcmcia_tuple tuple;
                    102:        int longlink_present;
                    103:        int longlink_common;
                    104:        u_long longlink_addr;
                    105:        int mfc_count;
                    106:        int mfc_index;
                    107:        struct {
                    108:                int     common;
                    109:                u_long  addr;
                    110:        } mfc[256 / 5];
                    111:        int ret;
                    112:
                    113:        ret = 0;
                    114:
                    115:        pct = sc->pct;
                    116:        pch = sc->pch;
                    117:
                    118:        /* allocate some memory */
                    119:
                    120:        if (pcmcia_chip_mem_alloc(pct, pch, PCMCIA_CIS_SIZE, &pcmh)) {
                    121: #ifdef DIAGNOSTIC
                    122:                printf("%s: can't alloc memory to read attributes\n",
                    123:                    sc->dev.dv_xname);
                    124: #endif
                    125:                return -1;
                    126:        }
                    127:
                    128:        /* initialize state for the primary tuple chain */
                    129:        if (pcmcia_chip_mem_map(pct, pch, PCMCIA_MEM_ATTR, 0,
                    130:            PCMCIA_CIS_SIZE, &pcmh, &tuple.ptr, &window)) {
                    131:                pcmcia_chip_mem_free(pct, pch, &pcmh);
                    132: #ifdef DIAGNOSTIC
                    133:                printf("%s: can't map memory to read attributes\n",
                    134:                    sc->dev.dv_xname);
                    135: #endif
                    136:                return -1;
                    137:        }
                    138:        tuple.memt = pcmh.memt;
                    139:        tuple.memh = pcmh.memh;
                    140:
                    141:        DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
                    142:
                    143:        tuple.mult = 2;
                    144:
                    145:        longlink_present = 1;
                    146:        longlink_common = 1;
                    147:        longlink_addr = 0;
                    148:
                    149:        mfc_count = 0;
                    150:        mfc_index = 0;
                    151:
                    152:        DPRINTF(("%s: CIS tuple chain:\n", sc->dev.dv_xname));
                    153:
                    154:        while (1) {
                    155:                while (1) {
                    156:                        /*
                    157:                         * Perform boundary check for insane cards.
                    158:                         * If CIS is too long, simulate CIS end.
                    159:                         * (This check may not be sufficient for
                    160:                         * malicious cards.)
                    161:                         */
                    162:                        if (tuple.mult * tuple.ptr >= PCMCIA_CIS_SIZE - 1
                    163:                            - 32 /* ad hoc value */ ) {
                    164:                                DPRINTF(("CISTPL_END (too long CIS)\n"));
                    165:                                tuple.code = PCMCIA_CISTPL_END;
                    166:                                goto cis_end;
                    167:                        }
                    168:
                    169:                        /* get the tuple code */
                    170:
                    171:                        tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr);
                    172:
                    173:                        /* two special-case tuples */
                    174:
                    175:                        if (tuple.code == PCMCIA_CISTPL_NULL) {
                    176:                                DPRINTF(("CISTPL_NONE\n 00\n"));
                    177:                                tuple.ptr++;
                    178:                                continue;
                    179:                        } else if (tuple.code == PCMCIA_CISTPL_END) {
                    180:                                DPRINTF(("CISTPL_END\n ff\n"));
                    181:                        cis_end:
                    182:                                /* Call the function for the END tuple, since
                    183:                                   the CIS semantics depend on it */
                    184:                                if ((*fct) (&tuple, arg)) {
                    185:                                        pcmcia_chip_mem_unmap(pct, pch,
                    186:                                                              window);
                    187:                                        ret = 1;
                    188:                                        goto done;
                    189:                                }
                    190:                                tuple.ptr++;
                    191:                                break;
                    192:                        }
                    193:                        /* now all the normal tuples */
                    194:
                    195:                        tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1);
                    196:                        switch (tuple.code) {
                    197:                        case PCMCIA_CISTPL_LONGLINK_A:
                    198:                        case PCMCIA_CISTPL_LONGLINK_C:
                    199:                                if (tuple.length < 4) {
                    200:                                        DPRINTF(("CISTPL_LONGLINK_%s too "
                    201:                                            "short %d\n",
                    202:                                            longlink_common ? "C" : "A",
                    203:                                            tuple.length));
                    204:                                        break;
                    205:                                }
                    206:                                longlink_present = 1;
                    207:                                longlink_common = (tuple.code ==
                    208:                                    PCMCIA_CISTPL_LONGLINK_C) ? 1 : 0;
                    209:                                longlink_addr = pcmcia_tuple_read_4(&tuple, 0);
                    210:                                DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
                    211:                                    longlink_common ? "C" : "A",
                    212:                                    longlink_addr));
                    213:                                break;
                    214:                        case PCMCIA_CISTPL_NO_LINK:
                    215:                                longlink_present = 0;
                    216:                                DPRINTF(("CISTPL_NO_LINK\n"));
                    217:                                break;
                    218:                        case PCMCIA_CISTPL_CHECKSUM:
                    219:                                if (tuple.length < 5) {
                    220:                                        DPRINTF(("CISTPL_CHECKSUM too "
                    221:                                            "short %d\n", tuple.length));
                    222:                                        break;
                    223:                                } {
                    224:                                        int16_t offset;
                    225:                                        u_long addr, length;
                    226:                                        u_int cksum, sum;
                    227:                                        int i;
                    228:
                    229:                                        *((u_int16_t *) & offset) =
                    230:                                            pcmcia_tuple_read_2(&tuple, 0);
                    231:                                        length = pcmcia_tuple_read_2(&tuple, 2);
                    232:                                        cksum = pcmcia_tuple_read_1(&tuple, 4);
                    233:
                    234:                                        addr = tuple.ptr + offset;
                    235:
                    236:                                        DPRINTF(("CISTPL_CHECKSUM addr=%lx "
                    237:                                            "len=%lx cksum=%x",
                    238:                                            addr, length, cksum));
                    239:
                    240:                                        /*
                    241:                                         * XXX do more work to deal with
                    242:                                         * distant regions
                    243:                                         */
                    244:                                        if ((addr >= PCMCIA_CIS_SIZE) ||
                    245:                                            ((addr + length) < 0) ||
                    246:                                            ((addr + length) >=
                    247:                                              PCMCIA_CIS_SIZE)) {
                    248:                                                DPRINTF((" skipped, "
                    249:                                                    "too distant\n"));
                    250:                                                break;
                    251:                                        }
                    252:                                        sum = 0;
                    253:                                        for (i = 0; i < length; i++)
                    254:                                                sum +=
                    255:                                                    bus_space_read_1(tuple.memt,
                    256:                                                    tuple.memh,
                    257:                                                    addr + tuple.mult * i);
                    258:                                        if (cksum != (sum & 0xff)) {
                    259:                                                DPRINTF((" failed sum=%x\n",
                    260:                                                    sum));
                    261:                                                printf("%s: CIS checksum "
                    262:                                                    "failed\n",
                    263:                                                    sc->dev.dv_xname);
                    264: #if 0
                    265:                                                /*
                    266:                                                 * XXX Some working cards have
                    267:                                                 * XXX bad checksums!!
                    268:                                                 */
                    269:                                                ret = -1;
                    270: #endif
                    271:                                        } else {
                    272:                                                DPRINTF((" ok\n"));
                    273:                                        }
                    274:                                }
                    275:                                break;
                    276:                        case PCMCIA_CISTPL_LONGLINK_MFC:
                    277:                                if (tuple.length < 6) {
                    278:                                        DPRINTF(("CISTPL_LONGLINK_MFC too "
                    279:                                            "short %d\n", tuple.length));
                    280:                                        break;
                    281:                                }
                    282:                                if (((tuple.length - 1) % 5) != 0) {
                    283:                                        DPRINTF(("CISTPL_LONGLINK_MFC bogus "
                    284:                                            "length %d\n", tuple.length));
                    285:                                        break;
                    286:                                }
                    287:                                {
                    288:                                        int i, tmp_count;
                    289:
                    290:                                        /*
                    291:                                         * put count into tmp var so that
                    292:                                         * if we have to bail (because it's
                    293:                                         * a bogus count) it won't be
                    294:                                         * remembered for later use.
                    295:                                         */
                    296:                                        tmp_count =
                    297:                                            pcmcia_tuple_read_1(&tuple, 0);
                    298:                                        DPRINTF(("CISTPL_LONGLINK_MFC %d",
                    299:                                            tmp_count));
                    300:
                    301:                                        /*
                    302:                                         * make _sure_ it's the right size;
                    303:                                         * if too short, it may be a weird
                    304:                                         * (unknown/undefined) format
                    305:                                         */
                    306:                                        if (tuple.length != (tmp_count*5 + 1)) {
                    307:                                                DPRINTF((" bogus length %d\n",
                    308:                                                    tuple.length));
                    309:                                                break;
                    310:                                        }
                    311:
                    312: #ifdef PCMCIACISDEBUG  /* maybe enable all the time? */
                    313:                                        /*
                    314:                                         * sanity check for a programming
                    315:                                         * error which is difficult to find
                    316:                                         * when debugging.
                    317:                                         */
                    318:                                        if (tmp_count >
                    319:                                            howmany(sizeof mfc, sizeof mfc[0]))
                    320:                                                panic("CISTPL_LONGLINK_MFC mfc "
                    321:                                                    "count would blow stack");
                    322: #endif
                    323:
                    324:                                        mfc_count = tmp_count;
                    325:                                        for (i = 0; i < mfc_count; i++) {
                    326:                                                mfc[i].common =
                    327:                                                    (pcmcia_tuple_read_1(&tuple,
                    328:                                                    1 + 5 * i) ==
                    329:                                                    PCMCIA_MFC_MEM_COMMON) ?
                    330:                                                    1 : 0;
                    331:                                                mfc[i].addr =
                    332:                                                    pcmcia_tuple_read_4(&tuple,
                    333:                                                    1 + 5 * i + 1);
                    334:                                                DPRINTF((" %s:%lx",
                    335:                                                    mfc[i].common ? "common" :
                    336:                                                    "attr", mfc[i].addr));
                    337:                                        }
                    338:                                        DPRINTF(("\n"));
                    339:                                }
                    340:                                /*
                    341:                                 * for LONGLINK_MFC, fall through to the
                    342:                                 * function.  This tuple has structural and
                    343:                                 * semantic content.
                    344:                                 */
                    345:                        default:
                    346:                                {
                    347:                                        if ((*fct) (&tuple, arg)) {
                    348:                                                pcmcia_chip_mem_unmap(pct,
                    349:                                                    pch, window);
                    350:                                                ret = 1;
                    351:                                                goto done;
                    352:                                        }
                    353:                                }
                    354:                                break;
                    355:                        }       /* switch */
                    356: #ifdef PCMCIACISDEBUG
                    357:                        /* print the tuple */
                    358:                        {
                    359:                                int i;
                    360:
                    361:                                DPRINTF((" %02x %02x", tuple.code,
                    362:                                    tuple.length));
                    363:
                    364:                                for (i = 0; i < tuple.length; i++) {
                    365:                                        DPRINTF((" %02x",
                    366:                                            pcmcia_tuple_read_1(&tuple, i)));
                    367:                                        if ((i % 16) == 13)
                    368:                                                DPRINTF(("\n"));
                    369:                                }
                    370:                                if ((i % 16) != 14)
                    371:                                        DPRINTF(("\n"));
                    372:                        }
                    373: #endif
                    374:                        /* skip to the next tuple */
                    375:                        tuple.ptr += 2 + tuple.length;
                    376:                }
                    377:
                    378:                /*
                    379:                 * the chain is done.  Clean up and move onto the next one,
                    380:                 * if any.  The loop is here in the case that there is an MFC
                    381:                 * card with no longlink (which defaults to existing, == 0).
                    382:                 * In general, this means that if one pointer fails, it will
                    383:                 * try the next one, instead of just bailing.
                    384:                 */
                    385:
                    386:                while (1) {
                    387:                        pcmcia_chip_mem_unmap(pct, pch, window);
                    388:
                    389:                        if (longlink_present) {
                    390:                                /*
                    391:                                 * if the longlink is to attribute memory,
                    392:                                 * then it is unindexed.  That is, if the
                    393:                                 * link value is 0x100, then the actual
                    394:                                 * memory address is 0x200.  This means that
                    395:                                 * we need to multiply by 2 before calling
                    396:                                 * mem_map, and then divide the resulting ptr
                    397:                                 * by 2 after.
                    398:                                 */
                    399:
                    400:                                if (!longlink_common)
                    401:                                        longlink_addr *= 2;
                    402:
                    403:                                pcmcia_chip_mem_map(pct, pch, longlink_common ?
                    404:                                    PCMCIA_MEM_COMMON : PCMCIA_MEM_ATTR,
                    405:                                    longlink_addr, PCMCIA_CIS_SIZE,
                    406:                                    &pcmh, &tuple.ptr, &window);
                    407:
                    408:                                if (!longlink_common)
                    409:                                        tuple.ptr /= 2;
                    410:
                    411:                                DPRINTF(("cis mem map %x\n",
                    412:                                    (unsigned int) tuple.memh));
                    413:
                    414:                                tuple.mult = longlink_common ? 1 : 2;
                    415:                                longlink_present = 0;
                    416:                                longlink_common = 1;
                    417:                                longlink_addr = 0;
                    418:                        } else if (mfc_count && (mfc_index < mfc_count)) {
                    419:                                if (!mfc[mfc_index].common)
                    420:                                        mfc[mfc_index].addr *= 2;
                    421:
                    422:                                pcmcia_chip_mem_map(pct, pch,
                    423:                                    mfc[mfc_index].common ?
                    424:                                    PCMCIA_MEM_COMMON : PCMCIA_MEM_ATTR,
                    425:                                    mfc[mfc_index].addr, PCMCIA_CIS_SIZE,
                    426:                                    &pcmh, &tuple.ptr, &window);
                    427:
                    428:                                if (!mfc[mfc_index].common)
                    429:                                        tuple.ptr /= 2;
                    430:
                    431:                                DPRINTF(("cis mem map %x\n",
                    432:                                    (unsigned int) tuple.memh));
                    433:
                    434:                                /* set parse state, and point at the next one */
                    435:
                    436:                                tuple.mult = mfc[mfc_index].common ? 1 : 2;
                    437:
                    438:                                mfc_index++;
                    439:                        } else {
                    440:                                goto done;
                    441:                        }
                    442:
                    443:                        /* make sure that the link is valid */
                    444:                        tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr);
                    445:                        if (tuple.code != PCMCIA_CISTPL_LINKTARGET) {
                    446:                                DPRINTF(("CISTPL_LINKTARGET expected, "
                    447:                                    "code %02x observed\n", tuple.code));
                    448:                                continue;
                    449:                        }
                    450:                        tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1);
                    451:                        if (tuple.length < 3) {
                    452:                                DPRINTF(("CISTPL_LINKTARGET too short %d\n",
                    453:                                    tuple.length));
                    454:                                continue;
                    455:                        }
                    456:                        if ((pcmcia_tuple_read_1(&tuple, 0) != 'C') ||
                    457:                            (pcmcia_tuple_read_1(&tuple, 1) != 'I') ||
                    458:                            (pcmcia_tuple_read_1(&tuple, 2) != 'S')) {
                    459:                                DPRINTF(("CISTPL_LINKTARGET magic "
                    460:                                    "%02x%02x%02x incorrect\n",
                    461:                                    pcmcia_tuple_read_1(&tuple, 0),
                    462:                                    pcmcia_tuple_read_1(&tuple, 1),
                    463:                                    pcmcia_tuple_read_1(&tuple, 2)));
                    464:                                continue;
                    465:                        }
                    466:                        tuple.ptr += 2 + tuple.length;
                    467:
                    468:                        break;
                    469:                }
                    470:        }
                    471:
                    472:        pcmcia_chip_mem_unmap(pct, pch, window);
                    473:
                    474: done:
                    475:        /* Last, free the allocated memory block */
                    476:        pcmcia_chip_mem_free(pct, pch, &pcmh);
                    477:
                    478:        return (ret);
                    479: }
                    480:
                    481: /* XXX this is incredibly verbose.  Not sure what trt is */
                    482:
                    483: void
                    484: pcmcia_print_cis(sc)
                    485:        struct pcmcia_softc *sc;
                    486: {
                    487:        struct pcmcia_card *card = &sc->card;
                    488:        struct pcmcia_function *pf;
                    489:        struct pcmcia_config_entry *cfe;
                    490:        int i;
                    491:
                    492:        printf("%s: CIS version ", sc->dev.dv_xname);
                    493:        if (card->cis1_major == 4) {
                    494:                if (card->cis1_minor == 0)
                    495:                        printf("PCMCIA 1.0\n");
                    496:                else if (card->cis1_minor == 1)
                    497:                        printf("PCMCIA 2.0 or 2.1\n");
                    498:        } else if (card->cis1_major >= 5)
                    499:                printf("PC Card Standard %d.%d\n", card->cis1_major,
                    500:                    card->cis1_minor);
                    501:        else
                    502:                printf("unknown (major=%d, minor=%d)\n",
                    503:                    card->cis1_major, card->cis1_minor);
                    504:
                    505:        printf("%s: CIS info: ", sc->dev.dv_xname);
                    506:        for (i = 0; i < 4; i++) {
                    507:                if (card->cis1_info[i] == NULL)
                    508:                        break;
                    509:                if (i)
                    510:                        printf(", ");
                    511:                printf("%s", card->cis1_info[i]);
                    512:        }
                    513:        printf("\n");
                    514:
                    515:        printf("%s: Manufacturer code 0x%x, product 0x%x\n",
                    516:               sc->dev.dv_xname, card->manufacturer, card->product);
                    517:
                    518:        SIMPLEQ_FOREACH(pf, &card->pf_head, pf_list) {
                    519:                printf("%s: function %d: ", sc->dev.dv_xname, pf->number);
                    520:
                    521:                switch (pf->function) {
                    522:                case PCMCIA_FUNCTION_UNSPEC:
                    523:                        printf("unspecified");
                    524:                        break;
                    525:                case PCMCIA_FUNCTION_MULTIFUNCTION:
                    526:                        printf("multi-function");
                    527:                        break;
                    528:                case PCMCIA_FUNCTION_MEMORY:
                    529:                        printf("memory");
                    530:                        break;
                    531:                case PCMCIA_FUNCTION_SERIAL:
                    532:                        printf("serial port");
                    533:                        break;
                    534:                case PCMCIA_FUNCTION_PARALLEL:
                    535:                        printf("parallel port");
                    536:                        break;
                    537:                case PCMCIA_FUNCTION_DISK:
                    538:                        printf("fixed disk");
                    539:                        break;
                    540:                case PCMCIA_FUNCTION_VIDEO:
                    541:                        printf("video adapter");
                    542:                        break;
                    543:                case PCMCIA_FUNCTION_NETWORK:
                    544:                        printf("network adapter");
                    545:                        break;
                    546:                case PCMCIA_FUNCTION_AIMS:
                    547:                        printf("auto incrementing mass storage");
                    548:                        break;
                    549:                case PCMCIA_FUNCTION_SCSI:
                    550:                        printf("SCSI bridge");
                    551:                        break;
                    552:                case PCMCIA_FUNCTION_SECURITY:
                    553:                        printf("Security services");
                    554:                        break;
                    555:                case PCMCIA_FUNCTION_INSTRUMENT:
                    556:                        printf("Instrument");
                    557:                        break;
                    558:                case PCMCIA_FUNCTION_IOBUS:
                    559:                        printf("Serial I/O Bus Adapter");
                    560:                        break;
                    561:                default:
                    562:                        printf("unknown (%d)", pf->function);
                    563:                        break;
                    564:                }
                    565:
                    566:                printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask);
                    567:
                    568:                SIMPLEQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
                    569:                        printf("%s: function %d, config table entry %d: ",
                    570:                            sc->dev.dv_xname, pf->number, cfe->number);
                    571:
                    572:                        switch (cfe->iftype) {
                    573:                        case PCMCIA_IFTYPE_MEMORY:
                    574:                                printf("memory card");
                    575:                                break;
                    576:                        case PCMCIA_IFTYPE_IO:
                    577:                                printf("I/O card");
                    578:                                break;
                    579:                        default:
                    580:                                printf("card type unknown");
                    581:                                break;
                    582:                        }
                    583:
                    584:                        printf("; irq mask %x", cfe->irqmask);
                    585:
                    586:                        if (cfe->num_iospace) {
                    587:                                printf("; iomask %lx, iospace", cfe->iomask);
                    588:
                    589:                                for (i = 0; i < cfe->num_iospace; i++)
                    590:                                        printf(" %lx%s%lx",
                    591:                                            cfe->iospace[i].start,
                    592:                                            cfe->iospace[i].length ? "-" : "",
                    593:                                            cfe->iospace[i].start +
                    594:                                              cfe->iospace[i].length - 1);
                    595:                        }
                    596:                        if (cfe->num_memspace) {
                    597:                                printf("; memspace");
                    598:
                    599:                                for (i = 0; i < cfe->num_memspace; i++)
                    600:                                        printf(" %lx%s%lx%s%lx",
                    601:                                            cfe->memspace[i].cardaddr,
                    602:                                            cfe->memspace[i].length ? "-" : "",
                    603:                                            cfe->memspace[i].cardaddr +
                    604:                                              cfe->memspace[i].length - 1,
                    605:                                            cfe->memspace[i].hostaddr ?
                    606:                                              "@" : "",
                    607:                                            cfe->memspace[i].hostaddr);
                    608:                        }
                    609:                        if (cfe->maxtwins)
                    610:                                printf("; maxtwins %d", cfe->maxtwins);
                    611:
                    612:                        printf(";");
                    613:
                    614:                        if (cfe->flags & PCMCIA_CFE_MWAIT_REQUIRED)
                    615:                                printf(" mwait_required");
                    616:                        if (cfe->flags & PCMCIA_CFE_RDYBSY_ACTIVE)
                    617:                                printf(" rdybsy_active");
                    618:                        if (cfe->flags & PCMCIA_CFE_WP_ACTIVE)
                    619:                                printf(" wp_active");
                    620:                        if (cfe->flags & PCMCIA_CFE_BVD_ACTIVE)
                    621:                                printf(" bvd_active");
                    622:                        if (cfe->flags & PCMCIA_CFE_IO8)
                    623:                                printf(" io8");
                    624:                        if (cfe->flags & PCMCIA_CFE_IO16)
                    625:                                printf(" io16");
                    626:                        if (cfe->flags & PCMCIA_CFE_IRQSHARE)
                    627:                                printf(" irqshare");
                    628:                        if (cfe->flags & PCMCIA_CFE_IRQPULSE)
                    629:                                printf(" irqpulse");
                    630:                        if (cfe->flags & PCMCIA_CFE_IRQLEVEL)
                    631:                                printf(" irqlevel");
                    632:                        if (cfe->flags & PCMCIA_CFE_POWERDOWN)
                    633:                                printf(" powerdown");
                    634:                        if (cfe->flags & PCMCIA_CFE_READONLY)
                    635:                                printf(" readonly");
                    636:                        if (cfe->flags & PCMCIA_CFE_AUDIO)
                    637:                                printf(" audio");
                    638:
                    639:                        printf("\n");
                    640:                }
                    641:        }
                    642:
                    643:        if (card->error)
                    644:                printf("%s: %d errors found while parsing CIS\n",
                    645:                    sc->dev.dv_xname, card->error);
                    646: }
                    647:
                    648: int
                    649: pcmcia_parse_cis_tuple(tuple, arg)
                    650:        struct pcmcia_tuple *tuple;
                    651:        void *arg;
                    652: {
                    653:        /* most of these are educated guesses */
                    654:        static struct pcmcia_config_entry init_cfe = {
                    655:                -1, PCMCIA_CFE_RDYBSY_ACTIVE | PCMCIA_CFE_WP_ACTIVE |
                    656:                PCMCIA_CFE_BVD_ACTIVE, PCMCIA_IFTYPE_MEMORY,
                    657:        };
                    658:
                    659:        struct cis_state *state = arg;
                    660:
                    661:        switch (tuple->code) {
                    662:        case PCMCIA_CISTPL_END:
                    663:                /*
                    664:                 * If we've seen a LONGLINK_MFC, and this is the first
                    665:                 * END after it, reset the function list.
                    666:                 *
                    667:                 * XXX This might also be the right place to start a
                    668:                 * new function, but that assumes that a function
                    669:                 * definition never crosses any longlink, and I'm not
                    670:                 * sure about that.  This is probably safe for MFC
                    671:                 * cards, but what we have now isn't broken, so I'd
                    672:                 * rather not change it.
                    673:                 */
                    674:                if (state->gotmfc == 1) {
                    675:                        struct pcmcia_function *pf, *pfnext;
                    676:
                    677:                        for (pf = SIMPLEQ_FIRST(&state->card->pf_head);
                    678:                            pf != NULL; pf = pfnext) {
                    679:                                pfnext = SIMPLEQ_NEXT(pf, pf_list);
                    680:                                free(pf, M_DEVBUF);
                    681:                        }
                    682:
                    683:                        SIMPLEQ_INIT(&state->card->pf_head);
                    684:
                    685:                        state->count = 0;
                    686:                        state->gotmfc = 2;
                    687:                        state->pf = NULL;
                    688:                }
                    689:                break;
                    690:
                    691:        case PCMCIA_CISTPL_LONGLINK_MFC:
                    692:                /*
                    693:                 * This tuple's structure was dealt with in scan_cis.  here,
                    694:                 * record the fact that the MFC tuple was seen, so that
                    695:                 * functions declared before the MFC link can be cleaned
                    696:                 * up.
                    697:                 */
                    698:                state->gotmfc = 1;
                    699:                break;
                    700:
                    701: #ifdef PCMCIACISDEBUG
                    702:        case PCMCIA_CISTPL_DEVICE:
                    703:        case PCMCIA_CISTPL_DEVICE_A:
                    704:                {
                    705:                        u_int reg, dtype, dspeed;
                    706:
                    707:                        reg = pcmcia_tuple_read_1(tuple, 0);
                    708:                        dtype = reg & PCMCIA_DTYPE_MASK;
                    709:                        dspeed = reg & PCMCIA_DSPEED_MASK;
                    710:
                    711:                        DPRINTF(("CISTPL_DEVICE%s type=",
                    712:                        (tuple->code == PCMCIA_CISTPL_DEVICE) ? "" : "_A"));
                    713:                        switch (dtype) {
                    714:                        case PCMCIA_DTYPE_NULL:
                    715:                                DPRINTF(("null"));
                    716:                                break;
                    717:                        case PCMCIA_DTYPE_ROM:
                    718:                                DPRINTF(("rom"));
                    719:                                break;
                    720:                        case PCMCIA_DTYPE_OTPROM:
                    721:                                DPRINTF(("otprom"));
                    722:                                break;
                    723:                        case PCMCIA_DTYPE_EPROM:
                    724:                                DPRINTF(("eprom"));
                    725:                                break;
                    726:                        case PCMCIA_DTYPE_EEPROM:
                    727:                                DPRINTF(("eeprom"));
                    728:                                break;
                    729:                        case PCMCIA_DTYPE_FLASH:
                    730:                                DPRINTF(("flash"));
                    731:                                break;
                    732:                        case PCMCIA_DTYPE_SRAM:
                    733:                                DPRINTF(("sram"));
                    734:                                break;
                    735:                        case PCMCIA_DTYPE_DRAM:
                    736:                                DPRINTF(("dram"));
                    737:                                break;
                    738:                        case PCMCIA_DTYPE_FUNCSPEC:
                    739:                                DPRINTF(("funcspec"));
                    740:                                break;
                    741:                        case PCMCIA_DTYPE_EXTEND:
                    742:                                DPRINTF(("extend"));
                    743:                                break;
                    744:                        default:
                    745:                                DPRINTF(("reserved"));
                    746:                                break;
                    747:                        }
                    748:                        DPRINTF((" speed="));
                    749:                        switch (dspeed) {
                    750:                        case PCMCIA_DSPEED_NULL:
                    751:                                DPRINTF(("null"));
                    752:                                break;
                    753:                        case PCMCIA_DSPEED_250NS:
                    754:                                DPRINTF(("250ns"));
                    755:                                break;
                    756:                        case PCMCIA_DSPEED_200NS:
                    757:                                DPRINTF(("200ns"));
                    758:                                break;
                    759:                        case PCMCIA_DSPEED_150NS:
                    760:                                DPRINTF(("150ns"));
                    761:                                break;
                    762:                        case PCMCIA_DSPEED_100NS:
                    763:                                DPRINTF(("100ns"));
                    764:                                break;
                    765:                        case PCMCIA_DSPEED_EXT:
                    766:                                DPRINTF(("ext"));
                    767:                                break;
                    768:                        default:
                    769:                                DPRINTF(("reserved"));
                    770:                                break;
                    771:                        }
                    772:                }
                    773:                DPRINTF(("\n"));
                    774:                break;
                    775: #endif
                    776:
                    777:        case PCMCIA_CISTPL_VERS_1:
                    778:                if (tuple->length < 6) {
                    779:                        DPRINTF(("CISTPL_VERS_1 too short %d\n",
                    780:                            tuple->length));
                    781:                        break;
                    782:                } {
                    783:                        int start, i, ch, count;
                    784:
                    785:                        state->card->cis1_major = pcmcia_tuple_read_1(tuple, 0);
                    786:                        state->card->cis1_minor = pcmcia_tuple_read_1(tuple, 1);
                    787:
                    788:                        for (count = 0, start = 0, i = 0;
                    789:                            (count < 4) && ((i + 4) < 256); i++) {
                    790:                                ch = pcmcia_tuple_read_1(tuple, 2 + i);
                    791:                                if (ch == 0xff)
                    792:                                        break;
                    793:                                state->card->cis1_info_buf[i] = ch;
                    794:                                if (ch == 0) {
                    795:                                        state->card->cis1_info[count] =
                    796:                                            state->card->cis1_info_buf + start;
                    797:                                        start = i + 1;
                    798:                                        count++;
                    799:                                }
                    800:                        }
                    801:                        DPRINTF(("CISTPL_VERS_1\n"));
                    802:                }
                    803:                break;
                    804:
                    805:        case PCMCIA_CISTPL_MANFID:
                    806:                if (tuple->length < 4) {
                    807:                        DPRINTF(("CISTPL_MANFID too short %d\n",
                    808:                            tuple->length));
                    809:                        break;
                    810:                }
                    811:                state->card->manufacturer = pcmcia_tuple_read_2(tuple, 0);
                    812:                state->card->product = pcmcia_tuple_read_2(tuple, 2);
                    813:                DPRINTF(("CISTPL_MANFID\n"));
                    814:                break;
                    815:
                    816:        case PCMCIA_CISTPL_FUNCID:
                    817:                if (tuple->length < 2) {
                    818:                        DPRINTF(("CISTPL_FUNCID too short %d\n",
                    819:                            tuple->length));
                    820:                        break;
                    821:                }
                    822:
                    823:                /*
                    824:                 * As far as I understand this, manufacturers do multifunction
                    825:                 * cards in various ways.  Sadly enough I do not have the
                    826:                 * PC-Card standard (donate!) so I can only guess what can
                    827:                 * be done.
                    828:                 * The original code implies FUNCID nodes are above CONFIG
                    829:                 * nodes in the CIS tree, however Xircom does it the other
                    830:                 * way round, which of course makes things a bit hard.
                    831:                 * --niklas@openbsd.org
                    832:                 */
                    833:                if (state->pf) {
                    834:                        if (state->pf->function == PCMCIA_FUNCTION_UNSPEC) {
                    835:                                /*
                    836:                                 * This looks like a opportunistic function
                    837:                                 * created by a CONFIG tuple.  Just keep it.
                    838:                                 */
                    839:                        } else {
                    840:                                /*
                    841:                                 * A function is being defined, end it.
                    842:                                 */
                    843:                                state->pf = NULL;
                    844:                        }
                    845:                }
                    846:                if (state->pf == NULL) {
                    847:                        state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
                    848:                            M_NOWAIT);
                    849:                        if (state->pf == NULL)
                    850:                                panic("pcmcia_parse_cis_tuple");
                    851:                        bzero(state->pf, sizeof(*state->pf));
                    852:                        state->pf->number = state->count++;
                    853:                        state->pf->last_config_index = -1;
                    854:                        SIMPLEQ_INIT(&state->pf->cfe_head);
                    855:
                    856:                        SIMPLEQ_INSERT_TAIL(&state->card->pf_head, state->pf,
                    857:                            pf_list);
                    858:                }
                    859:                state->pf->function = pcmcia_tuple_read_1(tuple, 0);
                    860:
                    861:                DPRINTF(("CISTPL_FUNCID\n"));
                    862:                break;
                    863:
                    864:        case PCMCIA_CISTPL_CONFIG:
                    865:                if (tuple->length < 3) {
                    866:                        DPRINTF(("CISTPL_CONFIG too short %d\n",
                    867:                            tuple->length));
                    868:                        break;
                    869:                } {
                    870:                        u_int reg, rasz, rmsz, rfsz;
                    871:                        int i;
                    872:
                    873:                        reg = pcmcia_tuple_read_1(tuple, 0);
                    874:                        rasz = 1 + ((reg & PCMCIA_TPCC_RASZ_MASK) >>
                    875:                            PCMCIA_TPCC_RASZ_SHIFT);
                    876:                        rmsz = 1 + ((reg & PCMCIA_TPCC_RMSZ_MASK) >>
                    877:                            PCMCIA_TPCC_RMSZ_SHIFT);
                    878:                        rfsz = ((reg & PCMCIA_TPCC_RFSZ_MASK) >>
                    879:                            PCMCIA_TPCC_RFSZ_SHIFT);
                    880:
                    881:                        if (tuple->length < (rasz + rmsz + rfsz)) {
                    882:                                DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
                    883:                                    "short %d\n", rasz, rmsz, rfsz,
                    884:                                    tuple->length));
                    885:                                break;
                    886:                        }
                    887:                        if (state->pf == NULL) {
                    888:                                state->pf = malloc(sizeof(*state->pf),
                    889:                                    M_DEVBUF, M_NOWAIT);
                    890:                                if (state->pf == NULL)
                    891:                                        panic("pcmcia_parse_cis_tuple");
                    892:                                bzero(state->pf, sizeof(*state->pf));
                    893:                                state->pf->number = state->count++;
                    894:                                state->pf->last_config_index = -1;
                    895:                                SIMPLEQ_INIT(&state->pf->cfe_head);
                    896:
                    897:                                SIMPLEQ_INSERT_TAIL(&state->card->pf_head,
                    898:                                    state->pf, pf_list);
                    899:
                    900:                                state->pf->function = PCMCIA_FUNCTION_UNSPEC;
                    901:                        }
                    902:                        state->pf->last_config_index =
                    903:                            pcmcia_tuple_read_1(tuple, 1);
                    904:
                    905:                        state->pf->ccr_base = 0;
                    906:                        for (i = 0; i < rasz; i++)
                    907:                                state->pf->ccr_base |=
                    908:                                    ((pcmcia_tuple_read_1(tuple, 2 + i)) <<
                    909:                                    (i * 8));
                    910:
                    911:                        state->pf->ccr_mask = 0;
                    912:                        for (i = 0; i < rmsz; i++)
                    913:                                state->pf->ccr_mask |=
                    914:                                    ((pcmcia_tuple_read_1(tuple,
                    915:                                    2 + rasz + i)) << (i * 8));
                    916:
                    917:                        /* skip the reserved area and subtuples */
                    918:
                    919:                        /* reset the default cfe for each cfe list */
                    920:                        state->temp_cfe = init_cfe;
                    921:                        state->default_cfe = &state->temp_cfe;
                    922:                }
                    923:                DPRINTF(("CISTPL_CONFIG\n"));
                    924:                break;
                    925:
                    926:        case PCMCIA_CISTPL_CFTABLE_ENTRY:
                    927:                if (tuple->length < 2) {
                    928:                        DPRINTF(("CISTPL_CFTABLE_ENTRY too short %d\n",
                    929:                            tuple->length));
                    930:                        break;
                    931:                } {
                    932:                        int idx, i, j;
                    933:                        u_int reg, reg2;
                    934:                        u_int intface, def, num;
                    935:                        u_int power, timing, iospace, irq, memspace, misc;
                    936:                        struct pcmcia_config_entry *cfe;
                    937:
                    938:                        idx = 0;
                    939:
                    940:                        reg = pcmcia_tuple_read_1(tuple, idx);
                    941:                        idx++;
                    942:                        intface = reg & PCMCIA_TPCE_INDX_INTFACE;
                    943:                        def = reg & PCMCIA_TPCE_INDX_DEFAULT;
                    944:                        num = reg & PCMCIA_TPCE_INDX_NUM_MASK;
                    945:
                    946:                        /*
                    947:                         * this is a little messy.  Some cards have only a
                    948:                         * cfentry with the default bit set.  So, as we go
                    949:                         * through the list, we add new indexes to the queue,
                    950:                         * and keep a pointer to the last one with the
                    951:                         * default bit set.  if we see a record with the same
                    952:                         * index, as the default, we stash the default and
                    953:                         * replace the queue entry. otherwise, we just add
                    954:                         * new entries to the queue, pointing the default ptr
                    955:                         * at them if the default bit is set.  if we get to
                    956:                         * the end with the default pointer pointing at a
                    957:                         * record which hasn't had a matching index, that's
                    958:                         * ok; it just becomes a cfentry like any other.
                    959:                         */
                    960:
                    961:                        /*
                    962:                         * if the index in the cis differs from the default
                    963:                         * cis, create new entry in the queue and start it
                    964:                         * with the current default
                    965:                         */
                    966:                        if (state->default_cfe == NULL) {
                    967:                                DPRINTF(("CISTPL_CFTABLE_ENTRY with no "
                    968:                                    "default\n"));
                    969:                                break;
                    970:                        }
                    971:                        if (num != state->default_cfe->number) {
                    972:                                cfe = (struct pcmcia_config_entry *)
                    973:                                    malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
                    974:                                if (cfe == NULL)
                    975:                                        panic("pcmcia_parse_cis_tuple");
                    976:
                    977:                                *cfe = *state->default_cfe;
                    978:
                    979:                                SIMPLEQ_INSERT_TAIL(&state->pf->cfe_head,
                    980:                                    cfe, cfe_list);
                    981:
                    982:                                cfe->number = num;
                    983:
                    984:                                /*
                    985:                                 * if the default bit is set in the cis, then
                    986:                                 * point the new default at whatever is being
                    987:                                 * filled in
                    988:                                 */
                    989:                                if (def)
                    990:                                        state->default_cfe = cfe;
                    991:                        } else {
                    992:                                /*
                    993:                                 * the cis index matches the default index,
                    994:                                 * fill in the default cfentry.  It is
                    995:                                 * assumed that the cfdefault index is in the
                    996:                                 * queue.  For it to be otherwise, the cis
                    997:                                 * index would have to be -1 (initial
                    998:                                 * condition) which is not possible, or there
                    999:                                 * would have to be a preceding cis entry
                   1000:                                 * which had the same cis index and had the
                   1001:                                 * default bit unset. Neither condition
                   1002:                                 * should happen.  If it does, this cfentry
                   1003:                                 * is lost (written into temp space), which
                   1004:                                 * is an acceptable failure mode.
                   1005:                                 */
                   1006:
                   1007:                                cfe = state->default_cfe;
                   1008:
                   1009:                                /*
                   1010:                                 * if the cis entry does not have the default
                   1011:                                 * bit set, copy the default out of the way
                   1012:                                 * first.
                   1013:                                 */
                   1014:                                if (!def) {
                   1015:                                        state->temp_cfe = *state->default_cfe;
                   1016:                                        state->default_cfe = &state->temp_cfe;
                   1017:                                }
                   1018:                        }
                   1019:
                   1020:                        if (intface) {
                   1021:                                reg = pcmcia_tuple_read_1(tuple, idx);
                   1022:                                idx++;
                   1023:                                cfe->flags &= ~(PCMCIA_CFE_MWAIT_REQUIRED
                   1024:                                    | PCMCIA_CFE_RDYBSY_ACTIVE
                   1025:                                    | PCMCIA_CFE_WP_ACTIVE
                   1026:                                    | PCMCIA_CFE_BVD_ACTIVE);
                   1027:                                if (reg & PCMCIA_TPCE_IF_MWAIT)
                   1028:                                        cfe->flags |= PCMCIA_CFE_MWAIT_REQUIRED;
                   1029:                                if (reg & PCMCIA_TPCE_IF_RDYBSY)
                   1030:                                        cfe->flags |= PCMCIA_CFE_RDYBSY_ACTIVE;
                   1031:                                if (reg & PCMCIA_TPCE_IF_WP)
                   1032:                                        cfe->flags |= PCMCIA_CFE_WP_ACTIVE;
                   1033:                                if (reg & PCMCIA_TPCE_IF_BVD)
                   1034:                                        cfe->flags |= PCMCIA_CFE_BVD_ACTIVE;
                   1035:                                cfe->iftype = reg & PCMCIA_TPCE_IF_IFTYPE;
                   1036:                        }
                   1037:                        reg = pcmcia_tuple_read_1(tuple, idx);
                   1038:                        idx++;
                   1039:
                   1040:                        power = reg & PCMCIA_TPCE_FS_POWER_MASK;
                   1041:                        timing = reg & PCMCIA_TPCE_FS_TIMING;
                   1042:                        iospace = reg & PCMCIA_TPCE_FS_IOSPACE;
                   1043:                        irq = reg & PCMCIA_TPCE_FS_IRQ;
                   1044:                        memspace = reg & PCMCIA_TPCE_FS_MEMSPACE_MASK;
                   1045:                        misc = reg & PCMCIA_TPCE_FS_MISC;
                   1046:
                   1047:                        if (power) {
                   1048:                                /* skip over power, don't save */
                   1049:                                /* for each parameter selection byte */
                   1050:                                for (i = 0; i < power; i++) {
                   1051:                                        reg = pcmcia_tuple_read_1(tuple, idx);
                   1052:                                        idx++;
                   1053:                                        /* for each bit */
                   1054:                                        for (j = 0; j < 7; j++) {
                   1055:                                                /* if the bit is set */
                   1056:                                                if ((reg >> j) & 0x01) {
                   1057:                                                        /* skip over bytes */
                   1058:                                                        do {
                   1059:                                                                reg2 = pcmcia_tuple_read_1(tuple, idx);
                   1060:                                                                idx++;
                   1061:                                                                /*
                   1062:                                                                 * until
                   1063:                                                                 * non-
                   1064:                                                                 * extension
                   1065:                                                                 * byte
                   1066:                                                                 */
                   1067:                                                        } while (reg2 & 0x80);
                   1068:                                                }
                   1069:                                        }
                   1070:                                }
                   1071:                        }
                   1072:                        if (timing) {
                   1073:                                /* skip over timing, don't save */
                   1074:                                reg = pcmcia_tuple_read_1(tuple, idx);
                   1075:                                idx++;
                   1076:
                   1077:                                if ((reg & PCMCIA_TPCE_TD_RESERVED_MASK) !=
                   1078:                                    PCMCIA_TPCE_TD_RESERVED_MASK)
                   1079:                                        idx++;
                   1080:                                if ((reg & PCMCIA_TPCE_TD_RDYBSY_MASK) !=
                   1081:                                    PCMCIA_TPCE_TD_RDYBSY_MASK)
                   1082:                                        idx++;
                   1083:                                if ((reg & PCMCIA_TPCE_TD_WAIT_MASK) !=
                   1084:                                    PCMCIA_TPCE_TD_WAIT_MASK)
                   1085:                                        idx++;
                   1086:                        }
                   1087:                        if (iospace) {
                   1088:                                if (tuple->length <= idx) {
                   1089:                                        DPRINTF(("ran out of space before TPCE_IO\n"));
                   1090:
                   1091:                                        goto abort_cfe;
                   1092:                                }
                   1093:
                   1094:                                reg = pcmcia_tuple_read_1(tuple, idx);
                   1095:                                idx++;
                   1096:
                   1097:                                cfe->flags &=
                   1098:                                    ~(PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16);
                   1099:                                if (reg & PCMCIA_TPCE_IO_BUSWIDTH_8BIT)
                   1100:                                        cfe->flags |= PCMCIA_CFE_IO8;
                   1101:                                if (reg & PCMCIA_TPCE_IO_BUSWIDTH_16BIT)
                   1102:                                        cfe->flags |= PCMCIA_CFE_IO16;
                   1103:                                cfe->iomask =
                   1104:                                    reg & PCMCIA_TPCE_IO_IOADDRLINES_MASK;
                   1105:
                   1106:                                if (reg & PCMCIA_TPCE_IO_HASRANGE) {
                   1107:                                        reg = pcmcia_tuple_read_1(tuple, idx);
                   1108:                                        idx++;
                   1109:
                   1110:                                        cfe->num_iospace = 1 + (reg &
                   1111:                                            PCMCIA_TPCE_IO_RANGE_COUNT);
                   1112:
                   1113:                                        if (cfe->num_iospace >
                   1114:                                            (sizeof(cfe->iospace) /
                   1115:                                             sizeof(cfe->iospace[0]))) {
                   1116:                                                DPRINTF(("too many io "
                   1117:                                                    "spaces %d",
                   1118:                                                    cfe->num_iospace));
                   1119:                                                state->card->error++;
                   1120:                                                break;
                   1121:                                        }
                   1122:                                        for (i = 0; i < cfe->num_iospace; i++) {
                   1123:                                                switch (reg & PCMCIA_TPCE_IO_RANGE_ADDRSIZE_MASK) {
                   1124:                                                case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_ONE:
                   1125:                                                        cfe->iospace[i].start =
                   1126:                                                                pcmcia_tuple_read_1(tuple, idx);
                   1127:                                                        idx++;
                   1128:                                                        break;
                   1129:                                                case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_TWO:
                   1130:                                                        cfe->iospace[i].start =
                   1131:                                                                pcmcia_tuple_read_2(tuple, idx);
                   1132:                                                        idx += 2;
                   1133:                                                        break;
                   1134:                                                case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_FOUR:
                   1135:                                                        cfe->iospace[i].start =
                   1136:                                                                pcmcia_tuple_read_4(tuple, idx);
                   1137:                                                        idx += 4;
                   1138:                                                        break;
                   1139:                                                }
                   1140:                                                switch (reg &
                   1141:                                                        PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
                   1142:                                                case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_ONE:
                   1143:                                                        cfe->iospace[i].length =
                   1144:                                                                pcmcia_tuple_read_1(tuple, idx);
                   1145:                                                        idx++;
                   1146:                                                        break;
                   1147:                                                case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_TWO:
                   1148:                                                        cfe->iospace[i].length =
                   1149:                                                                pcmcia_tuple_read_2(tuple, idx);
                   1150:                                                        idx += 2;
                   1151:                                                        break;
                   1152:                                                case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
                   1153:                                                        cfe->iospace[i].length =
                   1154:                                                                pcmcia_tuple_read_4(tuple, idx);
                   1155:                                                        idx += 4;
                   1156:                                                        break;
                   1157:                                                }
                   1158:                                                cfe->iospace[i].length++;
                   1159:                                        }
                   1160:                                } else {
                   1161:                                        cfe->num_iospace = 1;
                   1162:                                        cfe->iospace[0].start = 0;
                   1163:                                        cfe->iospace[0].length =
                   1164:                                            (1 << cfe->iomask);
                   1165:                                }
                   1166:                        }
                   1167:
                   1168:                        if (irq) {
                   1169:                                if (tuple->length <= idx) {
                   1170:                                        DPRINTF(("ran out of space before TPCE_IR\n"));
                   1171:
                   1172:                                        goto abort_cfe;
                   1173:                                }
                   1174:
                   1175:                                reg = pcmcia_tuple_read_1(tuple, idx);
                   1176:                                idx++;
                   1177:
                   1178:                                cfe->flags &= ~(PCMCIA_CFE_IRQSHARE
                   1179:                                    | PCMCIA_CFE_IRQPULSE
                   1180:                                    | PCMCIA_CFE_IRQLEVEL);
                   1181:                                if (reg & PCMCIA_TPCE_IR_SHARE)
                   1182:                                        cfe->flags |= PCMCIA_CFE_IRQSHARE;
                   1183:                                if (reg & PCMCIA_TPCE_IR_PULSE)
                   1184:                                        cfe->flags |= PCMCIA_CFE_IRQPULSE;
                   1185:                                if (reg & PCMCIA_TPCE_IR_LEVEL)
                   1186:                                        cfe->flags |= PCMCIA_CFE_IRQLEVEL;
                   1187:
                   1188:                                if (reg & PCMCIA_TPCE_IR_HASMASK) {
                   1189:                                        /*
                   1190:                                         * it's legal to ignore the
                   1191:                                         * special-interrupt bits, so I will
                   1192:                                         */
                   1193:
                   1194:                                        cfe->irqmask =
                   1195:                                            pcmcia_tuple_read_2(tuple, idx);
                   1196:                                        idx += 2;
                   1197:                                } else {
                   1198:                                        cfe->irqmask =
                   1199:                                            (1 << (reg & PCMCIA_TPCE_IR_IRQ));
                   1200:                                }
                   1201:                        }
                   1202:                        if (memspace) {
                   1203:                                if (tuple->length <= idx) {
                   1204:                                        DPRINTF(("ran out of space before TPCE_MS\n"));
                   1205:                                        goto abort_cfe;
                   1206:                                }
                   1207:
                   1208:                                if (memspace == PCMCIA_TPCE_FS_MEMSPACE_NONE) {
                   1209:                                        cfe->num_memspace = 0;
                   1210:                                } else if (memspace == PCMCIA_TPCE_FS_MEMSPACE_LENGTH) {
                   1211:                                        cfe->num_memspace = 1;
                   1212:                                        cfe->memspace[0].length = 256 *
                   1213:                                            pcmcia_tuple_read_2(tuple, idx);
                   1214:                                        idx += 2;
                   1215:                                        cfe->memspace[0].cardaddr = 0;
                   1216:                                        cfe->memspace[0].hostaddr = 0;
                   1217:                                } else if (memspace ==
                   1218:                                    PCMCIA_TPCE_FS_MEMSPACE_LENGTHADDR) {
                   1219:                                        cfe->num_memspace = 1;
                   1220:                                        cfe->memspace[0].length = 256 *
                   1221:                                            pcmcia_tuple_read_2(tuple, idx);
                   1222:                                        idx += 2;
                   1223:                                        cfe->memspace[0].cardaddr = 256 *
                   1224:                                            pcmcia_tuple_read_2(tuple, idx);
                   1225:                                        idx += 2;
                   1226:                                        cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
                   1227:                                } else {
                   1228:                                        int lengthsize;
                   1229:                                        int cardaddrsize;
                   1230:                                        int hostaddrsize;
                   1231:
                   1232:                                        reg = pcmcia_tuple_read_1(tuple, idx);
                   1233:                                        idx++;
                   1234:
                   1235:                                        cfe->num_memspace = (reg &
                   1236:                                            PCMCIA_TPCE_MS_COUNT) + 1;
                   1237:
                   1238:                                        if (cfe->num_memspace >
                   1239:                                            (sizeof(cfe->memspace) /
                   1240:                                             sizeof(cfe->memspace[0]))) {
                   1241:                                                DPRINTF(("too many mem "
                   1242:                                                    "spaces %d",
                   1243:                                                    cfe->num_memspace));
                   1244:                                                state->card->error++;
                   1245:                                                break;
                   1246:                                        }
                   1247:                                        lengthsize =
                   1248:                                                ((reg & PCMCIA_TPCE_MS_LENGTH_SIZE_MASK) >>
                   1249:                                                 PCMCIA_TPCE_MS_LENGTH_SIZE_SHIFT);
                   1250:                                        cardaddrsize =
                   1251:                                                ((reg & PCMCIA_TPCE_MS_CARDADDR_SIZE_MASK) >>
                   1252:                                                 PCMCIA_TPCE_MS_CARDADDR_SIZE_SHIFT);
                   1253:                                        hostaddrsize =
                   1254:                                                (reg & PCMCIA_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
                   1255:
                   1256:                                        if (lengthsize == 0) {
                   1257:                                                DPRINTF(("cfe memspace "
                   1258:                                                    "lengthsize == 0"));
                   1259:                                                state->card->error++;
                   1260:                                        }
                   1261:                                        for (i = 0; i < cfe->num_memspace; i++) {
                   1262:                                                if (lengthsize) {
                   1263:                                                        cfe->memspace[i].length =
                   1264:                                                                256 * pcmcia_tuple_read_n(tuple, lengthsize,
                   1265:                                                                       idx);
                   1266:                                                        idx += lengthsize;
                   1267:                                                } else {
                   1268:                                                        cfe->memspace[i].length = 0;
                   1269:                                                }
                   1270:                                                if (cfe->memspace[i].length == 0) {
                   1271:                                                        DPRINTF(("cfe->memspace[%d].length == 0",
                   1272:                                                                 i));
                   1273:                                                        state->card->error++;
                   1274:                                                }
                   1275:                                                if (cardaddrsize) {
                   1276:                                                        cfe->memspace[i].cardaddr =
                   1277:                                                                256 * pcmcia_tuple_read_n(tuple, cardaddrsize,
                   1278:                                                                       idx);
                   1279:                                                        idx += cardaddrsize;
                   1280:                                                } else {
                   1281:                                                        cfe->memspace[i].cardaddr = 0;
                   1282:                                                }
                   1283:                                                if (hostaddrsize) {
                   1284:                                                        cfe->memspace[i].hostaddr =
                   1285:                                                                256 * pcmcia_tuple_read_n(tuple, hostaddrsize,
                   1286:                                                                       idx);
                   1287:                                                        idx += hostaddrsize;
                   1288:                                                } else {
                   1289:                                                        cfe->memspace[i].hostaddr = 0;
                   1290:                                                }
                   1291:                                        }
                   1292:                                }
                   1293:                        }
                   1294:                        if (misc) {
                   1295:                                if (tuple->length <= idx) {
                   1296:                                        DPRINTF(("ran out of space before TPCE_MI\n"));
                   1297:
                   1298:                                        goto abort_cfe;
                   1299:                                }
                   1300:
                   1301:                                reg = pcmcia_tuple_read_1(tuple, idx);
                   1302:                                idx++;
                   1303:
                   1304:                                cfe->flags &= ~(PCMCIA_CFE_POWERDOWN
                   1305:                                    | PCMCIA_CFE_READONLY
                   1306:                                    | PCMCIA_CFE_AUDIO);
                   1307:                                if (reg & PCMCIA_TPCE_MI_PWRDOWN)
                   1308:                                        cfe->flags |= PCMCIA_CFE_POWERDOWN;
                   1309:                                if (reg & PCMCIA_TPCE_MI_READONLY)
                   1310:                                        cfe->flags |= PCMCIA_CFE_READONLY;
                   1311:                                if (reg & PCMCIA_TPCE_MI_AUDIO)
                   1312:                                        cfe->flags |= PCMCIA_CFE_AUDIO;
                   1313:                                cfe->maxtwins = reg & PCMCIA_TPCE_MI_MAXTWINS;
                   1314:
                   1315:                                while (reg & PCMCIA_TPCE_MI_EXT) {
                   1316:                                        reg = pcmcia_tuple_read_1(tuple, idx);
                   1317:                                        idx++;
                   1318:                                }
                   1319:                        }
                   1320:                        /* skip all the subtuples */
                   1321:                }
                   1322:
                   1323:        abort_cfe:
                   1324:                DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
                   1325:                break;
                   1326:
                   1327:        default:
                   1328:                DPRINTF(("unhandled CISTPL %x\n", tuple->code));
                   1329:                break;
                   1330:        }
                   1331:
                   1332:        return (0);
                   1333: }

CVSweb