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