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