The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/cardbus/cardbus_cis.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000,2001 Jonathan Chen.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions, and the following disclaimer,
   10  *    without modification, immediately at the beginning of the file.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in
   13  *    the documentation and/or other materials provided with the
   14  *    distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  * $FreeBSD: releng/5.0/sys/dev/cardbus/cardbus_cis.c 107301 2002-11-27 06:56:29Z imp $
   29  */
   30 
   31 /*
   32  * CIS Handling for the Cardbus Bus
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 #include <sys/malloc.h>
   39 
   40 #include <sys/bus.h>
   41 #include <machine/bus.h>
   42 #include <machine/resource.h>
   43 #include <sys/rman.h>
   44 
   45 #include <sys/pciio.h>
   46 #include <dev/pci/pcivar.h>
   47 #include <dev/pci/pcireg.h>
   48 
   49 #include <dev/cardbus/cardbusreg.h>
   50 #include <dev/cardbus/cardbusvar.h>
   51 #include <dev/cardbus/cardbus_cis.h>
   52 
   53 #include <dev/pccard/pccardvar.h>
   54 
   55 extern int cardbus_cis_debug;
   56 
   57 #define DPRINTF(a) if (cardbus_cis_debug) printf a
   58 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
   59 
   60 #define DECODE_PARAMS                                                   \
   61                 (device_t cbdev, device_t child, int id, int len,       \
   62                  u_int8_t *tupledata, u_int32_t start, u_int32_t *off,  \
   63                  struct tuple_callbacks *info)
   64 
   65 struct tuple_callbacks {
   66         int     id;
   67         char    *name;
   68         int     (*func) DECODE_PARAMS;
   69 };
   70 
   71 #define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS
   72 DECODE_PROTOTYPE(generic);
   73 DECODE_PROTOTYPE(nothing);
   74 DECODE_PROTOTYPE(copy);
   75 DECODE_PROTOTYPE(linktarget);
   76 DECODE_PROTOTYPE(vers_1);
   77 DECODE_PROTOTYPE(funcid);
   78 DECODE_PROTOTYPE(manfid);
   79 DECODE_PROTOTYPE(funce);
   80 DECODE_PROTOTYPE(bar);
   81 DECODE_PROTOTYPE(unhandled);
   82 DECODE_PROTOTYPE(end);
   83 static int      cardbus_read_tuple_conf(device_t cbdev, device_t child,
   84                     u_int32_t start, u_int32_t *off, int *tupleid, int *len,
   85                     u_int8_t *tupledata);
   86 static int      cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
   87                     u_int32_t start, u_int32_t *off, int *tupleid, int *len,
   88                     u_int8_t *tupledata);
   89 static int      cardbus_read_tuple(device_t cbdev, device_t child,
   90                     struct resource *res, u_int32_t start, u_int32_t *off,
   91                     int *tupleid, int *len, u_int8_t *tupledata);
   92 static void     cardbus_read_tuple_finish(device_t cbdev, device_t child,
   93                     int rid, struct resource *res);
   94 static struct resource  *cardbus_read_tuple_init(device_t cbdev, device_t child,
   95                     u_int32_t *start, int *rid);
   96 static int      decode_tuple(device_t cbdev, device_t child, int tupleid,
   97                     int len, u_int8_t *tupledata, u_int32_t start,
   98                     u_int32_t *off, struct tuple_callbacks *callbacks);
   99 static int      cardbus_parse_cis(device_t cbdev, device_t child,
  100                     struct tuple_callbacks *callbacks);
  101 static int      barsort(const void *a, const void *b);
  102 static int      cardbus_alloc_resources(device_t cbdev, device_t child);
  103 static void     cardbus_add_map(device_t cbdev, device_t child, int reg);
  104 static void     cardbus_pickup_maps(device_t cbdev, device_t child);
  105 
  106 
  107 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
  108 
  109 static char *funcnames[] = {
  110         "Multi-Functioned",
  111         "Memory",
  112         "Serial Port",
  113         "Parallel Port",
  114         "Fixed Disk",
  115         "Video Adaptor",
  116         "Network Adaptor",
  117         "AIMS",
  118         "SCSI",
  119         "Security"
  120 };
  121 
  122 struct cardbus_quirk {
  123         u_int32_t devid;        /* Vendor/device of the card */
  124         int     type;
  125 #define CARDBUS_QUIRK_MAP_REG   1 /* PCI map register in weird place */
  126         int     arg1;
  127         int     arg2;
  128 };
  129 
  130 struct cardbus_quirk cardbus_quirks[] = {
  131         { 0 }
  132 };
  133 
  134 static struct cis_tupleinfo *cisread_buf;
  135 static int ncisread_buf;
  136 
  137 /*
  138  * Handler functions for various CIS tuples
  139  */
  140 
  141 DECODE_PROTOTYPE(generic)
  142 {
  143 #ifdef CARDBUS_DEBUG
  144         int i;
  145 
  146         if (info)
  147                 printf("TUPLE: %s [%d]:", info->name, len);
  148         else
  149                 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
  150 
  151         for (i = 0; i < len; i++) {
  152                 if (i % 0x10 == 0 && len > 0x10)
  153                         printf("\n       0x%02x:", i);
  154                 printf(" %02x", tupledata[i]);
  155         }
  156         printf("\n");
  157 #endif
  158         return (0);
  159 }
  160 
  161 DECODE_PROTOTYPE(nothing)
  162 {
  163         return (0);
  164 }
  165 
  166 DECODE_PROTOTYPE(copy)
  167 {
  168         struct cis_tupleinfo *tmpbuf;
  169 
  170         tmpbuf = malloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1),
  171             M_DEVBUF, M_WAITOK);
  172         if (ncisread_buf > 0) {
  173                 memcpy(tmpbuf, cisread_buf,
  174                     sizeof(struct cis_tupleinfo) * ncisread_buf);
  175                 free(cisread_buf, M_DEVBUF);
  176         }
  177         cisread_buf = tmpbuf;
  178 
  179         cisread_buf[ncisread_buf].id = id;
  180         cisread_buf[ncisread_buf].len = len;
  181         cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, M_WAITOK);
  182         memcpy(cisread_buf[ncisread_buf].data, tupledata, len);
  183         ncisread_buf++;
  184         return (0);
  185 }
  186 
  187 DECODE_PROTOTYPE(linktarget)
  188 {
  189 #ifdef CARDBUS_DEBUG
  190         int i;
  191 
  192         printf("TUPLE: %s [%d]:", info->name, len);
  193 
  194         for (i = 0; i < len; i++) {
  195                 if (i % 0x10 == 0 && len > 0x10)
  196                         printf("\n       0x%02x:", i);
  197                 printf(" %02x", tupledata[i]);
  198         }
  199         printf("\n");
  200 #endif
  201         if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
  202             tupledata[2] != 'S') {
  203                 printf("Invalid data for CIS Link Target!\n");
  204                 decode_tuple_generic(cbdev, child, id, len, tupledata,
  205                     start, off, info);
  206                 return (EINVAL);
  207         }
  208         return (0);
  209 }
  210 
  211 DECODE_PROTOTYPE(vers_1)
  212 {
  213         int i;
  214 
  215         printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
  216         printf("Product name: ");
  217         for (i = 2; i < len; i++) {
  218                 if (tupledata[i] == '\0')
  219                         printf(" | ");
  220                 else if (tupledata[i] == 0xff)
  221                         break;
  222                 else
  223                         printf("%c", tupledata[i]);
  224         }
  225         printf("\n");
  226         return (0);
  227 }
  228 
  229 DECODE_PROTOTYPE(funcid)
  230 {
  231         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  232         int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
  233         int i;
  234 
  235         printf("Functions: ");
  236         for (i = 0; i < len; i++) {
  237                 if (tupledata[i] < numnames)
  238                         printf("%s", funcnames[tupledata[i]]);
  239                 else
  240                         printf("Unknown(%d)", tupledata[i]);
  241                 if (i < len-1)
  242                         printf(", ");
  243         }
  244 
  245         if (len > 0)
  246                 dinfo->funcid = tupledata[0];           /* use first in list */
  247         printf("\n");
  248         return (0);
  249 }
  250 
  251 DECODE_PROTOTYPE(manfid)
  252 {
  253         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  254         int i;
  255 
  256         printf("Manufacturer ID: ");
  257         for (i = 0; i < len; i++)
  258                 printf("%02x", tupledata[i]);
  259         printf("\n");
  260 
  261         if (len == 5) {
  262                 dinfo->mfrid = tupledata[1] | (tupledata[2]<<8);
  263                 dinfo->prodid = tupledata[3] | (tupledata[4]<<8);
  264         }
  265         return (0);
  266 }
  267 
  268 DECODE_PROTOTYPE(funce)
  269 {
  270         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  271         int type, i;
  272 
  273         printf("Function Extension: ");
  274         for (i = 0; i < len; i++)
  275                 printf("%02x", tupledata[i]);
  276         printf("\n");
  277         if (len < 2)                    /* too short */
  278                 return (0);
  279         type = tupledata[0];            /* XXX <32 always? */
  280         switch (dinfo->funcid) {
  281         case TPL_FUNC_SERIAL:
  282                 if (type == TPL_FUNCE_SER_UART) {       /* NB: len known > 1 */
  283                         dinfo->funce.sio.type = tupledata[1] & 0x1f;
  284                 }
  285                 dinfo->fepresent |= 1<<type;
  286                 break;
  287         case TPL_FUNC_LAN:
  288                 switch (type) {
  289                 case TPL_FUNCE_LAN_TECH:
  290                         dinfo->funce.lan.tech = tupledata[1];   /* XXX mask? */
  291                         break;
  292 #if 0
  293                 case TPL_FUNCE_LAN_SPEED:
  294                         for (i = 0; i < 3; i++) {
  295                                 if (dinfo->funce.lan.speed[i] == 0) {
  296                                         if (len > 4) {
  297                                                 dinfo->funce.lan.speed[i] =
  298                                                         ...;
  299                                         }
  300                                         break;
  301                                 }
  302                         }
  303                         break;
  304 #endif
  305                 case TPL_FUNCE_LAN_MEDIA:
  306                         for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
  307                                 if (dinfo->funce.lan.media[i] == 0) {
  308                                         /* NB: len known > 1 */
  309                                         dinfo->funce.lan.media[i] =
  310                                                 tupledata[1];   /*XXX? mask */
  311                                         break;
  312                                 }
  313                         }
  314                         break;
  315                 case TPL_FUNCE_LAN_NID:
  316                         if (len > 6)
  317                                 bcopy(&tupledata[1], dinfo->funce.lan.nid, 6);
  318                         break;
  319                 case TPL_FUNCE_LAN_CONN:
  320                         dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
  321                         break;
  322                 }
  323                 dinfo->fepresent |= 1<<type;
  324                 break;
  325         }
  326         return (0);
  327 }
  328 
  329 DECODE_PROTOTYPE(bar)
  330 {
  331         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  332         int type;
  333         int reg;
  334         u_int32_t bar;
  335 
  336         if (len != 6) {
  337                 printf("*** ERROR *** BAR length not 6 (%d)\n", len);
  338                 return (EINVAL);
  339         }
  340         reg = *(u_int16_t*)tupledata;
  341         len = *(u_int32_t*)(tupledata + 2);
  342         if (reg & TPL_BAR_REG_AS) {
  343                 type = SYS_RES_IOPORT;
  344         } else {
  345                 type = SYS_RES_MEMORY;
  346         }
  347         bar = (reg & TPL_BAR_REG_ASI_MASK) - 1;
  348         if (bar < 0 || bar > 5 ||
  349             (type == SYS_RES_IOPORT && bar == 5)) {
  350                 device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n",
  351                     reg, bar);
  352                 return (0);
  353         }
  354         bar = CARDBUS_BASE0_REG + bar * 4;
  355         if (type == SYS_RES_MEMORY) {
  356                 if (bar & TPL_BAR_REG_PREFETCHABLE)
  357                         dinfo->mprefetchable |= BARBIT(bar);
  358                 if (bar & TPL_BAR_REG_BELOW1MB)
  359                         dinfo->mbelow1mb |= BARBIT(bar);
  360         } else if (type == SYS_RES_IOPORT) {
  361                 if (bar & TPL_BAR_REG_BELOW1MB)
  362                         dinfo->ibelow1mb |= BARBIT(bar);
  363         }
  364         DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
  365             (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
  366             (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
  367             " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
  368             ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") :
  369             (dinfo->ibelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "" ));
  370 
  371         resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
  372 
  373         /*
  374          * Mark the appropriate bit in the PCI command register so that
  375          * device drivers will know which type of BARs can be used.
  376          */
  377         pci_enable_io(child, type);
  378         return (0);
  379 }
  380 
  381 DECODE_PROTOTYPE(unhandled)
  382 {
  383         printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
  384         return (-1);
  385 }
  386 
  387 DECODE_PROTOTYPE(end)
  388 {
  389         printf("CIS reading done\n");
  390         return (0);
  391 }
  392 
  393 /*
  394  * Functions to read the a tuple from the card
  395  */
  396 
  397 static int
  398 cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start,
  399     u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
  400 {
  401         int i, j;
  402         u_int32_t e;
  403         u_int32_t loc;
  404 
  405         loc = start + *off;
  406 
  407         e = pci_read_config(child, loc - loc % 4, 4);
  408         for (j = loc % 4; j > 0; j--)
  409                 e >>= 8;
  410         *len = 0;
  411         for (i = loc, j = -2; j < *len; j++, i++) {
  412                 if (i % 4 == 0)
  413                         e = pci_read_config(child, i, 4);
  414                 if (j == -2)
  415                         *tupleid = 0xff & e;
  416                 else if (j == -1)
  417                         *len = 0xff & e;
  418                 else
  419                         tupledata[j] = 0xff & e;
  420                 e >>= 8;
  421         }
  422         *off += *len + 2;
  423         return (0);
  424 }
  425 
  426 static int
  427 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start,
  428     u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
  429 {
  430         bus_space_tag_t bt;
  431         bus_space_handle_t bh;
  432         int ret;
  433 
  434         bt = rman_get_bustag(res);
  435         bh = rman_get_bushandle(res);
  436 
  437         *tupleid = bus_space_read_1(bt, bh, start + *off);
  438         *len = bus_space_read_1(bt, bh, start + *off + 1);
  439         bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
  440         ret = 0;
  441         *off += *len + 2;
  442         return (ret);
  443 }
  444 
  445 static int
  446 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
  447     u_int32_t start, u_int32_t *off, int *tupleid, int *len,
  448     u_int8_t *tupledata)
  449 {
  450         if (res == (struct resource*)~0UL) {
  451                 return (cardbus_read_tuple_conf(cbdev, child, start, off,
  452                     tupleid, len, tupledata));
  453         } else {
  454                 return (cardbus_read_tuple_mem(cbdev, res, start, off,
  455                     tupleid, len, tupledata));
  456         }
  457 }
  458 
  459 static void
  460 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
  461     struct resource *res)
  462 {
  463         if (res != (struct resource*)~0UL) {
  464                 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
  465                 pci_write_config(child, rid, 0, 4);
  466                 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
  467         }
  468 }
  469 
  470 static struct resource *
  471 cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start,
  472     int *rid)
  473 {
  474         u_int32_t testval;
  475         u_int32_t size;
  476         struct resource *res;
  477 
  478         switch (CARDBUS_CIS_SPACE(*start)) {
  479         case CARDBUS_CIS_ASI_TUPLE:
  480                 /* CIS in PCI config space need no initialization */
  481                 return ((struct resource*)~0UL);
  482         case CARDBUS_CIS_ASI_BAR0:
  483         case CARDBUS_CIS_ASI_BAR1:
  484         case CARDBUS_CIS_ASI_BAR2:
  485         case CARDBUS_CIS_ASI_BAR3:
  486         case CARDBUS_CIS_ASI_BAR4:
  487         case CARDBUS_CIS_ASI_BAR5:
  488                 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
  489                 break;
  490         case CARDBUS_CIS_ASI_ROM:
  491                 *rid = CARDBUS_ROM_REG;
  492 #if 0
  493                 /*
  494                  * This mask doesn't contain the bit that actually enables
  495                  * the Option ROM.
  496                  */
  497                 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
  498 #endif
  499                 break;
  500         default:
  501                 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
  502                     CARDBUS_CIS_SPACE(*start));
  503                 return (NULL);
  504         }
  505 
  506         /* figure out how much space we need */
  507         pci_write_config(child, *rid, 0xffffffff, 4);
  508         testval = pci_read_config(child, *rid, 4);
  509 
  510         /*
  511          * This bit has a different meaning depending if we are dealing
  512          * with a normal BAR or an Option ROM BAR.
  513          */
  514         if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
  515                 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
  516                 return (NULL);
  517         }
  518 
  519         size = CARDBUS_MAPREG_MEM_SIZE(testval);
  520         /* XXX Is this some kind of hack? */
  521         if (size < 4096)
  522                 size = 4096;
  523         /* allocate the memory space to read CIS */
  524         res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
  525             rman_make_alignment_flags(size) | RF_ACTIVE);
  526         if (res == NULL) {
  527                 device_printf(cbdev, "Unable to allocate resource "
  528                     "to read CIS.\n");
  529                 return (NULL);
  530         }
  531         pci_write_config(child, *rid,
  532             rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
  533                 CARDBUS_ROM_ENABLE : 0),
  534             4);
  535         PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
  536 
  537         /* Flip to the right ROM image if CIS is in ROM */
  538         if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
  539                 bus_space_tag_t bt;
  540                 bus_space_handle_t bh;
  541                 u_int32_t imagesize;
  542                 u_int32_t imagebase = 0;
  543                 u_int32_t pcidata;
  544                 u_int16_t romsig;
  545                 int romnum = 0;
  546                 int imagenum;
  547 
  548                 bt = rman_get_bustag(res);
  549                 bh = rman_get_bushandle(res);
  550 
  551                 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
  552                 for (romnum = 0;; romnum++) {
  553                         romsig = bus_space_read_2(bt, bh,
  554                             imagebase + CARDBUS_EXROM_SIGNATURE);
  555                         if (romsig != 0xaa55) {
  556                                 device_printf(cbdev, "Bad header in rom %d: "
  557                                     "[%x] %04x\n", romnum, imagebase + 
  558                                     CARDBUS_EXROM_SIGNATURE, romsig);
  559                                 bus_release_resource(cbdev, SYS_RES_MEMORY,
  560                                     *rid, res);
  561                                 *rid = 0;
  562                                 return (NULL);
  563                         }
  564 
  565                         /*
  566                          * If this was the Option ROM image that we were
  567                          * looking for, then we are done.
  568                          */
  569                         if (romnum == imagenum)
  570                                 break;
  571 
  572                         /* Find out where the next Option ROM image is */
  573                         pcidata = imagebase + bus_space_read_2(bt, bh,
  574                             imagebase + CARDBUS_EXROM_DATA_PTR);
  575                         imagesize = bus_space_read_2(bt, bh,
  576                             pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
  577 
  578                         if (imagesize == 0) {
  579                                 /*
  580                                  * XXX some ROMs seem to have this as zero,
  581                                  * can we assume this means 1 block?
  582                                  */
  583                                 device_printf(cbdev, "Warning, size of Option "
  584                                     "ROM image %d is 0 bytes, assuming 512 "
  585                                     "bytes.\n", romnum);
  586                                 imagesize = 1;
  587                         }
  588 
  589                         /* Image size is in 512 byte units */
  590                         imagesize <<= 9;
  591 
  592                         if ((bus_space_read_1(bt, bh, pcidata + 
  593                             CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
  594                                 device_printf(cbdev, "Cannot find CIS in "
  595                                     "Option ROM\n");
  596                                 bus_release_resource(cbdev, SYS_RES_MEMORY,
  597                                     *rid, res);
  598                                 *rid = 0;
  599                                 return (NULL);
  600                         }
  601                         imagebase += imagesize;
  602                 }
  603                 *start = imagebase + CARDBUS_CIS_ADDR(*start);
  604         } else {
  605                 *start = CARDBUS_CIS_ADDR(*start);
  606         }
  607 
  608         return (res);
  609 }
  610 
  611 /*
  612  * Dispatch the right handler function per tuple
  613  */
  614 
  615 static int
  616 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
  617     u_int8_t *tupledata, u_int32_t start, u_int32_t *off,
  618     struct tuple_callbacks *callbacks)
  619 {
  620         int i;
  621         for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
  622                 if (tupleid == callbacks[i].id)
  623                         return (callbacks[i].func(cbdev, child, tupleid, len,
  624                             tupledata, start, off, &callbacks[i]));
  625         }
  626 
  627         if (tupleid < CISTPL_CUSTOMSTART) {
  628                 device_printf(cbdev, "Undefined tuple encountered, "
  629                     "CIS parsing terminated\n");
  630                 return (EINVAL);
  631         }
  632         return (callbacks[i].func(cbdev, child, tupleid, len,
  633             tupledata, start, off, NULL));
  634 }
  635 
  636 static int
  637 cardbus_parse_cis(device_t cbdev, device_t child,
  638     struct tuple_callbacks *callbacks)
  639 {
  640         u_int8_t tupledata[MAXTUPLESIZE];
  641         int tupleid;
  642         int len;
  643         int expect_linktarget;
  644         u_int32_t start, off;
  645         struct resource *res;
  646         int rid;
  647 
  648         bzero(tupledata, MAXTUPLESIZE);
  649         expect_linktarget = TRUE;
  650         if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
  651                 return (ENXIO);
  652         off = 0;
  653         res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
  654         if (res == NULL)
  655                 return (ENXIO);
  656         do {
  657                 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
  658                     &tupleid, &len, tupledata)) {
  659                         device_printf(cbdev, "Failed to read CIS.\n");
  660                         cardbus_read_tuple_finish(cbdev, child, rid, res);
  661                         return (ENXIO);
  662                 }
  663 
  664                 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
  665                         device_printf(cbdev, "Expecting link target, got 0x%x\n",
  666                             tupleid);
  667                         cardbus_read_tuple_finish(cbdev, child, rid, res);
  668                         return (EINVAL);
  669                 }
  670                 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
  671                     tupledata, start, &off, callbacks);
  672                 if (expect_linktarget != 0) {
  673                         cardbus_read_tuple_finish(cbdev, child, rid, res);
  674                         return (expect_linktarget);
  675                 }
  676         } while (tupleid != CISTPL_END);
  677         cardbus_read_tuple_finish(cbdev, child, rid, res);
  678         return (0);
  679 }
  680 
  681 static int
  682 barsort(const void *a, const void *b)
  683 {
  684         return ((*(const struct resource_list_entry * const *)b)->count -
  685             (*(const struct resource_list_entry * const *)a)->count);
  686 }
  687 
  688 static int
  689 cardbus_alloc_resources(device_t cbdev, device_t child)
  690 {
  691         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  692         int count;
  693         struct resource_list_entry *rle;
  694         struct resource_list_entry **barlist;
  695         int tmp;
  696         u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
  697         struct resource *res;
  698         u_int32_t start,end;
  699         int rid, flags;
  700 
  701         count = 0;
  702         SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
  703                 count++;
  704         }
  705         if (count == 0)
  706                 return (0);
  707         barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
  708             M_WAITOK);
  709         count = 0;
  710         SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
  711                 barlist[count] = rle;
  712                 if (rle->type == SYS_RES_IOPORT) {
  713                         io_size += rle->count;
  714                 } else if (rle->type == SYS_RES_MEMORY) {
  715                         if (dinfo->mprefetchable & BARBIT(rle->rid))
  716                                 mem_psize += rle->count;
  717                         else
  718                                 mem_nsize += rle->count;
  719                 }
  720                 count++;
  721         }
  722 
  723         /*
  724          * We want to allocate the largest resource first, so that our
  725          * allocated memory is packed.
  726          */
  727         qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
  728 
  729         /* Allocate prefetchable memory */
  730         flags = 0;
  731         for (tmp = 0; tmp < count; tmp++) {
  732                 if (barlist[tmp]->res == NULL &&
  733                     barlist[tmp]->type == SYS_RES_MEMORY &&
  734                     dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
  735                         flags = rman_make_alignment_flags(barlist[tmp]->count);
  736                         break;
  737                 }
  738         }
  739         if (flags > 0) { /* If any prefetchable memory is requested... */
  740                 /*
  741                  * First we allocate one big space for all resources of this
  742                  * type.  We do this because our parent, pccbb, needs to open
  743                  * a window to forward all addresses within the window, and
  744                  * it would be best if nobody else has resources allocated
  745                  * within the window.
  746                  * (XXX: Perhaps there might be a better way to do this?)
  747                  */
  748                 rid = 0;
  749                 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
  750                     (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
  751                     mem_psize, flags);
  752                 start = rman_get_start(res);
  753                 end = rman_get_end(res);
  754                 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
  755                 /*
  756                  * Now that we know the region is free, release it and hand it
  757                  * out piece by piece.
  758                  */
  759                 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
  760                 for (tmp = 0; tmp < count; tmp++) {
  761                         if (barlist[tmp]->res == NULL &&
  762                             barlist[tmp]->type == SYS_RES_MEMORY &&
  763                             dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
  764                                 barlist[tmp]->res = bus_alloc_resource(cbdev,
  765                                     barlist[tmp]->type,
  766                                     &barlist[tmp]->rid, start, end,
  767                                     barlist[tmp]->count,
  768                                     rman_make_alignment_flags(
  769                                     barlist[tmp]->count));
  770                                 if (barlist[tmp]->res == NULL) {
  771                                         mem_nsize += barlist[tmp]->count;
  772                                         dinfo->mprefetchable &=
  773                                             ~BARBIT(barlist[tmp]->rid);
  774                                         DEVPRINTF((cbdev, "Cannot pre-allocate "
  775                                             "prefetchable memory, will try as "
  776                                             "non-prefetchable.\n"));
  777                                 } else {
  778                                         barlist[tmp]->start =
  779                                             rman_get_start(barlist[tmp]->res);
  780                                         barlist[tmp]->end =
  781                                             rman_get_end(barlist[tmp]->res);
  782                                         pci_write_config(child,
  783                                             barlist[tmp]->rid,
  784                                             barlist[tmp]->start, 4);
  785                                         DEVPRINTF((cbdev, "Prefetchable memory "
  786                                             "rid=%x at %lx-%lx\n",
  787                                             barlist[tmp]->rid,
  788                                             barlist[tmp]->start,
  789                                             barlist[tmp]->end));
  790                                 }
  791                         }
  792                 }
  793         }
  794 
  795         /* Allocate non-prefetchable memory */
  796         flags = 0;
  797         for (tmp = 0; tmp < count; tmp++) {
  798                 if (barlist[tmp]->res == NULL &&
  799                     barlist[tmp]->type == SYS_RES_MEMORY) {
  800                         flags = rman_make_alignment_flags(barlist[tmp]->count);
  801                         break;
  802                 }
  803         }
  804         if (flags > 0) { /* If any non-prefetchable memory is requested... */
  805                 /*
  806                  * First we allocate one big space for all resources of this
  807                  * type.  We do this because our parent, pccbb, needs to open
  808                  * a window to forward all addresses within the window, and
  809                  * it would be best if nobody else has resources allocated
  810                  * within the window.
  811                  * (XXX: Perhaps there might be a better way to do this?)
  812                  */
  813                 rid = 0;
  814                 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
  815                     ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
  816                     mem_nsize, flags);
  817                 start = rman_get_start(res);
  818                 end = rman_get_end(res);
  819                 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
  820                     start, end));
  821                 /*
  822                  * Now that we know the region is free, release it and hand it
  823                  * out piece by piece.
  824                  */
  825                 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
  826                 for (tmp = 0; tmp < count; tmp++) {
  827                         if (barlist[tmp]->res == NULL &&
  828                             barlist[tmp]->type == SYS_RES_MEMORY) {
  829                                 barlist[tmp]->res = bus_alloc_resource(cbdev,
  830                                     barlist[tmp]->type, &barlist[tmp]->rid,
  831                                     start, end, barlist[tmp]->count,
  832                                     rman_make_alignment_flags(
  833                                     barlist[tmp]->count));
  834                                 if (barlist[tmp]->res == NULL) {
  835                                         DEVPRINTF((cbdev, "Cannot pre-allocate "
  836                                             "memory for cardbus device\n"));
  837                                         free(barlist, M_DEVBUF);
  838                                         return (ENOMEM);
  839                                 }
  840                                 barlist[tmp]->start =
  841                                     rman_get_start(barlist[tmp]->res);
  842                                 barlist[tmp]->end = rman_get_end(
  843                                         barlist[tmp]->res);
  844                                 pci_write_config(child, barlist[tmp]->rid,
  845                                     barlist[tmp]->start, 4);
  846                                 DEVPRINTF((cbdev, "Non-prefetchable memory "
  847                                     "rid=%x at %lx-%lx (%lx)\n",
  848                                     barlist[tmp]->rid, barlist[tmp]->start,
  849                                     barlist[tmp]->end, barlist[tmp]->count));
  850                         }
  851                 }
  852         }
  853 
  854         /* Allocate IO ports */
  855         flags = 0;
  856         for (tmp = 0; tmp < count; tmp++) {
  857                 if (barlist[tmp]->res == NULL &&
  858                     barlist[tmp]->type == SYS_RES_IOPORT) {
  859                         flags = rman_make_alignment_flags(barlist[tmp]->count);
  860                         break;
  861                 }
  862         }
  863         if (flags > 0) { /* If any IO port is requested... */
  864                 /*
  865                  * First we allocate one big space for all resources of this
  866                  * type.  We do this because our parent, pccbb, needs to open
  867                  * a window to forward all addresses within the window, and
  868                  * it would be best if nobody else has resources allocated
  869                  * within the window.
  870                  * (XXX: Perhaps there might be a better way to do this?)
  871                  */
  872                 rid = 0;
  873                 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
  874                     (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
  875                 start = rman_get_start(res);
  876                 end = rman_get_end(res);
  877                 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
  878                 /*
  879                  * Now that we know the region is free, release it and hand it
  880                  * out piece by piece.
  881                  */
  882                 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
  883                 for (tmp = 0; tmp < count; tmp++) {
  884                         if (barlist[tmp]->res == NULL &&
  885                             barlist[tmp]->type == SYS_RES_IOPORT) {
  886                                 barlist[tmp]->res = bus_alloc_resource(cbdev,
  887                                     barlist[tmp]->type, &barlist[tmp]->rid,
  888                                     start, end, barlist[tmp]->count,
  889                                     rman_make_alignment_flags(
  890                                     barlist[tmp]->count));
  891                                 if (barlist[tmp]->res == NULL) {
  892                                         DEVPRINTF((cbdev, "Cannot pre-allocate "
  893                                             "IO port for cardbus device\n"));
  894                                         free(barlist, M_DEVBUF);
  895                                         return (ENOMEM);
  896                                 }
  897                                 barlist[tmp]->start =
  898                                     rman_get_start(barlist[tmp]->res);
  899                                 barlist[tmp]->end =
  900                                     rman_get_end(barlist[tmp]->res);
  901                         pci_write_config(child, barlist[tmp]->rid,
  902                             barlist[tmp]->start, 4);
  903                         DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
  904                             barlist[tmp]->rid, barlist[tmp]->start,
  905                             barlist[tmp]->end));
  906                         }
  907                 }
  908         }
  909 
  910         /* Allocate IRQ */
  911         rid = 0;
  912         res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
  913             RF_SHAREABLE);
  914         resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
  915             rman_get_start(res), rman_get_end(res), 1);
  916         rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
  917         rle->res = res;
  918         dinfo->pci.cfg.intline = rman_get_start(res);
  919         pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
  920 
  921         free(barlist, M_DEVBUF);
  922         return (0);
  923 }
  924 
  925 /*
  926  * Adding a memory/io resource (sans CIS)
  927  */
  928 
  929 static void
  930 cardbus_add_map(device_t cbdev, device_t child, int reg)
  931 {
  932         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  933         struct resource_list_entry *rle;
  934         u_int32_t size;
  935         u_int32_t testval;
  936         int type;
  937 
  938         SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
  939                 if (rle->rid == reg)
  940                         return;
  941         }
  942 
  943         if (reg == CARDBUS_ROM_REG)
  944                 testval = CARDBUS_ROM_ADDRMASK;
  945         else
  946                 testval = ~0;
  947 
  948         pci_write_config(child, reg, testval, 4);
  949         testval = pci_read_config(child, reg, 4);
  950 
  951         if (testval == ~0 || testval == 0)
  952                 return;
  953 
  954         if ((testval & 1) == 0)
  955                 type = SYS_RES_MEMORY;
  956         else
  957                 type = SYS_RES_IOPORT;
  958 
  959         size = CARDBUS_MAPREG_MEM_SIZE(testval);
  960         device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
  961             reg, size);
  962         resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
  963 }
  964 
  965 static void
  966 cardbus_pickup_maps(device_t cbdev, device_t child)
  967 {
  968         struct cardbus_devinfo *dinfo = device_get_ivars(child);
  969         struct cardbus_quirk *q;
  970         int reg;
  971 
  972         /*
  973          * Try to pick up any resources that was not specified in CIS.
  974          * Some devices (eg, 3c656) does not list all resources required by
  975          * the driver in its CIS.
  976          * XXX: should we do this or use quirks?
  977          */
  978         for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
  979                 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
  980         }
  981 
  982         for (q = &cardbus_quirks[0]; q->devid; q++) {
  983                 if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
  984                     && q->type == CARDBUS_QUIRK_MAP_REG) {
  985                         cardbus_add_map(cbdev, child, q->arg1);
  986                 }
  987         }
  988 }
  989 
  990 int
  991 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id,
  992     struct cis_tupleinfo **buff, int *nret)
  993 {
  994         struct tuple_callbacks cisread_callbacks[] = {
  995                 MAKETUPLE(NULL,                 nothing),
  996                 /* first entry will be overwritten */
  997                 MAKETUPLE(NULL,                 nothing),
  998                 MAKETUPLE(DEVICE,               nothing),
  999                 MAKETUPLE(LONG_LINK_CB,         unhandled),
 1000                 MAKETUPLE(INDIRECT,             unhandled),
 1001                 MAKETUPLE(CONFIG_CB,            nothing),
 1002                 MAKETUPLE(CFTABLE_ENTRY_CB,     nothing),
 1003                 MAKETUPLE(LONGLINK_MFC,         unhandled),
 1004                 MAKETUPLE(BAR,                  nothing),
 1005                 MAKETUPLE(PWR_MGMNT,            nothing),
 1006                 MAKETUPLE(EXTDEVICE,            nothing),
 1007                 MAKETUPLE(CHECKSUM,             nothing),
 1008                 MAKETUPLE(LONGLINK_A,           unhandled),
 1009                 MAKETUPLE(LONGLINK_C,           unhandled),
 1010                 MAKETUPLE(LINKTARGET,           nothing),
 1011                 MAKETUPLE(NO_LINK,              nothing),
 1012                 MAKETUPLE(VERS_1,               nothing),
 1013                 MAKETUPLE(ALTSTR,               nothing),
 1014                 MAKETUPLE(DEVICE_A,             nothing),
 1015                 MAKETUPLE(JEDEC_C,              nothing),
 1016                 MAKETUPLE(JEDEC_A,              nothing),
 1017                 MAKETUPLE(CONFIG,               nothing),
 1018                 MAKETUPLE(CFTABLE_ENTRY,        nothing),
 1019                 MAKETUPLE(DEVICE_OC,            nothing),
 1020                 MAKETUPLE(DEVICE_OA,            nothing),
 1021                 MAKETUPLE(DEVICE_GEO,           nothing),
 1022                 MAKETUPLE(DEVICE_GEO_A,         nothing),
 1023                 MAKETUPLE(MANFID,               nothing),
 1024                 MAKETUPLE(FUNCID,               nothing),
 1025                 MAKETUPLE(FUNCE,                nothing),
 1026                 MAKETUPLE(SWIL,                 nothing),
 1027                 MAKETUPLE(VERS_2,               nothing),
 1028                 MAKETUPLE(FORMAT,               nothing),
 1029                 MAKETUPLE(GEOMETRY,             nothing),
 1030                 MAKETUPLE(BYTEORDER,            nothing),
 1031                 MAKETUPLE(DATE,                 nothing),
 1032                 MAKETUPLE(BATTERY,              nothing),
 1033                 MAKETUPLE(ORG,                  nothing),
 1034                 MAKETUPLE(END,                  end),
 1035                 MAKETUPLE(GENERIC,              nothing),
 1036         };
 1037         int ret;
 1038 
 1039         cisread_callbacks[0].id = id;
 1040         cisread_callbacks[0].name = "COPY";
 1041         cisread_callbacks[0].func = decode_tuple_copy;
 1042         ncisread_buf = 0;
 1043         cisread_buf = NULL;
 1044         ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
 1045 
 1046         *buff = cisread_buf;
 1047         *nret = ncisread_buf;
 1048         return (ret);
 1049 }
 1050 
 1051 void
 1052 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
 1053 {
 1054         int i;
 1055         for (i = 0; i < *nret; i++)
 1056                 free(buff[i].data, M_DEVBUF);
 1057         if (*nret > 0)
 1058                 free(buff, M_DEVBUF);
 1059 }
 1060 
 1061 int
 1062 cardbus_do_cis(device_t cbdev, device_t child)
 1063 {
 1064         int ret;
 1065         struct tuple_callbacks init_callbacks[] = {
 1066                 MAKETUPLE(NULL,                 generic),
 1067                 MAKETUPLE(DEVICE,               generic),
 1068                 MAKETUPLE(LONG_LINK_CB,         unhandled),
 1069                 MAKETUPLE(INDIRECT,             unhandled),
 1070                 MAKETUPLE(CONFIG_CB,            generic),
 1071                 MAKETUPLE(CFTABLE_ENTRY_CB,     generic),
 1072                 MAKETUPLE(LONGLINK_MFC,         unhandled),
 1073                 MAKETUPLE(BAR,                  bar),
 1074                 MAKETUPLE(PWR_MGMNT,            generic),
 1075                 MAKETUPLE(EXTDEVICE,            generic),
 1076                 MAKETUPLE(CHECKSUM,             generic),
 1077                 MAKETUPLE(LONGLINK_A,           unhandled),
 1078                 MAKETUPLE(LONGLINK_C,           unhandled),
 1079                 MAKETUPLE(LINKTARGET,           linktarget),
 1080                 MAKETUPLE(NO_LINK,              generic),
 1081                 MAKETUPLE(VERS_1,               vers_1),
 1082                 MAKETUPLE(ALTSTR,               generic),
 1083                 MAKETUPLE(DEVICE_A,             generic),
 1084                 MAKETUPLE(JEDEC_C,              generic),
 1085                 MAKETUPLE(JEDEC_A,              generic),
 1086                 MAKETUPLE(CONFIG,               generic),
 1087                 MAKETUPLE(CFTABLE_ENTRY,        generic),
 1088                 MAKETUPLE(DEVICE_OC,            generic),
 1089                 MAKETUPLE(DEVICE_OA,            generic),
 1090                 MAKETUPLE(DEVICE_GEO,           generic),
 1091                 MAKETUPLE(DEVICE_GEO_A,         generic),
 1092                 MAKETUPLE(MANFID,               manfid),
 1093                 MAKETUPLE(FUNCID,               funcid),
 1094                 MAKETUPLE(FUNCE,                funce),
 1095                 MAKETUPLE(SWIL,                 generic),
 1096                 MAKETUPLE(VERS_2,               generic),
 1097                 MAKETUPLE(FORMAT,               generic),
 1098                 MAKETUPLE(GEOMETRY,             generic),
 1099                 MAKETUPLE(BYTEORDER,            generic),
 1100                 MAKETUPLE(DATE,                 generic),
 1101                 MAKETUPLE(BATTERY,              generic),
 1102                 MAKETUPLE(ORG,                  generic),
 1103                 MAKETUPLE(END,                  end),
 1104                 MAKETUPLE(GENERIC,              generic),
 1105         };
 1106 
 1107         ret = cardbus_parse_cis(cbdev, child, init_callbacks);
 1108         if (ret < 0)
 1109                 return (ret);
 1110         cardbus_pickup_maps(cbdev, child);
 1111         return (cardbus_alloc_resources(cbdev, child));
 1112 }

Cache object: 0b30a8e4840bdce628af1735a7b5bca8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.