]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/pccard/pccard_cis.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / pccard / pccard_cis.c
1 /* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps Exp $ */
2 /* $FreeBSD$ */
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/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/kernel.h>
38 #include <sys/queue.h>
39 #include <sys/types.h>
40
41 #include <sys/bus.h>
42 #include <machine/bus.h>
43 #include <sys/rman.h>
44 #include <machine/resource.h>
45
46 #include <dev/pccard/pccardreg.h>
47 #include <dev/pccard/pccardvar.h>
48 #include <dev/pccard/pccardvarp.h>
49 #include <dev/pccard/pccard_cis.h>
50
51 #include "card_if.h"
52
53 extern int      pccard_cis_debug;
54
55 #define PCCARDCISDEBUG
56 #ifdef PCCARDCISDEBUG
57 #define DPRINTF(arg) do { if (pccard_cis_debug) printf arg; } while (0)
58 #define DEVPRINTF(arg) do { if (pccard_cis_debug) device_printf arg; } while (0)
59 #else
60 #define DPRINTF(arg)
61 #define DEVPRINTF(arg)
62 #endif
63
64 #define PCCARD_CIS_SIZE         4096
65
66 struct cis_state {
67         int     count;
68         int     gotmfc;
69         struct pccard_config_entry temp_cfe;
70         struct pccard_config_entry *default_cfe;
71         struct pccard_card *card;
72         struct pccard_function *pf;
73 };
74
75 static int pccard_parse_cis_tuple(const struct pccard_tuple *, void *);
76 static int decode_funce(const struct pccard_tuple *, struct pccard_function *);
77
78 void
79 pccard_read_cis(struct pccard_softc *sc)
80 {
81         struct cis_state state;
82
83         bzero(&state, sizeof state);
84         state.card = &sc->card;
85         state.card->error = 0;
86         state.card->cis1_major = -1;
87         state.card->cis1_minor = -1;
88         state.card->cis1_info[0] = NULL;
89         state.card->cis1_info[1] = NULL;
90         state.card->cis1_info[2] = NULL;
91         state.card->cis1_info[3] = NULL;
92         state.card->manufacturer = PCMCIA_VENDOR_INVALID;
93         state.card->product = PCMCIA_PRODUCT_INVALID;
94         STAILQ_INIT(&state.card->pf_head);
95         state.pf = NULL;
96
97         /*
98          * XXX The following shouldn't be needed, but some slow cards
99          * XXX seem to need it still.  Need to investigate if there's
100          * XXX a way to tell if the card is 'ready' or not rather than
101          * XXX sleeping like this.  We're called just after the power
102          * XXX up of the socket.  The standard timing diagrams don't
103          * XXX seem to indicate that a delay is required.  The old
104          * XXX delay was 1s.  This delay is .1s.
105          */
106         pause("pccard", hz / 10);
107         if (pccard_scan_cis(device_get_parent(sc->dev), sc->dev,
108             pccard_parse_cis_tuple, &state) == -1)
109                 state.card->error++;
110 }
111
112 int
113 pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
114 {
115         struct resource *res;
116         int rid;
117         struct pccard_tuple tuple;
118         int longlink_present;
119         int longlink_common;
120         u_long longlink_addr;           /* Type suspect */
121         int mfc_count;
122         int mfc_index;
123 #ifdef PCCARDCISDEBUG
124         int cis_none_cnt = 10;  /* Only report 10 CIS_NONEs */
125 #endif
126         struct {
127                 int     common;
128                 u_long  addr;
129         } mfc[256 / 5];
130         int ret;
131
132         ret = 0;
133
134         /* allocate some memory */
135
136         /*
137          * Some reports from the field suggest that a 64k memory boundary
138          * helps card CIS being able to be read.  Try it here and see what
139          * the results actually are.  I'm not sure I understand why this
140          * would make cards work better, but it is easy enough to test.
141          */
142         rid = 0;
143         res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
144             PCCARD_CIS_SIZE, RF_ACTIVE | rman_make_alignment_flags(64*1024));
145         if (res == NULL) {
146                 device_printf(dev, "can't alloc memory to read attributes\n");
147                 return -1;
148         }
149         CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR);
150         tuple.memt = rman_get_bustag(res);
151         tuple.memh = rman_get_bushandle(res);
152         tuple.ptr = 0;
153
154         DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n",
155             (unsigned int) tuple.memh, rman_get_start(res)));
156
157         tuple.mult = 2;
158
159         longlink_present = 1;
160         longlink_common = 1;
161         longlink_addr = 0;
162
163         mfc_count = 0;
164         mfc_index = 0;
165
166         DEVPRINTF((dev, "CIS tuple chain:\n"));
167
168         while (1) {
169                 while (1) {
170                         /*
171                          * Perform boundary check for insane cards.
172                          * If CIS is too long, simulate CIS end.
173                          * (This check may not be sufficient for
174                          * malicious cards.)
175                          */
176                         if (tuple.mult * tuple.ptr >= PCCARD_CIS_SIZE - 1
177                             - 32 /* ad hoc value */ ) {
178                                 printf("CIS is too long -- truncating\n");
179                                 tuple.code = CISTPL_END;
180                         } else {
181                                 /* get the tuple code */
182                                 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
183                         }
184
185                         /* two special-case tuples */
186
187                         if (tuple.code == CISTPL_NULL) {
188 #ifdef PCCARDCISDEBUG
189                                 if (cis_none_cnt > 0)
190                                         DPRINTF(("CISTPL_NONE\n 00\n"));
191                                 else if (cis_none_cnt == 0)
192                                         DPRINTF(("TOO MANY CIS_NONE\n"));
193                                 cis_none_cnt--;
194 #endif
195                                 if ((*fct)(&tuple, arg)) {
196                                         ret = 1;
197                                         goto done;
198                                 }
199                                 tuple.ptr++;
200                                 continue;
201                         } else if (tuple.code == CISTPL_END) {
202                                 DPRINTF(("CISTPL_END\n ff\n"));
203                                 /* Call the function for the END tuple, since
204                                    the CIS semantics depend on it */
205                                 if ((*fct)(&tuple, arg)) {
206                                         ret = 1;
207                                         goto done;
208                                 }
209                                 tuple.ptr++;
210                                 break;
211                         }
212                         /* now all the normal tuples */
213
214                         tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
215                         switch (tuple.code) {
216                         case CISTPL_LONGLINK_A:
217                         case CISTPL_LONGLINK_C:
218                                 if ((*fct)(&tuple, arg)) {
219                                         ret = 1;
220                                         goto done;
221                                 }
222                                 if (tuple.length < 4) {
223                                         DPRINTF(("CISTPL_LONGLINK_%s too "
224                                             "short %d\n",
225                                             longlink_common ? "C" : "A",
226                                             tuple.length));
227                                         break;
228                                 }
229                                 longlink_present = 1;
230                                 longlink_common = (tuple.code ==
231                                     CISTPL_LONGLINK_C) ? 1 : 0;
232                                 longlink_addr = pccard_tuple_read_4(&tuple, 0);
233                                 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
234                                     longlink_common ? "C" : "A",
235                                     longlink_addr));
236                                 break;
237                         case CISTPL_NO_LINK:
238                                 if ((*fct)(&tuple, arg)) {
239                                         ret = 1;
240                                         goto done;
241                                 }
242                                 longlink_present = 0;
243                                 DPRINTF(("CISTPL_NO_LINK\n"));
244                                 break;
245                         case CISTPL_CHECKSUM:
246                                 if ((*fct)(&tuple, arg)) {
247                                         ret = 1;
248                                         goto done;
249                                 }
250                                 if (tuple.length < 5) {
251                                         DPRINTF(("CISTPL_CHECKSUM too "
252                                             "short %d\n", tuple.length));
253                                         break;
254                                 } {
255                                         int16_t offset;
256                                         u_long addr, length;
257                                         u_int cksum, sum;
258                                         int i;
259
260                                         offset = (uint16_t)
261                                             pccard_tuple_read_2(&tuple, 0);
262                                         length = pccard_tuple_read_2(&tuple, 2);
263                                         cksum = pccard_tuple_read_1(&tuple, 4);
264
265                                         addr = tuple.ptr + offset;
266
267                                         DPRINTF(("CISTPL_CHECKSUM addr=%lx "
268                                             "len=%lx cksum=%x",
269                                             addr, length, cksum));
270
271                                         /*
272                                          * XXX do more work to deal with
273                                          * distant regions
274                                          */
275                                         if ((addr >= PCCARD_CIS_SIZE) ||
276                                             ((addr + length) >=
277                                             PCCARD_CIS_SIZE)) {
278                                                 DPRINTF((" skipped, "
279                                                     "too distant\n"));
280                                                 break;
281                                         }
282                                         sum = 0;
283                                         for (i = 0; i < length; i++)
284                                                 sum +=
285                                                     bus_space_read_1(tuple.memt,
286                                                     tuple.memh,
287                                                     addr + tuple.mult * i);
288                                         if (cksum != (sum & 0xff)) {
289                                                 DPRINTF((" failed sum=%x\n",
290                                                     sum));
291                                                 device_printf(dev, 
292                                                     "CIS checksum failed\n");
293 #if 0
294                                                 /*
295                                                  * XXX Some working cards have
296                                                  * XXX bad checksums!!
297                                                  */
298                                                 ret = -1;
299 #endif
300                                         } else {
301                                                 DPRINTF((" ok\n"));
302                                         }
303                                 }
304                                 break;
305                         case CISTPL_LONGLINK_MFC:
306                                 if (tuple.length < 1) {
307                                         DPRINTF(("CISTPL_LONGLINK_MFC too "
308                                             "short %d\n", tuple.length));
309                                         break;
310                                 }
311                                 if (((tuple.length - 1) % 5) != 0) {
312                                         DPRINTF(("CISTPL_LONGLINK_MFC bogus "
313                                             "length %d\n", tuple.length));
314                                         break;
315                                 }
316                                 /*
317                                  * this is kind of ad hoc, as I don't have
318                                  * any real documentation
319                                  */
320                                 {
321                                         int i, tmp_count;
322
323                                         /*
324                                          * put count into tmp var so that
325                                          * if we have to bail (because it's
326                                          * a bogus count) it won't be
327                                          * remembered for later use.
328                                          */
329                                         tmp_count =
330                                             pccard_tuple_read_1(&tuple, 0);
331
332                                         DPRINTF(("CISTPL_LONGLINK_MFC %d",
333                                             tmp_count));
334
335                                         /*
336                                          * make _sure_ it's the right size;
337                                          * if too short, it may be a weird
338                                          * (unknown/undefined) format
339                                          */
340                                         if (tuple.length != (tmp_count*5 + 1)) {
341                                                 DPRINTF((" bogus length %d\n",
342                                                     tuple.length));
343                                                 break;
344                                         }
345                                         /*
346                                          * sanity check for a programming
347                                          * error which is difficult to find
348                                          * when debugging.
349                                          */
350                                         if (tmp_count >
351                                             howmany(sizeof mfc, sizeof mfc[0]))
352                                                 panic("CISTPL_LONGLINK_MFC mfc "
353                                                     "count would blow stack");
354                                         mfc_count = tmp_count;
355                                         for (i = 0; i < mfc_count; i++) {
356                                                 mfc[i].common =
357                                                     (pccard_tuple_read_1(&tuple,
358                                                     1 + 5 * i) ==
359                                                     PCCARD_MFC_MEM_COMMON) ?
360                                                     1 : 0;
361                                                 mfc[i].addr =
362                                                     pccard_tuple_read_4(&tuple,
363                                                     1 + 5 * i + 1);
364                                                 DPRINTF((" %s:%lx",
365                                                     mfc[i].common ? "common" :
366                                                     "attr", mfc[i].addr));
367                                         }
368                                         DPRINTF(("\n"));
369                                 }
370                                 /*
371                                  * for LONGLINK_MFC, fall through to the
372                                  * function.  This tuple has structural and
373                                  * semantic content.
374                                  */
375                         default:
376                                 {
377                                         if ((*fct)(&tuple, arg)) {
378                                                 ret = 1;
379                                                 goto done;
380                                         }
381                                 }
382                                 break;
383                         }       /* switch */
384 #ifdef PCCARDCISDEBUG
385                         /* print the tuple */
386                         {
387                                 int i;
388
389                                 DPRINTF((" %02x %02x", tuple.code,
390                                     tuple.length));
391
392                                 for (i = 0; i < tuple.length; i++) {
393                                         DPRINTF((" %02x",
394                                             pccard_tuple_read_1(&tuple, i)));
395                                         if ((i % 16) == 13)
396                                                 DPRINTF(("\n"));
397                                 }
398
399                                 if ((i % 16) != 14)
400                                         DPRINTF(("\n"));
401                         }
402 #endif
403                         /* skip to the next tuple */
404                         tuple.ptr += 2 + tuple.length;
405                 }
406
407                 /*
408                  * the chain is done.  Clean up and move onto the next one,
409                  * if any.  The loop is here in the case that there is an MFC
410                  * card with no longlink (which defaults to existing, == 0).
411                  * In general, this means that if one pointer fails, it will
412                  * try the next one, instead of just bailing.
413                  */
414                 while (1) {
415                         if (longlink_present) {
416                                 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY,
417                                     rid, longlink_common ?
418                                     PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
419                                 DPRINTF(("cis mem map %x\n",
420                                     (unsigned int) tuple.memh));
421                                 tuple.mult = longlink_common ? 1 : 2;
422                                 tuple.ptr = longlink_addr;
423                                 longlink_present = 0;
424                                 longlink_common = 1;
425                                 longlink_addr = 0;
426                         } else if (mfc_count && (mfc_index < mfc_count)) {
427                                 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY,
428                                     rid, mfc[mfc_index].common ?
429                                     PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
430                                 DPRINTF(("cis mem map %x\n",
431                                     (unsigned int) tuple.memh));
432                                 /* set parse state, and point at the next one */
433                                 tuple.mult = mfc[mfc_index].common ? 1 : 2;
434                                 tuple.ptr = mfc[mfc_index].addr;
435                                 mfc_index++;
436                         } else {
437                                 goto done;
438                         }
439
440                         /* make sure that the link is valid */
441                         tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
442                         if (tuple.code != CISTPL_LINKTARGET) {
443                                 DPRINTF(("CISTPL_LINKTARGET expected, "
444                                     "code %02x observed\n", tuple.code));
445                                 continue;
446                         }
447                         tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
448                         if (tuple.length < 3) {
449                                 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
450                                     tuple.length));
451                                 continue;
452                         }
453                         if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
454                             (pccard_tuple_read_1(&tuple, 1) != 'I') ||
455                             (pccard_tuple_read_1(&tuple, 2) != 'S')) {
456                                 DPRINTF(("CISTPL_LINKTARGET magic "
457                                     "%02x%02x%02x incorrect\n",
458                                     pccard_tuple_read_1(&tuple, 0),
459                                     pccard_tuple_read_1(&tuple, 1),
460                                     pccard_tuple_read_1(&tuple, 2)));
461                                 continue;
462                         }
463                         tuple.ptr += 2 + tuple.length;
464                         break;
465                 }
466         }
467
468 done:
469         bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
470
471         return (ret);
472 }
473
474 /* XXX this is incredibly verbose.  Not sure what trt is */
475
476 void
477 pccard_print_cis(device_t dev)
478 {
479         struct pccard_softc *sc = PCCARD_SOFTC(dev);
480         struct pccard_card *card = &sc->card;
481         struct pccard_function *pf;
482         struct pccard_config_entry *cfe;
483         int i;
484
485         device_printf(dev, "CIS version ");
486         if (card->cis1_major == 4) {
487                 if (card->cis1_minor == 0)
488                         printf("PCCARD 1.0\n");
489                 else if (card->cis1_minor == 1)
490                         printf("PCCARD 2.0 or 2.1\n");
491         } else if (card->cis1_major >= 5)
492                 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
493         else
494                 printf("unknown (major=%d, minor=%d)\n",
495                     card->cis1_major, card->cis1_minor);
496
497         device_printf(dev, "CIS info: ");
498         for (i = 0; i < 4; i++) {
499                 if (card->cis1_info[i] == NULL)
500                         break;
501                 if (i)
502                         printf(", ");
503                 printf("%s", card->cis1_info[i]);
504         }
505         printf("\n");
506
507         device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
508             card->manufacturer, card->product);
509
510         STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
511                 device_printf(dev, "function %d: ", pf->number);
512
513                 switch (pf->function) {
514                 case PCCARD_FUNCTION_UNSPEC:
515                         printf("unspecified");
516                         break;
517                 case PCCARD_FUNCTION_MULTIFUNCTION:
518                         printf("multi-function");
519                         break;
520                 case PCCARD_FUNCTION_MEMORY:
521                         printf("memory");
522                         break;
523                 case PCCARD_FUNCTION_SERIAL:
524                         printf("serial port");
525                         break;
526                 case PCCARD_FUNCTION_PARALLEL:
527                         printf("parallel port");
528                         break;
529                 case PCCARD_FUNCTION_DISK:
530                         printf("fixed disk");
531                         break;
532                 case PCCARD_FUNCTION_VIDEO:
533                         printf("video adapter");
534                         break;
535                 case PCCARD_FUNCTION_NETWORK:
536                         printf("network adapter");
537                         break;
538                 case PCCARD_FUNCTION_AIMS:
539                         printf("auto incrementing mass storage");
540                         break;
541                 case PCCARD_FUNCTION_SCSI:
542                         printf("SCSI bridge");
543                         break;
544                 case PCCARD_FUNCTION_SECURITY:
545                         printf("Security services");
546                         break;
547                 case PCCARD_FUNCTION_INSTRUMENT:
548                         printf("Instrument");
549                         break;
550                 default:
551                         printf("unknown (%d)", pf->function);
552                         break;
553                 }
554
555                 printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask);
556
557                 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
558                         device_printf(dev, "function %d, config table entry "
559                             "%d: ", pf->number, cfe->number);
560
561                         switch (cfe->iftype) {
562                         case PCCARD_IFTYPE_MEMORY:
563                                 printf("memory card");
564                                 break;
565                         case PCCARD_IFTYPE_IO:
566                                 printf("I/O card");
567                                 break;
568                         default:
569                                 printf("card type unknown");
570                                 break;
571                         }
572
573                         printf("; irq mask %x", cfe->irqmask);
574
575                         if (cfe->num_iospace) {
576                                 printf("; iomask %lx, iospace", cfe->iomask);
577
578                                 for (i = 0; i < cfe->num_iospace; i++) {
579                                         printf(" %lx", cfe->iospace[i].start);
580                                         if (cfe->iospace[i].length)
581                                                 printf("-%lx",
582                                                     cfe->iospace[i].start +
583                                                     cfe->iospace[i].length - 1);
584                                 }
585                         }
586                         if (cfe->num_memspace) {
587                                 printf("; memspace");
588
589                                 for (i = 0; i < cfe->num_memspace; i++) {
590                                         printf(" %lx",
591                                             cfe->memspace[i].cardaddr);
592                                         if (cfe->memspace[i].length)
593                                                 printf("-%lx",
594                                                     cfe->memspace[i].cardaddr +
595                                                     cfe->memspace[i].length - 1);
596                                         if (cfe->memspace[i].hostaddr)
597                                                 printf("@%lx",
598                                                     cfe->memspace[i].hostaddr);
599                                 }
600                         }
601                         if (cfe->maxtwins)
602                                 printf("; maxtwins %d", cfe->maxtwins);
603
604                         printf(";");
605
606                         if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
607                                 printf(" mwait_required");
608                         if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
609                                 printf(" rdybsy_active");
610                         if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
611                                 printf(" wp_active");
612                         if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
613                                 printf(" bvd_active");
614                         if (cfe->flags & PCCARD_CFE_IO8)
615                                 printf(" io8");
616                         if (cfe->flags & PCCARD_CFE_IO16)
617                                 printf(" io16");
618                         if (cfe->flags & PCCARD_CFE_IRQSHARE)
619                                 printf(" irqshare");
620                         if (cfe->flags & PCCARD_CFE_IRQPULSE)
621                                 printf(" irqpulse");
622                         if (cfe->flags & PCCARD_CFE_IRQLEVEL)
623                                 printf(" irqlevel");
624                         if (cfe->flags & PCCARD_CFE_POWERDOWN)
625                                 printf(" powerdown");
626                         if (cfe->flags & PCCARD_CFE_READONLY)
627                                 printf(" readonly");
628                         if (cfe->flags & PCCARD_CFE_AUDIO)
629                                 printf(" audio");
630
631                         printf("\n");
632                 }
633         }
634
635         if (card->error)
636                 device_printf(dev, "%d errors found while parsing CIS\n",
637                     card->error);
638 }
639
640 static int
641 pccard_parse_cis_tuple(const struct pccard_tuple *tuple, void *arg)
642 {
643         /* most of these are educated guesses */
644         static struct pccard_config_entry init_cfe = {
645                 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
646                 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
647         };
648
649         struct cis_state *state = arg;
650
651         switch (tuple->code) {
652         case CISTPL_END:
653                 /* if we've seen a LONGLINK_MFC, and this is the first
654                  * END after it, reset the function list.  
655                  *
656                  * XXX This might also be the right place to start a
657                  * new function, but that assumes that a function
658                  * definition never crosses any longlink, and I'm not
659                  * sure about that.  This is probably safe for MFC
660                  * cards, but what we have now isn't broken, so I'd
661                  * rather not change it.
662                  */
663                 if (state->gotmfc == 1) {
664                         struct pccard_function *pf, *pfnext;
665
666                         for (pf = STAILQ_FIRST(&state->card->pf_head); 
667                              pf != NULL; pf = pfnext) {
668                                 pfnext = STAILQ_NEXT(pf, pf_list);
669                                 free(pf, M_DEVBUF);
670                         }
671
672                         STAILQ_INIT(&state->card->pf_head);
673
674                         state->count = 0;
675                         state->gotmfc = 2;
676                         state->pf = NULL;
677                 }
678                 break;
679         case CISTPL_LONGLINK_MFC:
680                 /*
681                  * this tuple's structure was dealt with in scan_cis.  here,
682                  * record the fact that the MFC tuple was seen, so that
683                  * functions declared before the MFC link can be cleaned
684                  * up.
685                  */
686                 state->gotmfc = 1;
687                 break;
688 #ifdef PCCARDCISDEBUG
689         case CISTPL_DEVICE:
690         case CISTPL_DEVICE_A:
691                 {
692                         u_int reg, dtype, dspeed;
693
694                         reg = pccard_tuple_read_1(tuple, 0);
695                         dtype = reg & PCCARD_DTYPE_MASK;
696                         dspeed = reg & PCCARD_DSPEED_MASK;
697
698                         DPRINTF(("CISTPL_DEVICE%s type=",
699                         (tuple->code == CISTPL_DEVICE) ? "" : "_A"));
700                         switch (dtype) {
701                         case PCCARD_DTYPE_NULL:
702                                 DPRINTF(("null"));
703                                 break;
704                         case PCCARD_DTYPE_ROM:
705                                 DPRINTF(("rom"));
706                                 break;
707                         case PCCARD_DTYPE_OTPROM:
708                                 DPRINTF(("otprom"));
709                                 break;
710                         case PCCARD_DTYPE_EPROM:
711                                 DPRINTF(("eprom"));
712                                 break;
713                         case PCCARD_DTYPE_EEPROM:
714                                 DPRINTF(("eeprom"));
715                                 break;
716                         case PCCARD_DTYPE_FLASH:
717                                 DPRINTF(("flash"));
718                                 break;
719                         case PCCARD_DTYPE_SRAM:
720                                 DPRINTF(("sram"));
721                                 break;
722                         case PCCARD_DTYPE_DRAM:
723                                 DPRINTF(("dram"));
724                                 break;
725                         case PCCARD_DTYPE_FUNCSPEC:
726                                 DPRINTF(("funcspec"));
727                                 break;
728                         case PCCARD_DTYPE_EXTEND:
729                                 DPRINTF(("extend"));
730                                 break;
731                         default:
732                                 DPRINTF(("reserved"));
733                                 break;
734                         }
735                         DPRINTF((" speed="));
736                         switch (dspeed) {
737                         case PCCARD_DSPEED_NULL:
738                                 DPRINTF(("null"));
739                                 break;
740                         case PCCARD_DSPEED_250NS:
741                                 DPRINTF(("250ns"));
742                                 break;
743                         case PCCARD_DSPEED_200NS:
744                                 DPRINTF(("200ns"));
745                                 break;
746                         case PCCARD_DSPEED_150NS:
747                                 DPRINTF(("150ns"));
748                                 break;
749                         case PCCARD_DSPEED_100NS:
750                                 DPRINTF(("100ns"));
751                                 break;
752                         case PCCARD_DSPEED_EXT:
753                                 DPRINTF(("ext"));
754                                 break;
755                         default:
756                                 DPRINTF(("reserved"));
757                                 break;
758                         }
759                 }
760                 DPRINTF(("\n"));
761                 break;
762 #endif
763         case CISTPL_VERS_1:
764                 if (tuple->length < 6) {
765                         DPRINTF(("CISTPL_VERS_1 too short %d\n",
766                             tuple->length));
767                         break;
768                 } {
769                         int start, i, ch, count;
770
771                         state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
772                         state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
773
774                         for (count = 0, start = 0, i = 0;
775                             (count < 4) && ((i + 4) < 256); i++) {
776                                 ch = pccard_tuple_read_1(tuple, 2 + i);
777                                 if (ch == 0xff)
778                                         break;
779                                 state->card->cis1_info_buf[i] = ch;
780                                 if (ch == 0) {
781                                         state->card->cis1_info[count] =
782                                             state->card->cis1_info_buf + start;
783                                         start = i + 1;
784                                         count++;
785                                 }
786                         }
787                         DPRINTF(("CISTPL_VERS_1\n"));
788                 }
789                 break;
790         case CISTPL_MANFID:
791                 if (tuple->length < 4) {
792                         DPRINTF(("CISTPL_MANFID too short %d\n",
793                             tuple->length));
794                         break;
795                 }
796                 state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
797                 state->card->product = pccard_tuple_read_2(tuple, 2);
798                 /*
799                  * This is for xe driver. But not limited to that driver.
800                  * In PC Card Standard,
801                  * Manufacturer ID: 2byte.
802                  * Product ID: typically 2bytes, but there's no limit on its
803                  * size.  prodext is a two byte field, so maybe we should
804                  * also handle the '6' case.  So far no cards have surfaced
805                  * with a length of '6'.
806                  */
807                 if (tuple->length == 5 )
808                         state->card->prodext = pccard_tuple_read_1(tuple, 4);
809                 DPRINTF(("CISTPL_MANFID\n"));
810                 break;
811         case CISTPL_FUNCID:
812                 if (tuple->length < 1) {
813                         DPRINTF(("CISTPL_FUNCID too short %d\n",
814                             tuple->length));
815                         break;
816                 }
817                 if ((state->pf == NULL) || (state->gotmfc == 2)) {
818                         state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
819                             M_NOWAIT | M_ZERO);
820                         state->pf->number = state->count++;
821                         state->pf->last_config_index = -1;
822                         STAILQ_INIT(&state->pf->cfe_head);
823
824                         STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
825                             pf_list);
826                 }
827                 state->pf->function = pccard_tuple_read_1(tuple, 0);
828
829                 DPRINTF(("CISTPL_FUNCID\n"));
830                 break;
831         case CISTPL_FUNCE:
832                 if (state->pf == NULL || state->pf->function <= 0) {
833                         DPRINTF(("CISTPL_FUNCE is not followed by "
834                                 "valid CISTPL_FUNCID\n"));
835                         break;
836                 }
837                 if (tuple->length >= 2)
838                         decode_funce(tuple, state->pf);
839                 DPRINTF(("CISTPL_FUNCE\n"));
840                 break;
841         case CISTPL_CONFIG:
842                 if (tuple->length < 3) {
843                         DPRINTF(("CISTPL_CONFIG too short %d\n",
844                             tuple->length));
845                         break;
846                 } {
847                         u_int reg, rasz, rmsz, rfsz;
848                         int i;
849
850                         reg = pccard_tuple_read_1(tuple, 0);
851                         rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
852                             PCCARD_TPCC_RASZ_SHIFT);
853                         rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
854                             PCCARD_TPCC_RMSZ_SHIFT);
855                         rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
856                             PCCARD_TPCC_RFSZ_SHIFT);
857
858                         if (tuple->length < (rasz + rmsz + rfsz)) {
859                                 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
860                                     "short %d\n", rasz, rmsz, rfsz,
861                                     tuple->length));
862                                 break;
863                         }
864                         if (state->pf == NULL) {
865                                 state->pf = malloc(sizeof(*state->pf),
866                                     M_DEVBUF, M_NOWAIT | M_ZERO);
867                                 state->pf->number = state->count++;
868                                 state->pf->last_config_index = -1;
869                                 STAILQ_INIT(&state->pf->cfe_head);
870
871                                 STAILQ_INSERT_TAIL(&state->card->pf_head,
872                                     state->pf, pf_list);
873
874                                 state->pf->function = PCCARD_FUNCTION_UNSPEC;
875                         }
876                         state->pf->last_config_index =
877                             pccard_tuple_read_1(tuple, 1);
878
879                         state->pf->ccr_base = 0;
880                         for (i = 0; i < rasz; i++)
881                                 state->pf->ccr_base |=
882                                     ((pccard_tuple_read_1(tuple, 2 + i)) <<
883                                     (i * 8));
884
885                         state->pf->ccr_mask = 0;
886                         for (i = 0; i < rmsz; i++)
887                                 state->pf->ccr_mask |=
888                                     ((pccard_tuple_read_1(tuple,
889                                     2 + rasz + i)) << (i * 8));
890
891                         /* skip the reserved area and subtuples */
892
893                         /* reset the default cfe for each cfe list */
894                         state->temp_cfe = init_cfe;
895                         state->default_cfe = &state->temp_cfe;
896                 }
897                 DPRINTF(("CISTPL_CONFIG\n"));
898                 break;
899         case CISTPL_CFTABLE_ENTRY:
900                 {
901                         int idx, i, j;
902                         u_int reg, reg2;
903                         u_int intface, def, num;
904                         u_int power, timing, iospace, irq, memspace, misc;
905                         struct pccard_config_entry *cfe;
906
907                         idx = 0;
908
909                         reg = pccard_tuple_read_1(tuple, idx);
910                         idx++;
911                         intface = reg & PCCARD_TPCE_INDX_INTFACE;
912                         def = reg & PCCARD_TPCE_INDX_DEFAULT;
913                         num = reg & PCCARD_TPCE_INDX_NUM_MASK;
914
915                         /*
916                          * this is a little messy.  Some cards have only a
917                          * cfentry with the default bit set.  So, as we go
918                          * through the list, we add new indexes to the queue,
919                          * and keep a pointer to the last one with the
920                          * default bit set.  if we see a record with the same
921                          * index, as the default, we stash the default and
922                          * replace the queue entry. otherwise, we just add
923                          * new entries to the queue, pointing the default ptr
924                          * at them if the default bit is set.  if we get to
925                          * the end with the default pointer pointing at a
926                          * record which hasn't had a matching index, that's
927                          * ok; it just becomes a cfentry like any other.
928                          */
929
930                         /*
931                          * if the index in the cis differs from the default
932                          * cis, create new entry in the queue and start it
933                          * with the current default
934                          */
935                         if (num != state->default_cfe->number) {
936                                 cfe = (struct pccard_config_entry *)
937                                     malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
938                                 if (cfe == NULL) {
939                                         DPRINTF(("no memory for config entry\n"));
940                                         goto abort_cfe;
941                                 }
942                                 *cfe = *state->default_cfe;
943
944                                 STAILQ_INSERT_TAIL(&state->pf->cfe_head,
945                                     cfe, cfe_list);
946
947                                 cfe->number = num;
948
949                                 /*
950                                  * if the default bit is set in the cis, then
951                                  * point the new default at whatever is being
952                                  * filled in
953                                  */
954                                 if (def)
955                                         state->default_cfe = cfe;
956                         } else {
957                                 /*
958                                  * the cis index matches the default index,
959                                  * fill in the default cfentry.  It is
960                                  * assumed that the cfdefault index is in the
961                                  * queue.  For it to be otherwise, the cis
962                                  * index would have to be -1 (initial
963                                  * condition) which is not possible, or there
964                                  * would have to be a preceding cis entry
965                                  * which had the same cis index and had the
966                                  * default bit unset. Neither condition
967                                  * should happen.  If it does, this cfentry
968                                  * is lost (written into temp space), which
969                                  * is an acceptable failure mode.
970                                  */
971
972                                 cfe = state->default_cfe;
973
974                                 /*
975                                  * if the cis entry does not have the default
976                                  * bit set, copy the default out of the way
977                                  * first.
978                                  */
979                                 if (!def) {
980                                         state->temp_cfe = *state->default_cfe;
981                                         state->default_cfe = &state->temp_cfe;
982                                 }
983                         }
984
985                         if (intface) {
986                                 reg = pccard_tuple_read_1(tuple, idx);
987                                 idx++;
988                                 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
989                                     | PCCARD_CFE_RDYBSY_ACTIVE
990                                     | PCCARD_CFE_WP_ACTIVE
991                                     | PCCARD_CFE_BVD_ACTIVE);
992                                 if (reg & PCCARD_TPCE_IF_MWAIT)
993                                         cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
994                                 if (reg & PCCARD_TPCE_IF_RDYBSY)
995                                         cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
996                                 if (reg & PCCARD_TPCE_IF_WP)
997                                         cfe->flags |= PCCARD_CFE_WP_ACTIVE;
998                                 if (reg & PCCARD_TPCE_IF_BVD)
999                                         cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
1000                                 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
1001                         }
1002                         reg = pccard_tuple_read_1(tuple, idx);
1003                         idx++;
1004
1005                         power = reg & PCCARD_TPCE_FS_POWER_MASK;
1006                         timing = reg & PCCARD_TPCE_FS_TIMING;
1007                         iospace = reg & PCCARD_TPCE_FS_IOSPACE;
1008                         irq = reg & PCCARD_TPCE_FS_IRQ;
1009                         memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
1010                         misc = reg & PCCARD_TPCE_FS_MISC;
1011
1012                         if (power) {
1013                                 /* skip over power, don't save */
1014                                 /* for each parameter selection byte */
1015                                 for (i = 0; i < power; i++) {
1016                                         reg = pccard_tuple_read_1(tuple, idx);
1017                                         idx++;
1018                                         /* for each bit */
1019                                         for (j = 0; j < 7; j++) {
1020                                                 /* if the bit is set */
1021                                                 if ((reg >> j) & 0x01) {
1022                                                         /* skip over bytes */
1023                                                         do {
1024                                                                 reg2 = pccard_tuple_read_1(tuple, idx);
1025                                                                 idx++;
1026                                                                 /*
1027                                                                  * until
1028                                                                  * non-extensi
1029                                                                  * on byte
1030                                                                  */
1031                                                         } while (reg2 & 0x80);
1032                                                 }
1033                                         }
1034                                 }
1035                         }
1036                         if (timing) {
1037                                 /* skip over timing, don't save */
1038                                 reg = pccard_tuple_read_1(tuple, idx);
1039                                 idx++;
1040
1041                                 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1042                                     PCCARD_TPCE_TD_RESERVED_MASK)
1043                                         idx++;
1044                                 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1045                                     PCCARD_TPCE_TD_RDYBSY_MASK)
1046                                         idx++;
1047                                 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1048                                     PCCARD_TPCE_TD_WAIT_MASK)
1049                                         idx++;
1050                         }
1051                         if (iospace) {
1052                                 if (tuple->length <= idx) {
1053                                         DPRINTF(("ran out of space before TCPE_IO\n"));
1054                                         goto abort_cfe;
1055                                 }
1056
1057                                 reg = pccard_tuple_read_1(tuple, idx);
1058                                 idx++;
1059                                 cfe->flags &=
1060                                     ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1061                                 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1062                                         cfe->flags |= PCCARD_CFE_IO8;
1063                                 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1064                                         cfe->flags |= PCCARD_CFE_IO16;
1065                                 cfe->iomask =
1066                                     reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1067
1068                                 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1069                                         reg = pccard_tuple_read_1(tuple, idx);
1070                                         idx++;
1071
1072                                         cfe->num_iospace = 1 + (reg &
1073                                             PCCARD_TPCE_IO_RANGE_COUNT);
1074
1075                                         if (cfe->num_iospace >
1076                                             (sizeof(cfe->iospace) /
1077                                              sizeof(cfe->iospace[0]))) {
1078                                                 DPRINTF(("too many io "
1079                                                     "spaces %d",
1080                                                     cfe->num_iospace));
1081                                                 state->card->error++;
1082                                                 break;
1083                                         }
1084                                         for (i = 0; i < cfe->num_iospace; i++) {
1085                                                 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1086                                                 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1087                                                         cfe->iospace[i].start =
1088                                                                 pccard_tuple_read_1(tuple, idx);
1089                                                         idx++;
1090                                                         break;
1091                                                 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1092                                                         cfe->iospace[i].start =
1093                                                                 pccard_tuple_read_2(tuple, idx);
1094                                                         idx += 2;
1095                                                         break;
1096                                                 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1097                                                         cfe->iospace[i].start =
1098                                                                 pccard_tuple_read_4(tuple, idx);
1099                                                         idx += 4;
1100                                                         break;
1101                                                 }
1102                                                 switch (reg &
1103                                                         PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1104                                                 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1105                                                         cfe->iospace[i].length =
1106                                                                 pccard_tuple_read_1(tuple, idx);
1107                                                         idx++;
1108                                                         break;
1109                                                 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1110                                                         cfe->iospace[i].length =
1111                                                                 pccard_tuple_read_2(tuple, idx);
1112                                                         idx += 2;
1113                                                         break;
1114                                                 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1115                                                         cfe->iospace[i].length =
1116                                                                 pccard_tuple_read_4(tuple, idx);
1117                                                         idx += 4;
1118                                                         break;
1119                                                 }
1120                                                 cfe->iospace[i].length++;
1121                                         }
1122                                 } else {
1123                                         cfe->num_iospace = 1;
1124                                         cfe->iospace[0].start = 0;
1125                                         cfe->iospace[0].length =
1126                                             (1 << cfe->iomask);
1127                                 }
1128                         }
1129                         if (irq) {
1130                                 if (tuple->length <= idx) {
1131                                         DPRINTF(("ran out of space before TCPE_IR\n"));
1132                                         goto abort_cfe;
1133                                 }
1134
1135                                 reg = pccard_tuple_read_1(tuple, idx);
1136                                 idx++;
1137                                 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1138                                     | PCCARD_CFE_IRQPULSE
1139                                     | PCCARD_CFE_IRQLEVEL);
1140                                 if (reg & PCCARD_TPCE_IR_SHARE)
1141                                         cfe->flags |= PCCARD_CFE_IRQSHARE;
1142                                 if (reg & PCCARD_TPCE_IR_PULSE)
1143                                         cfe->flags |= PCCARD_CFE_IRQPULSE;
1144                                 if (reg & PCCARD_TPCE_IR_LEVEL)
1145                                         cfe->flags |= PCCARD_CFE_IRQLEVEL;
1146
1147                                 if (reg & PCCARD_TPCE_IR_HASMASK) {
1148                                         /*
1149                                          * it's legal to ignore the
1150                                          * special-interrupt bits, so I will
1151                                          */
1152
1153                                         cfe->irqmask =
1154                                             pccard_tuple_read_2(tuple, idx);
1155                                         idx += 2;
1156                                 } else {
1157                                         cfe->irqmask =
1158                                             (1 << (reg & PCCARD_TPCE_IR_IRQ));
1159                                 }
1160                         }
1161                         if (memspace) {
1162                                 if (tuple->length <= idx) {
1163                                         DPRINTF(("ran out of space before TCPE_MS\n"));
1164                                         goto abort_cfe;
1165                                 }
1166
1167                                 if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
1168                                         cfe->num_memspace = 1;
1169                                         cfe->memspace[0].length = 256 *
1170                                             pccard_tuple_read_2(tuple, idx);
1171                                         idx += 2;
1172                                         cfe->memspace[0].cardaddr = 0;
1173                                         cfe->memspace[0].hostaddr = 0;
1174                                 } else if (memspace ==
1175                                     PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
1176                                         cfe->num_memspace = 1;
1177                                         cfe->memspace[0].length = 256 *
1178                                             pccard_tuple_read_2(tuple, idx);
1179                                         idx += 2;
1180                                         cfe->memspace[0].cardaddr = 256 *
1181                                             pccard_tuple_read_2(tuple, idx);
1182                                         idx += 2;
1183                                         cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1184                                 } else {
1185                                         int lengthsize;
1186                                         int cardaddrsize;
1187                                         int hostaddrsize;
1188
1189                                         reg = pccard_tuple_read_1(tuple, idx);
1190                                         idx++;
1191
1192                                         cfe->num_memspace = (reg &
1193                                             PCCARD_TPCE_MS_COUNT) + 1;
1194
1195                                         if (cfe->num_memspace >
1196                                             (sizeof(cfe->memspace) /
1197                                              sizeof(cfe->memspace[0]))) {
1198                                                 DPRINTF(("too many mem "
1199                                                     "spaces %d",
1200                                                     cfe->num_memspace));
1201                                                 state->card->error++;
1202                                                 break;
1203                                         }
1204                                         lengthsize =
1205                                                 ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
1206                                                  PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
1207                                         cardaddrsize =
1208                                                 ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
1209                                                  PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
1210                                         hostaddrsize =
1211                                                 (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1212
1213                                         if (lengthsize == 0) {
1214                                                 DPRINTF(("cfe memspace "
1215                                                     "lengthsize == 0"));
1216                                                 state->card->error++;
1217                                         }
1218                                         for (i = 0; i < cfe->num_memspace; i++) {
1219                                                 if (lengthsize) {
1220                                                         cfe->memspace[i].length =
1221                                                                 256 * pccard_tuple_read_n(tuple, lengthsize,
1222                                                                        idx);
1223                                                         idx += lengthsize;
1224                                                 } else {
1225                                                         cfe->memspace[i].length = 0;
1226                                                 }
1227                                                 if (cfe->memspace[i].length == 0) {
1228                                                         DPRINTF(("cfe->memspace[%d].length == 0",
1229                                                                  i));
1230                                                         state->card->error++;
1231                                                 }
1232                                                 if (cardaddrsize) {
1233                                                         cfe->memspace[i].cardaddr =
1234                                                                 256 * pccard_tuple_read_n(tuple, cardaddrsize,
1235                                                                        idx);
1236                                                         idx += cardaddrsize;
1237                                                 } else {
1238                                                         cfe->memspace[i].cardaddr = 0;
1239                                                 }
1240                                                 if (hostaddrsize) {
1241                                                         cfe->memspace[i].hostaddr =
1242                                                                 256 * pccard_tuple_read_n(tuple, hostaddrsize,
1243                                                                        idx);
1244                                                         idx += hostaddrsize;
1245                                                 } else {
1246                                                         cfe->memspace[i].hostaddr = 0;
1247                                                 }
1248                                         }
1249                                 }
1250                         } else
1251                                 cfe->num_memspace = 0;
1252                         if (misc) {
1253                                 if (tuple->length <= idx) {
1254                                         DPRINTF(("ran out of space before TCPE_MI\n"));
1255                                         goto abort_cfe;
1256                                 }
1257
1258                                 reg = pccard_tuple_read_1(tuple, idx);
1259                                 idx++;
1260                                 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1261                                     | PCCARD_CFE_READONLY
1262                                     | PCCARD_CFE_AUDIO);
1263                                 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1264                                         cfe->flags |= PCCARD_CFE_POWERDOWN;
1265                                 if (reg & PCCARD_TPCE_MI_READONLY)
1266                                         cfe->flags |= PCCARD_CFE_READONLY;
1267                                 if (reg & PCCARD_TPCE_MI_AUDIO)
1268                                         cfe->flags |= PCCARD_CFE_AUDIO;
1269                                 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1270
1271                                 while (reg & PCCARD_TPCE_MI_EXT) {
1272                                         reg = pccard_tuple_read_1(tuple, idx);
1273                                         idx++;
1274                                 }
1275                         }
1276                         /* skip all the subtuples */
1277                 }
1278
1279         abort_cfe:
1280                 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1281                 break;
1282         default:
1283                 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1284                 break;
1285         }
1286
1287         return (0);
1288 }
1289
1290 static int
1291 decode_funce(const struct pccard_tuple *tuple, struct pccard_function *pf)
1292 {
1293         int i;
1294         int len;
1295         int type = pccard_tuple_read_1(tuple, 0);
1296
1297         switch (pf->function) {
1298         case PCCARD_FUNCTION_DISK:
1299                 if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1300                         pf->pf_funce_disk_interface
1301                                 = pccard_tuple_read_1(tuple, 1);
1302                 }
1303                 break;
1304         case PCCARD_FUNCTION_NETWORK:
1305                 if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
1306                         len = pccard_tuple_read_1(tuple, 1);
1307                         if (tuple->length < 2 + len || len > 8) {
1308                                 /* tuple length not enough or nid too long */
1309                                 break;
1310                         }
1311                         for (i = 0; i < len; i++) {
1312                                 pf->pf_funce_lan_nid[i]
1313                                         = pccard_tuple_read_1(tuple, i + 2);
1314                         }
1315                         pf->pf_funce_lan_nidlen = len;
1316                 }
1317                 break;
1318         default:
1319                 break;
1320         }
1321         return 0;
1322 }