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