pcmcia_cis.c revision 1.42
1/*	$NetBSD: pcmcia_cis.c,v 1.42 2006/04/06 18:06:43 rpaulo Exp $	*/
2
3/*
4 * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 *    must display the following acknowledgement:
16 *	This product includes software developed by Marc Horowitz.
17 * 4. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: pcmcia_cis.c,v 1.42 2006/04/06 18:06:43 rpaulo Exp $");
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/device.h>
38#include <sys/malloc.h>
39
40#include <dev/pcmcia/pcmciareg.h>
41#include <dev/pcmcia/pcmciachip.h>
42#include <dev/pcmcia/pcmciavar.h>
43
44#ifdef PCMCIACISDEBUG
45int	pcmciacis_debug = 0;
46#define	DPRINTF(arg) if (pcmciacis_debug) printf arg
47#else
48#define	DPRINTF(arg)
49#endif
50
51#define	PCMCIA_CIS_SIZE		1024
52
53struct cis_state {
54	int	count;
55	int	gotmfc;
56	struct pcmcia_config_entry temp_cfe;
57	struct pcmcia_config_entry *default_cfe;
58	struct pcmcia_card *card;
59	struct pcmcia_function *pf;
60};
61
62int	pcmcia_parse_cis_tuple(struct pcmcia_tuple *, void *);
63static int decode_funce(struct pcmcia_tuple *, struct pcmcia_function *);
64static void create_pf(struct cis_state *);
65
66
67static void
68create_pf(struct cis_state *state)
69{
70	state->pf = malloc(sizeof(*state->pf), M_DEVBUF, M_NOWAIT|M_ZERO);
71	state->pf->number = state->count++;
72	state->pf->last_config_index = -1;
73	SIMPLEQ_INIT(&state->pf->cfe_head);
74	SIMPLEQ_INSERT_TAIL(&state->card->pf_head, state->pf, pf_list);
75}
76
77void
78pcmcia_free_pf(struct pcmcia_function_head *pfhead)
79{
80	struct pcmcia_function *pf, *npf;
81	struct pcmcia_config_entry *cfe, *ncfe;
82
83	for (pf = SIMPLEQ_FIRST(pfhead); pf != NULL; pf = npf) {
84		npf = SIMPLEQ_NEXT(pf, pf_list);
85		for (cfe = SIMPLEQ_FIRST(&pf->cfe_head); cfe != NULL;
86		    cfe = ncfe) {
87			ncfe = SIMPLEQ_NEXT(cfe, cfe_list);
88			free(cfe, M_DEVBUF);
89		}
90		free(pf, M_DEVBUF);
91	}
92
93	SIMPLEQ_INIT(pfhead);
94}
95
96void
97pcmcia_read_cis(sc)
98	struct pcmcia_softc *sc;
99{
100	struct cis_state state;
101
102	memset(&state, 0, sizeof state);
103
104	state.card = &sc->card;
105
106	state.card->error = 0;
107	state.card->cis1_major = -1;
108	state.card->cis1_minor = -1;
109	state.card->cis1_info[0] = NULL;
110	state.card->cis1_info[1] = NULL;
111	state.card->cis1_info[2] = NULL;
112	state.card->cis1_info[3] = NULL;
113	state.card->manufacturer = PCMCIA_VENDOR_INVALID;
114	state.card->product = PCMCIA_PRODUCT_INVALID;
115	SIMPLEQ_INIT(&state.card->pf_head);
116
117	state.pf = NULL;
118
119	if (pcmcia_scan_cis((struct device *)sc, pcmcia_parse_cis_tuple,
120	    &state) == -1)
121		state.card->error++;
122}
123
124int
125pcmcia_scan_cis(dev, fct, arg)
126	struct device *dev;
127	int (*fct)(struct pcmcia_tuple *, void *);
128	void *arg;
129{
130	struct pcmcia_softc *sc = (struct pcmcia_softc *) dev;
131	pcmcia_chipset_tag_t pct;
132	pcmcia_chipset_handle_t pch;
133	int window;
134	struct pcmcia_mem_handle pcmh;
135	struct pcmcia_tuple tuple;
136	int longlink_present;
137	int longlink_common;
138	u_long longlink_addr;
139	int mfc_count;
140	int mfc_index;
141	struct {
142		int	common;
143		u_long	addr;
144	} mfc[256 / 5];
145	int ret;
146
147	ret = 0;
148
149	pct = sc->pct;
150	pch = sc->pch;
151
152	/* allocate some memory */
153
154	if (pcmcia_chip_mem_alloc(pct, pch, PCMCIA_CIS_SIZE, &pcmh)) {
155#ifdef DIAGNOSTIC
156		printf("%s: can't alloc memory to read attributes\n",
157		    sc->dev.dv_xname);
158#endif
159		return -1;
160	}
161	/* initialize state for the primary tuple chain */
162	if (pcmcia_chip_mem_map(pct, pch, PCMCIA_MEM_ATTR, 0,
163	    PCMCIA_CIS_SIZE, &pcmh, &tuple.ptr, &window)) {
164		pcmcia_chip_mem_free(pct, pch, &pcmh);
165#ifdef DIAGNOSTIC
166		printf("%s: can't map memory to read attributes\n",
167		    sc->dev.dv_xname);
168#endif
169		return -1;
170	}
171	tuple.memt = pcmh.memt;
172	tuple.memh = pcmh.memh;
173
174	DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
175
176	tuple.mult = 2;
177
178	longlink_present = 1;
179	longlink_common = 1;
180	longlink_addr = 0;
181
182	mfc_count = 0;
183	mfc_index = 0;
184
185	DPRINTF(("%s: CIS tuple chain:\n", sc->dev.dv_xname));
186
187	while (1) {
188		DELAY(1000);
189
190		while (1) {
191			/*
192			 * Perform boundary check for insane cards.
193			 * If CIS is too long, simulate CIS end.
194			 * (This check may not be sufficient for
195			 * malicious cards.)
196			 */
197			if (tuple.mult * tuple.ptr >= PCMCIA_CIS_SIZE - 1
198			    - 32 /* ad hoc value */ ) {
199				DPRINTF(("CISTPL_END (too long CIS)\n"));
200				tuple.code = PCMCIA_CISTPL_END;
201				goto cis_end;
202			}
203
204			/* get the tuple code */
205
206			tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr);
207
208			/* two special-case tuples */
209
210			if (tuple.code == PCMCIA_CISTPL_NULL) {
211				DPRINTF((" 00\nCISTPL_NONE\n"));
212				tuple.ptr++;
213				continue;
214			} else if (tuple.code == PCMCIA_CISTPL_END) {
215				DPRINTF((" ff\nCISTPL_END\n"));
216			cis_end:
217				/* Call the function for the END tuple, since
218				   the CIS semantics depend on it */
219				if ((*fct) (&tuple, arg)) {
220					pcmcia_chip_mem_unmap(pct, pch,
221							      window);
222					ret = 1;
223					goto done;
224				}
225				tuple.ptr++;
226				break;
227			}
228
229			/* now all the normal tuples */
230
231			tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1);
232#ifdef PCMCIACISDEBUG
233			/* print the tuple */
234			{
235				int i;
236
237				DPRINTF((" %02x %02x", tuple.code,
238				    tuple.length));
239
240				for (i = 0; i < tuple.length; i++) {
241					DPRINTF((" %02x",
242					    pcmcia_tuple_read_1(&tuple, i)));
243					if ((i % 16) == 13)
244						DPRINTF(("\n"));
245				}
246				if ((i % 16) != 14)
247					DPRINTF(("\n"));
248			}
249#endif
250			switch (tuple.code) {
251			case PCMCIA_CISTPL_LONGLINK_A:
252			case PCMCIA_CISTPL_LONGLINK_C:
253				if (tuple.length < 4) {
254					DPRINTF(("CISTPL_LONGLINK_%s too "
255					    "short %d\n",
256					    longlink_common ? "C" : "A",
257					    tuple.length));
258					break;
259				}
260				longlink_present = 1;
261				longlink_common = (tuple.code ==
262				    PCMCIA_CISTPL_LONGLINK_C) ? 1 : 0;
263				longlink_addr = pcmcia_tuple_read_4(&tuple, 0);
264				DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
265				    longlink_common ? "C" : "A",
266				    longlink_addr));
267				break;
268			case PCMCIA_CISTPL_NO_LINK:
269				longlink_present = 0;
270				DPRINTF(("CISTPL_NO_LINK\n"));
271				break;
272			case PCMCIA_CISTPL_CHECKSUM:
273				if (tuple.length < 5) {
274					DPRINTF(("CISTPL_CHECKSUM too "
275					    "short %d\n", tuple.length));
276					break;
277				} {
278					int16_t offset;
279					u_long addr, length;
280					u_int cksum, sum;
281					int i;
282
283					*((u_int16_t *) & offset) =
284					    pcmcia_tuple_read_2(&tuple, 0);
285					length = pcmcia_tuple_read_2(&tuple, 2);
286					cksum = pcmcia_tuple_read_1(&tuple, 4);
287
288					addr = tuple.ptr + offset;
289
290					DPRINTF(("CISTPL_CHECKSUM addr=%lx "
291					    "len=%lx cksum=%x",
292					    addr, length, cksum));
293
294					/*
295					 * XXX do more work to deal with
296					 * distant regions
297					 */
298					if ((addr >= PCMCIA_CIS_SIZE) ||
299					    ((addr + length) < 0) ||
300					    ((addr + length) >=
301					      PCMCIA_CIS_SIZE)) {
302						DPRINTF((" skipped, "
303						    "too distant\n"));
304						break;
305					}
306					sum = 0;
307					for (i = 0; i < length; i++)
308						sum +=
309						    bus_space_read_1(tuple.memt,
310						    tuple.memh,
311						    addr + tuple.mult * i);
312					if (cksum != (sum & 0xff)) {
313						DPRINTF((" failed sum=%x\n",
314						    sum));
315						printf("%s: CIS checksum "
316						    "failed\n",
317						    sc->dev.dv_xname);
318#if 0
319						/*
320						 * XXX Some working cards have
321						 * XXX bad checksums!!
322						 */
323						ret = -1;
324#endif
325					} else {
326						DPRINTF((" ok\n"));
327					}
328				}
329				break;
330			case PCMCIA_CISTPL_LONGLINK_MFC:
331				if (tuple.length < 1) {
332					DPRINTF(("CISTPL_LONGLINK_MFC too "
333					    "short %d\n", tuple.length));
334					break;
335				}
336				if (((tuple.length - 1) % 5) != 0) {
337					DPRINTF(("CISTPL_LONGLINK_MFC bogus "
338					    "length %d\n", tuple.length));
339					break;
340				}
341				/*
342				 * this is kind of ad hoc, as I don't have
343				 * any real documentation
344				 */
345				{
346					int i, tmp_count;
347
348					/*
349					 * put count into tmp var so that
350					 * if we have to bail (because it's
351					 * a bogus count) it won't be
352					 * remembered for later use.
353					 */
354					tmp_count =
355					    pcmcia_tuple_read_1(&tuple, 0);
356					DPRINTF(("CISTPL_LONGLINK_MFC %d",
357					    tmp_count));
358
359					/*
360					 * make _sure_ it's the right size;
361					 * if too short, it may be a weird
362					 * (unknown/undefined) format
363					 */
364					if (tuple.length != (tmp_count*5 + 1)) {
365						DPRINTF((" bogus length %d\n",
366						    tuple.length));
367						break;
368					}
369
370#ifdef PCMCIACISDEBUG	/* maybe enable all the time? */
371					/*
372					 * sanity check for a programming
373					 * error which is difficult to find
374					 * when debugging.
375					 */
376					if (tmp_count >
377					    howmany(sizeof mfc, sizeof mfc[0]))
378						panic("CISTPL_LONGLINK_MFC mfc "
379						    "count would blow stack");
380#endif
381
382					mfc_count = tmp_count;
383					for (i = 0; i < mfc_count; i++) {
384						mfc[i].common =
385						    (pcmcia_tuple_read_1(&tuple,
386						    1 + 5 * i) ==
387						    PCMCIA_MFC_MEM_COMMON) ?
388						    1 : 0;
389						mfc[i].addr =
390						    pcmcia_tuple_read_4(&tuple,
391						    1 + 5 * i + 1);
392						DPRINTF((" %s:%lx",
393						    mfc[i].common ? "common" :
394						    "attr", mfc[i].addr));
395					}
396					DPRINTF(("\n"));
397				}
398				/*
399				 * for LONGLINK_MFC, fall through to the
400				 * function.  This tuple has structural and
401				 * semantic content.
402				 */
403			default:
404				{
405					if ((*fct) (&tuple, arg)) {
406						pcmcia_chip_mem_unmap(pct,
407						    pch, window);
408						ret = 1;
409						goto done;
410					}
411				}
412				break;
413			}	/* switch */
414			/* skip to the next tuple */
415			tuple.ptr += 2 + tuple.length;
416		}
417
418		/*
419		 * the chain is done.  Clean up and move onto the next one,
420		 * if any.  The loop is here in the case that there is an MFC
421		 * card with no longlink (which defaults to existing, == 0).
422		 * In general, this means that if one pointer fails, it will
423		 * try the next one, instead of just bailing.
424		 */
425
426		while (1) {
427			pcmcia_chip_mem_unmap(pct, pch, window);
428
429			if (longlink_present) {
430				/*
431				 * if the longlink is to attribute memory,
432				 * then it is unindexed.  That is, if the
433				 * link value is 0x100, then the actual
434				 * memory address is 0x200.  This means that
435				 * we need to multiply by 2 before calling
436				 * mem_map, and then divide the resulting ptr
437				 * by 2 after.
438				 */
439
440				if (!longlink_common)
441					longlink_addr *= 2;
442
443				pcmcia_chip_mem_map(pct, pch, longlink_common ?
444				    (PCMCIA_WIDTH_MEM8 | PCMCIA_MEM_COMMON) :
445				    PCMCIA_MEM_ATTR,
446				    longlink_addr, PCMCIA_CIS_SIZE,
447				    &pcmh, &tuple.ptr, &window);
448
449				tuple.memt = pcmh.memt;
450				tuple.memh = pcmh.memh;
451
452				if (!longlink_common)
453					tuple.ptr /= 2;
454
455				DPRINTF(("cis mem map %x\n",
456				    (unsigned int) tuple.memh));
457
458				tuple.mult = longlink_common ? 1 : 2;
459				longlink_present = 0;
460				longlink_common = 1;
461				longlink_addr = 0;
462			} else if (mfc_count && (mfc_index < mfc_count)) {
463				if (!mfc[mfc_index].common)
464					mfc[mfc_index].addr *= 2;
465
466				pcmcia_chip_mem_map(pct, pch,
467				    mfc[mfc_index].common ?
468				    (PCMCIA_WIDTH_MEM8 | PCMCIA_MEM_COMMON) :
469				    PCMCIA_MEM_ATTR,
470				    mfc[mfc_index].addr, PCMCIA_CIS_SIZE,
471				    &pcmh, &tuple.ptr, &window);
472
473				if (!mfc[mfc_index].common)
474					tuple.ptr /= 2;
475
476				DPRINTF(("cis mem map %x\n",
477				    (unsigned int) tuple.memh));
478
479				/* set parse state, and point at the next one */
480
481				tuple.mult = mfc[mfc_index].common ? 1 : 2;
482
483				mfc_index++;
484			} else {
485				goto done;
486			}
487
488			/* make sure that the link is valid */
489			tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr);
490			if (tuple.code != PCMCIA_CISTPL_LINKTARGET) {
491				DPRINTF(("CISTPL_LINKTARGET expected, "
492				    "code %02x observed\n", tuple.code));
493				continue;
494			}
495			tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1);
496			if (tuple.length < 3) {
497				DPRINTF(("CISTPL_LINKTARGET too short %d\n",
498				    tuple.length));
499				continue;
500			}
501			if ((pcmcia_tuple_read_1(&tuple, 0) != 'C') ||
502			    (pcmcia_tuple_read_1(&tuple, 1) != 'I') ||
503			    (pcmcia_tuple_read_1(&tuple, 2) != 'S')) {
504				DPRINTF(("CISTPL_LINKTARGET magic "
505				    "%02x%02x%02x incorrect\n",
506				    pcmcia_tuple_read_1(&tuple, 0),
507				    pcmcia_tuple_read_1(&tuple, 1),
508				    pcmcia_tuple_read_1(&tuple, 2)));
509				continue;
510			}
511			tuple.ptr += 2 + tuple.length;
512
513			break;
514		}
515	}
516
517	pcmcia_chip_mem_unmap(pct, pch, window);
518
519done:
520	/* Last, free the allocated memory block */
521	pcmcia_chip_mem_free(pct, pch, &pcmh);
522
523	return (ret);
524}
525
526/* XXX this is incredibly verbose.  Not sure what trt is */
527
528void
529pcmcia_print_cis(sc)
530	struct pcmcia_softc *sc;
531{
532	struct pcmcia_card *card = &sc->card;
533	struct pcmcia_function *pf;
534	struct pcmcia_config_entry *cfe;
535	int i;
536
537	printf("%s: CIS version ", sc->dev.dv_xname);
538	if (card->cis1_major == 4) {
539		if (card->cis1_minor == 0)
540			printf("PCMCIA 1.0\n");
541		else if (card->cis1_minor == 1)
542			printf("PCMCIA 2.0 or 2.1\n");
543	} else if (card->cis1_major >= 5)
544		printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
545	else
546		printf("unknown (major=%d, minor=%d)\n",
547		    card->cis1_major, card->cis1_minor);
548
549	printf("%s: CIS info: ", sc->dev.dv_xname);
550	for (i = 0; i < 4; i++) {
551		if (card->cis1_info[i] == NULL)
552			break;
553		if (i)
554			printf(", ");
555		printf("%s", card->cis1_info[i]);
556	}
557	printf("\n");
558
559	printf("%s: Manufacturer code 0x%x, product 0x%x\n",
560	       sc->dev.dv_xname, card->manufacturer, card->product);
561
562	SIMPLEQ_FOREACH(pf, &card->pf_head, pf_list) {
563		printf("%s: function %d: ", sc->dev.dv_xname, pf->number);
564
565		switch (pf->function) {
566		case PCMCIA_FUNCTION_UNSPEC:
567			printf("unspecified");
568			break;
569		case PCMCIA_FUNCTION_MULTIFUNCTION:
570			printf("multi-function");
571			break;
572		case PCMCIA_FUNCTION_MEMORY:
573			printf("memory");
574			break;
575		case PCMCIA_FUNCTION_SERIAL:
576			printf("serial port");
577			break;
578		case PCMCIA_FUNCTION_PARALLEL:
579			printf("parallel port");
580			break;
581		case PCMCIA_FUNCTION_DISK:
582			printf("fixed disk");
583			switch (pf->pf_funce_disk_interface) {
584			case PCMCIA_TPLFE_DDI_PCCARD_ATA:
585				printf("(ata)");
586				break;
587			default:
588				break;
589			}
590			break;
591		case PCMCIA_FUNCTION_VIDEO:
592			printf("video adapter");
593			break;
594		case PCMCIA_FUNCTION_NETWORK:
595			printf("network adapter");
596			break;
597		case PCMCIA_FUNCTION_AIMS:
598			printf("auto incrementing mass storage");
599			break;
600		case PCMCIA_FUNCTION_SCSI:
601			printf("SCSI bridge");
602			break;
603		case PCMCIA_FUNCTION_SECURITY:
604			printf("Security services");
605			break;
606		case PCMCIA_FUNCTION_INSTRUMENT:
607			printf("Instrument");
608			break;
609		default:
610			printf("unknown (%d)", pf->function);
611			break;
612		}
613
614		printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask);
615
616		SIMPLEQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
617			printf("%s: function %d, config table entry %d: ",
618			    sc->dev.dv_xname, pf->number, cfe->number);
619
620			switch (cfe->iftype) {
621			case PCMCIA_IFTYPE_MEMORY:
622				printf("memory card");
623				break;
624			case PCMCIA_IFTYPE_IO:
625				printf("I/O card");
626				break;
627			default:
628				printf("card type unknown");
629				break;
630			}
631
632			printf("; irq mask %x", cfe->irqmask);
633
634			if (cfe->num_iospace) {
635				printf("; iomask %lx, iospace", cfe->iomask);
636
637				for (i = 0; i < cfe->num_iospace; i++) {
638					printf(" %lx", cfe->iospace[i].start);
639					if (cfe->iospace[i].length)
640						printf("-%lx",
641						    cfe->iospace[i].start +
642						    cfe->iospace[i].length - 1);
643				}
644			}
645			if (cfe->num_memspace) {
646				printf("; memspace");
647
648				for (i = 0; i < cfe->num_memspace; i++) {
649					printf(" %lx",
650					    cfe->memspace[i].cardaddr);
651					if (cfe->memspace[i].length)
652						printf("-%lx",
653						    cfe->memspace[i].cardaddr +
654						    cfe->memspace[i].length - 1);
655					if (cfe->memspace[i].hostaddr)
656						printf("@%lx",
657						    cfe->memspace[i].hostaddr);
658				}
659			}
660			if (cfe->maxtwins)
661				printf("; maxtwins %d", cfe->maxtwins);
662
663			printf(";");
664
665			if (cfe->flags & PCMCIA_CFE_MWAIT_REQUIRED)
666				printf(" mwait_required");
667			if (cfe->flags & PCMCIA_CFE_RDYBSY_ACTIVE)
668				printf(" rdybsy_active");
669			if (cfe->flags & PCMCIA_CFE_WP_ACTIVE)
670				printf(" wp_active");
671			if (cfe->flags & PCMCIA_CFE_BVD_ACTIVE)
672				printf(" bvd_active");
673			if (cfe->flags & PCMCIA_CFE_IO8)
674				printf(" io8");
675			if (cfe->flags & PCMCIA_CFE_IO16)
676				printf(" io16");
677			if (cfe->flags & PCMCIA_CFE_IRQSHARE)
678				printf(" irqshare");
679			if (cfe->flags & PCMCIA_CFE_IRQPULSE)
680				printf(" irqpulse");
681			if (cfe->flags & PCMCIA_CFE_IRQLEVEL)
682				printf(" irqlevel");
683			if (cfe->flags & PCMCIA_CFE_POWERDOWN)
684				printf(" powerdown");
685			if (cfe->flags & PCMCIA_CFE_READONLY)
686				printf(" readonly");
687			if (cfe->flags & PCMCIA_CFE_AUDIO)
688				printf(" audio");
689
690			printf("\n");
691		}
692	}
693
694	if (card->error)
695		printf("%s: %d errors found while parsing CIS\n",
696		    sc->dev.dv_xname, card->error);
697}
698
699int
700pcmcia_parse_cis_tuple(tuple, arg)
701	struct pcmcia_tuple *tuple;
702	void *arg;
703{
704	/* most of these are educated guesses */
705	static const struct pcmcia_config_entry init_cfe = {
706		-1, PCMCIA_CFE_RDYBSY_ACTIVE | PCMCIA_CFE_WP_ACTIVE |
707		PCMCIA_CFE_BVD_ACTIVE, PCMCIA_IFTYPE_MEMORY,
708	};
709
710	struct cis_state *state = arg;
711
712	switch (tuple->code) {
713	case PCMCIA_CISTPL_END:
714		/* if we've seen a LONGLINK_MFC, and this is the first
715		 * END after it, reset the function list.
716		 *
717		 * XXX This might also be the right place to start a
718		 * new function, but that assumes that a function
719		 * definition never crosses any longlink, and I'm not
720		 * sure about that.  This is probably safe for MFC
721		 * cards, but what we have now isn't broken, so I'd
722		 * rather not change it.
723		 */
724		if (state->gotmfc == 1) {
725			state->gotmfc = 2;
726			state->count = 0;
727			state->pf = NULL;
728
729			pcmcia_free_pf(&state->card->pf_head);
730		}
731		break;
732	case PCMCIA_CISTPL_LONGLINK_MFC:
733		/*
734		 * this tuple's structure was dealt with in scan_cis.  here,
735		 * record the fact that the MFC tuple was seen, so that
736		 * functions declared before the MFC link can be cleaned
737		 * up.
738		 */
739		if (state->gotmfc == 0) {
740			state->gotmfc = 1;
741		} else {
742			DPRINTF(("got LONGLINK_MFC again!"));
743		}
744		break;
745#ifdef PCMCIACISDEBUG
746	case PCMCIA_CISTPL_DEVICE:
747	case PCMCIA_CISTPL_DEVICE_A:
748		{
749			u_int reg, dtype, dspeed;
750
751			reg = pcmcia_tuple_read_1(tuple, 0);
752			dtype = reg & PCMCIA_DTYPE_MASK;
753			dspeed = reg & PCMCIA_DSPEED_MASK;
754
755			DPRINTF(("CISTPL_DEVICE%s type=",
756			(tuple->code == PCMCIA_CISTPL_DEVICE) ? "" : "_A"));
757			switch (dtype) {
758			case PCMCIA_DTYPE_NULL:
759				DPRINTF(("null"));
760				break;
761			case PCMCIA_DTYPE_ROM:
762				DPRINTF(("rom"));
763				break;
764			case PCMCIA_DTYPE_OTPROM:
765				DPRINTF(("otprom"));
766				break;
767			case PCMCIA_DTYPE_EPROM:
768				DPRINTF(("eprom"));
769				break;
770			case PCMCIA_DTYPE_EEPROM:
771				DPRINTF(("eeprom"));
772				break;
773			case PCMCIA_DTYPE_FLASH:
774				DPRINTF(("flash"));
775				break;
776			case PCMCIA_DTYPE_SRAM:
777				DPRINTF(("sram"));
778				break;
779			case PCMCIA_DTYPE_DRAM:
780				DPRINTF(("dram"));
781				break;
782			case PCMCIA_DTYPE_FUNCSPEC:
783				DPRINTF(("funcspec"));
784				break;
785			case PCMCIA_DTYPE_EXTEND:
786				DPRINTF(("extend"));
787				break;
788			default:
789				DPRINTF(("reserved"));
790				break;
791			}
792			DPRINTF((" speed="));
793			switch (dspeed) {
794			case PCMCIA_DSPEED_NULL:
795				DPRINTF(("null"));
796				break;
797			case PCMCIA_DSPEED_250NS:
798				DPRINTF(("250ns"));
799				break;
800			case PCMCIA_DSPEED_200NS:
801				DPRINTF(("200ns"));
802				break;
803			case PCMCIA_DSPEED_150NS:
804				DPRINTF(("150ns"));
805				break;
806			case PCMCIA_DSPEED_100NS:
807				DPRINTF(("100ns"));
808				break;
809			case PCMCIA_DSPEED_EXT:
810				DPRINTF(("ext"));
811				break;
812			default:
813				DPRINTF(("reserved"));
814				break;
815			}
816		}
817		DPRINTF(("\n"));
818		break;
819#endif
820	case PCMCIA_CISTPL_VERS_1:
821		if (tuple->length < 6) {
822			DPRINTF(("CISTPL_VERS_1 too short %d\n",
823			    tuple->length));
824			break;
825		} {
826			int start, i, ch, count;
827
828			state->card->cis1_major = pcmcia_tuple_read_1(tuple, 0);
829			state->card->cis1_minor = pcmcia_tuple_read_1(tuple, 1);
830
831			for (count = 0, start = 0, i = 0;
832			    (count < 4) && ((i + 4) < 256); i++) {
833				ch = pcmcia_tuple_read_1(tuple, 2 + i);
834				if (ch == 0xff) {
835					if (i > start) {
836						state->card->cis1_info_buf[i] = 0;
837						state->card->cis1_info[count] =
838						    state->card->cis1_info_buf + start;
839					}
840					break;
841				}
842				state->card->cis1_info_buf[i] = ch;
843				if (ch == 0) {
844					state->card->cis1_info[count] =
845					    state->card->cis1_info_buf + start;
846					start = i + 1;
847					count++;
848				}
849			}
850			DPRINTF(("CISTPL_VERS_1\n"));
851		}
852		break;
853	case PCMCIA_CISTPL_MANFID:
854		if (tuple->length < 4) {
855			DPRINTF(("CISTPL_MANFID too short %d\n",
856			    tuple->length));
857			break;
858		}
859		state->card->manufacturer = pcmcia_tuple_read_2(tuple, 0);
860		state->card->product = pcmcia_tuple_read_2(tuple, 2);
861		DPRINTF(("CISTPL_MANFID\n"));
862		break;
863	case PCMCIA_CISTPL_FUNCID:
864		if (tuple->length < 1) {
865			DPRINTF(("CISTPL_FUNCID too short %d\n",
866			    tuple->length));
867			break;
868		}
869		if (state->pf) {
870			if (state->pf->function == PCMCIA_FUNCTION_UNSPEC) {
871				/*
872				 * This looks like a opportunistic function
873				 * created by a CONFIG tuple.  Just keep it.
874				 */
875			} else {
876				/*
877				 * A function is being defined, end it.
878				 */
879				state->pf = NULL;
880			}
881		}
882		if (state->pf == NULL)
883			create_pf(state);
884		state->pf->function = pcmcia_tuple_read_1(tuple, 0);
885
886		DPRINTF(("CISTPL_FUNCID\n"));
887		break;
888	case PCMCIA_CISTPL_FUNCE:
889		if (state->pf == NULL || state->pf->function <= 0) {
890			DPRINTF(("CISTPL_FUNCE is not followed by "
891			    "valid CISTPL_FUNCID\n"));
892			break;
893		}
894		if (tuple->length >= 2) {
895			decode_funce(tuple, state->pf);
896		}
897		break;
898	case PCMCIA_CISTPL_CONFIG:
899		if (tuple->length < 3) {
900			DPRINTF(("CISTPL_CONFIG too short %d\n",
901			    tuple->length));
902			break;
903		} {
904			u_int reg, rasz, rmsz, rfsz;
905			int i;
906
907			reg = pcmcia_tuple_read_1(tuple, 0);
908			rasz = 1 + ((reg & PCMCIA_TPCC_RASZ_MASK) >>
909			    PCMCIA_TPCC_RASZ_SHIFT);
910			rmsz = 1 + ((reg & PCMCIA_TPCC_RMSZ_MASK) >>
911			    PCMCIA_TPCC_RMSZ_SHIFT);
912			rfsz = ((reg & PCMCIA_TPCC_RFSZ_MASK) >>
913			    PCMCIA_TPCC_RFSZ_SHIFT);
914
915			if (tuple->length < (rasz + rmsz + rfsz)) {
916				DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
917				    "short %d\n", rasz, rmsz, rfsz,
918				    tuple->length));
919				break;
920			}
921			if (state->pf == NULL) {
922				create_pf(state);
923				state->pf->function = PCMCIA_FUNCTION_UNSPEC;
924			}
925			state->pf->last_config_index =
926			    pcmcia_tuple_read_1(tuple, 1);
927
928			state->pf->ccr_base = 0;
929			for (i = 0; i < rasz; i++)
930				state->pf->ccr_base |=
931				    ((pcmcia_tuple_read_1(tuple, 2 + i)) <<
932				    (i * 8));
933
934			state->pf->ccr_mask = 0;
935			for (i = 0; i < rmsz; i++)
936				state->pf->ccr_mask |=
937				    ((pcmcia_tuple_read_1(tuple,
938				    2 + rasz + i)) << (i * 8));
939
940			/* skip the reserved area and subtuples */
941
942			/* reset the default cfe for each cfe list */
943			state->temp_cfe = init_cfe;
944			state->default_cfe = &state->temp_cfe;
945		}
946		DPRINTF(("CISTPL_CONFIG\n"));
947		break;
948	case PCMCIA_CISTPL_CFTABLE_ENTRY:
949		{
950			int idx, i, j;
951			u_int reg, reg2;
952			u_int intface, def, num;
953			u_int power, timing, iospace, irq, memspace, misc;
954			struct pcmcia_config_entry *cfe;
955
956			idx = 0;
957
958			reg = pcmcia_tuple_read_1(tuple, idx);
959			idx++;
960			intface = reg & PCMCIA_TPCE_INDX_INTFACE;
961			def = reg & PCMCIA_TPCE_INDX_DEFAULT;
962			num = reg & PCMCIA_TPCE_INDX_NUM_MASK;
963
964			/*
965			 * this is a little messy.  Some cards have only a
966			 * cfentry with the default bit set.  So, as we go
967			 * through the list, we add new indexes to the queue,
968			 * and keep a pointer to the last one with the
969			 * default bit set.  if we see a record with the same
970			 * index, as the default, we stash the default and
971			 * replace the queue entry. otherwise, we just add
972			 * new entries to the queue, pointing the default ptr
973			 * at them if the default bit is set.  if we get to
974			 * the end with the default pointer pointing at a
975			 * record which hasn't had a matching index, that's
976			 * ok; it just becomes a cfentry like any other.
977			 */
978
979			/*
980			 * if the index in the cis differs from the default
981			 * cis, create new entry in the queue and start it
982			 * with the current default
983			 */
984			if (state->default_cfe == NULL) {
985				DPRINTF(("CISTPL_CFTABLE_ENTRY with no "
986				    "default\n"));
987				break;
988			}
989			if (num != state->default_cfe->number) {
990				cfe = (struct pcmcia_config_entry *)
991				    malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
992
993				*cfe = *state->default_cfe;
994
995				SIMPLEQ_INSERT_TAIL(&state->pf->cfe_head,
996				    cfe, cfe_list);
997
998				cfe->number = num;
999
1000				/*
1001				 * if the default bit is set in the cis, then
1002				 * point the new default at whatever is being
1003				 * filled in
1004				 */
1005				if (def)
1006					state->default_cfe = cfe;
1007			} else {
1008				/*
1009				 * the cis index matches the default index,
1010				 * fill in the default cfentry.  It is
1011				 * assumed that the cfdefault index is in the
1012				 * queue.  For it to be otherwise, the cis
1013				 * index would have to be -1 (initial
1014				 * condition) which is not possible, or there
1015				 * would have to be a preceding cis entry
1016				 * which had the same cis index and had the
1017				 * default bit unset. Neither condition
1018				 * should happen.  If it does, this cfentry
1019				 * is lost (written into temp space), which
1020				 * is an acceptable failure mode.
1021				 */
1022
1023				cfe = state->default_cfe;
1024
1025				/*
1026				 * if the cis entry does not have the default
1027				 * bit set, copy the default out of the way
1028				 * first.
1029				 */
1030				if (!def) {
1031					state->temp_cfe = *state->default_cfe;
1032					state->default_cfe = &state->temp_cfe;
1033				}
1034			}
1035
1036			if (intface) {
1037				reg = pcmcia_tuple_read_1(tuple, idx);
1038				idx++;
1039				cfe->flags &= ~(PCMCIA_CFE_MWAIT_REQUIRED
1040				    | PCMCIA_CFE_RDYBSY_ACTIVE
1041				    | PCMCIA_CFE_WP_ACTIVE
1042				    | PCMCIA_CFE_BVD_ACTIVE);
1043				if (reg & PCMCIA_TPCE_IF_MWAIT)
1044					cfe->flags |= PCMCIA_CFE_MWAIT_REQUIRED;
1045				if (reg & PCMCIA_TPCE_IF_RDYBSY)
1046					cfe->flags |= PCMCIA_CFE_RDYBSY_ACTIVE;
1047				if (reg & PCMCIA_TPCE_IF_WP)
1048					cfe->flags |= PCMCIA_CFE_WP_ACTIVE;
1049				if (reg & PCMCIA_TPCE_IF_BVD)
1050					cfe->flags |= PCMCIA_CFE_BVD_ACTIVE;
1051				cfe->iftype = reg & PCMCIA_TPCE_IF_IFTYPE;
1052			}
1053			reg = pcmcia_tuple_read_1(tuple, idx);
1054			idx++;
1055
1056			power = reg & PCMCIA_TPCE_FS_POWER_MASK;
1057			timing = reg & PCMCIA_TPCE_FS_TIMING;
1058			iospace = reg & PCMCIA_TPCE_FS_IOSPACE;
1059			irq = reg & PCMCIA_TPCE_FS_IRQ;
1060			memspace = reg & PCMCIA_TPCE_FS_MEMSPACE_MASK;
1061			misc = reg & PCMCIA_TPCE_FS_MISC;
1062
1063			if (power) {
1064				/* skip over power, don't save */
1065				/* for each parameter selection byte */
1066				for (i = 0; i < power; i++) {
1067					reg = pcmcia_tuple_read_1(tuple, idx);
1068					idx++;
1069					/* for each bit */
1070					for (j = 0; j < 7; j++) {
1071						/* if the bit is set */
1072						if ((reg >> j) & 0x01) {
1073							/* skip over bytes */
1074							do {
1075								reg2 = pcmcia_tuple_read_1(tuple, idx);
1076								idx++;
1077								/*
1078								 * until
1079								 * non-
1080								 * extension
1081								 * byte
1082								 */
1083							} while (reg2 & 0x80);
1084						}
1085					}
1086				}
1087			}
1088			if (timing) {
1089				/* skip over timing, don't save */
1090				reg = pcmcia_tuple_read_1(tuple, idx);
1091				idx++;
1092
1093				if ((reg & PCMCIA_TPCE_TD_RESERVED_MASK) !=
1094				    PCMCIA_TPCE_TD_RESERVED_MASK)
1095					idx++;
1096				if ((reg & PCMCIA_TPCE_TD_RDYBSY_MASK) !=
1097				    PCMCIA_TPCE_TD_RDYBSY_MASK)
1098					idx++;
1099				if ((reg & PCMCIA_TPCE_TD_WAIT_MASK) !=
1100				    PCMCIA_TPCE_TD_WAIT_MASK)
1101					idx++;
1102			}
1103			if (iospace) {
1104				if (tuple->length <= idx) {
1105					DPRINTF(("ran out of space before TCPE_IO\n"));
1106					goto abort_cfe;
1107				}
1108
1109				reg = pcmcia_tuple_read_1(tuple, idx);
1110				idx++;
1111
1112				cfe->flags &=
1113				    ~(PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16);
1114				if (reg & PCMCIA_TPCE_IO_BUSWIDTH_8BIT)
1115					cfe->flags |= PCMCIA_CFE_IO8;
1116				if (reg & PCMCIA_TPCE_IO_BUSWIDTH_16BIT)
1117					cfe->flags |= PCMCIA_CFE_IO16;
1118				cfe->iomask =
1119				    reg & PCMCIA_TPCE_IO_IOADDRLINES_MASK;
1120
1121				if (reg & PCMCIA_TPCE_IO_HASRANGE) {
1122					reg = pcmcia_tuple_read_1(tuple, idx);
1123					idx++;
1124
1125					cfe->num_iospace = 1 + (reg &
1126					    PCMCIA_TPCE_IO_RANGE_COUNT);
1127
1128					if (cfe->num_iospace >
1129					    (sizeof(cfe->iospace) /
1130					     sizeof(cfe->iospace[0]))) {
1131						DPRINTF(("too many io "
1132						    "spaces %d",
1133						    cfe->num_iospace));
1134						state->card->error++;
1135						break;
1136					}
1137					for (i = 0; i < cfe->num_iospace; i++) {
1138						switch (reg & PCMCIA_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1139						case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_NONE:
1140							cfe->iospace[i].start =
1141							    0;
1142							break;
1143						case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_ONE:
1144							cfe->iospace[i].start =
1145								pcmcia_tuple_read_1(tuple, idx);
1146							idx++;
1147							break;
1148						case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_TWO:
1149							cfe->iospace[i].start =
1150								pcmcia_tuple_read_2(tuple, idx);
1151							idx += 2;
1152							break;
1153						case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1154							cfe->iospace[i].start =
1155								pcmcia_tuple_read_4(tuple, idx);
1156							idx += 4;
1157							break;
1158						}
1159						switch (reg &
1160							PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1161						case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_NONE:
1162							cfe->iospace[i].length =
1163							    0;
1164							break;
1165						case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1166							cfe->iospace[i].length =
1167								pcmcia_tuple_read_1(tuple, idx);
1168							idx++;
1169							break;
1170						case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1171							cfe->iospace[i].length =
1172								pcmcia_tuple_read_2(tuple, idx);
1173							idx += 2;
1174							break;
1175						case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1176							cfe->iospace[i].length =
1177								pcmcia_tuple_read_4(tuple, idx);
1178							idx += 4;
1179							break;
1180						}
1181						cfe->iospace[i].length++;
1182					}
1183				} else {
1184					cfe->num_iospace = 1;
1185					cfe->iospace[0].start = 0;
1186					cfe->iospace[0].length =
1187					    (1 << cfe->iomask);
1188				}
1189			}
1190			if (irq) {
1191				if (tuple->length <= idx) {
1192					DPRINTF(("ran out of space before TCPE_IR\n"));
1193					goto abort_cfe;
1194				}
1195
1196				reg = pcmcia_tuple_read_1(tuple, idx);
1197				idx++;
1198
1199				cfe->flags &= ~(PCMCIA_CFE_IRQSHARE
1200				    | PCMCIA_CFE_IRQPULSE
1201				    | PCMCIA_CFE_IRQLEVEL);
1202				if (reg & PCMCIA_TPCE_IR_SHARE)
1203					cfe->flags |= PCMCIA_CFE_IRQSHARE;
1204				if (reg & PCMCIA_TPCE_IR_PULSE)
1205					cfe->flags |= PCMCIA_CFE_IRQPULSE;
1206				if (reg & PCMCIA_TPCE_IR_LEVEL)
1207					cfe->flags |= PCMCIA_CFE_IRQLEVEL;
1208
1209				if (reg & PCMCIA_TPCE_IR_HASMASK) {
1210					/*
1211					 * it's legal to ignore the
1212					 * special-interrupt bits, so I will
1213					 */
1214
1215					cfe->irqmask =
1216					    pcmcia_tuple_read_2(tuple, idx);
1217					idx += 2;
1218				} else {
1219					cfe->irqmask =
1220					    (1 << (reg & PCMCIA_TPCE_IR_IRQ));
1221				}
1222			}
1223			if (memspace && tuple->length <= idx) {
1224				DPRINTF(("ran out of space before TCPE_MS\n"));
1225				goto abort_cfe;
1226			}
1227
1228			switch (memspace) {
1229			case PCMCIA_TPCE_FS_MEMSPACE_NONE:
1230				cfe->num_memspace = 0;
1231				break;
1232
1233			case PCMCIA_TPCE_FS_MEMSPACE_LENGTH:
1234				cfe->num_memspace = 1;
1235				cfe->memspace[0].length = 256 *
1236				    pcmcia_tuple_read_2(tuple, idx);
1237				idx += 2;
1238				cfe->memspace[0].cardaddr = 0;
1239				cfe->memspace[0].hostaddr = 0;
1240				break;
1241
1242			case PCMCIA_TPCE_FS_MEMSPACE_LENGTHADDR:
1243				cfe->num_memspace = 1;
1244				cfe->memspace[0].length = 256 *
1245				    pcmcia_tuple_read_2(tuple, idx);
1246				idx += 2;
1247				cfe->memspace[0].cardaddr = 256 *
1248				    pcmcia_tuple_read_2(tuple, idx);
1249				idx += 2;
1250				cfe->memspace[0].hostaddr =
1251				    cfe->memspace[0].cardaddr;
1252				break;
1253
1254			default:
1255			{
1256				int lengthsize;
1257				int cardaddrsize;
1258				int hostaddrsize;
1259
1260				reg = pcmcia_tuple_read_1(tuple, idx);
1261				idx++;
1262
1263				cfe->num_memspace = (reg & PCMCIA_TPCE_MS_COUNT)
1264				    + 1;
1265
1266				if (cfe->num_memspace >
1267				    (sizeof(cfe->memspace) /
1268					sizeof(cfe->memspace[0]))) {
1269					DPRINTF(("too many mem spaces %d",
1270					    cfe->num_memspace));
1271					state->card->error++;
1272					break;
1273				}
1274				lengthsize =
1275				    ((reg & PCMCIA_TPCE_MS_LENGTH_SIZE_MASK) >>
1276					PCMCIA_TPCE_MS_LENGTH_SIZE_SHIFT);
1277				cardaddrsize =
1278				    ((reg &
1279					PCMCIA_TPCE_MS_CARDADDR_SIZE_MASK) >>
1280					  PCMCIA_TPCE_MS_CARDADDR_SIZE_SHIFT);
1281				hostaddrsize =
1282				    (reg & PCMCIA_TPCE_MS_HOSTADDR) ?
1283				    cardaddrsize : 0;
1284
1285				if (lengthsize == 0) {
1286					DPRINTF(("cfe memspace "
1287					    "lengthsize == 0"));
1288					state->card->error++;
1289				}
1290				for (i = 0; i < cfe->num_memspace; i++) {
1291					if (lengthsize) {
1292						cfe->memspace[i].length = 256 *
1293						    pcmcia_tuple_read_n(tuple,
1294							lengthsize, idx);
1295						idx += lengthsize;
1296					} else {
1297						cfe->memspace[i].length = 0;
1298					}
1299					if (cfe->memspace[i].length == 0) {
1300						DPRINTF(("cfe->memspace"
1301						    "[%d].length == 0", i));
1302						state->card->error++;
1303					}
1304					if (cardaddrsize) {
1305						cfe->memspace[i].cardaddr =
1306						    256 *
1307						    pcmcia_tuple_read_n(tuple,
1308							cardaddrsize, idx);
1309						idx += cardaddrsize;
1310					} else {
1311						cfe->memspace[i].cardaddr = 0;
1312					}
1313					if (hostaddrsize) {
1314						cfe->memspace[i].hostaddr =
1315						    256 *
1316						    pcmcia_tuple_read_n(tuple,
1317							hostaddrsize, idx);
1318						idx += hostaddrsize;
1319					} else {
1320						cfe->memspace[i].hostaddr = 0;
1321					}
1322				}
1323			}
1324
1325			if (misc) {
1326				if (tuple->length <= idx) {
1327					DPRINTF(("ran out of space before TCPE_MI\n"));
1328					goto abort_cfe;
1329				}
1330
1331				reg = pcmcia_tuple_read_1(tuple, idx);
1332				idx++;
1333
1334				cfe->flags &= ~(PCMCIA_CFE_POWERDOWN
1335				    | PCMCIA_CFE_READONLY
1336				    | PCMCIA_CFE_AUDIO);
1337				if (reg & PCMCIA_TPCE_MI_PWRDOWN)
1338					cfe->flags |= PCMCIA_CFE_POWERDOWN;
1339				if (reg & PCMCIA_TPCE_MI_READONLY)
1340					cfe->flags |= PCMCIA_CFE_READONLY;
1341				if (reg & PCMCIA_TPCE_MI_AUDIO)
1342					cfe->flags |= PCMCIA_CFE_AUDIO;
1343				cfe->maxtwins = reg & PCMCIA_TPCE_MI_MAXTWINS;
1344
1345				while (reg & PCMCIA_TPCE_MI_EXT) {
1346					reg = pcmcia_tuple_read_1(tuple, idx);
1347					idx++;
1348				}
1349			}
1350			/* skip all the subtuples */
1351		}
1352
1353	abort_cfe:
1354		DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1355		break;
1356	default:
1357		DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1358		break;
1359	}
1360
1361	return (0);
1362}
1363
1364
1365
1366static int
1367decode_funce(tuple, pf)
1368	struct pcmcia_tuple *tuple;
1369	struct pcmcia_function *pf;
1370{
1371	int type = pcmcia_tuple_read_1(tuple, 0);
1372
1373	switch (pf->function) {
1374	case PCMCIA_FUNCTION_DISK:
1375		if (type == PCMCIA_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1376			pf->pf_funce_disk_interface
1377			    = pcmcia_tuple_read_1(tuple, 1);
1378		}
1379		break;
1380	case PCMCIA_FUNCTION_NETWORK:
1381		if (type == PCMCIA_TPLFE_TYPE_LAN_NID) {
1382			int i;
1383			int len = pcmcia_tuple_read_1(tuple, 1);
1384			if (tuple->length < 2 + len || len > 8) {
1385				/* tuple length not enough or nid too long */
1386				break;
1387			}
1388			for (i = 0; i < len; ++i) {
1389				pf->pf_funce_lan_nid[i]
1390				    = pcmcia_tuple_read_1(tuple, 2 + i);
1391			}
1392			pf->pf_funce_lan_nidlen = len;
1393		}
1394		break;
1395	default:
1396		break;
1397	}
1398
1399	return 0;
1400}
1401