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