root/dev/pcmcia/pcmcia_cis.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcmcia_read_cis
  2. pcmcia_scan_cis
  3. pcmcia_print_cis
  4. pcmcia_parse_cis_tuple

    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 }

/* [<][>][^][v][top][bottom][index][help] */