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