1/*-
2 * Copyright (c) 2005-2008, M. Warner Losh
3 * Copyright (c) 2000,2001 Jonathan Chen.
4 * 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 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30
31/*
32 * CIS Handling for the Cardbus Bus
33 */
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/malloc.h>
39
40#include <sys/bus.h>
41#include <machine/bus.h>
42#include <machine/resource.h>
43#include <sys/rman.h>
44#include <sys/endian.h>
45
46#include <sys/pciio.h>
47#include <dev/pci/pcivar.h>
48#include <dev/pci/pcireg.h>
49
50#include <dev/pccard/pccardvar.h>
51#include <dev/pccard/pccard_cis.h>
52
53#include <dev/cardbus/cardbusreg.h>
54#include <dev/cardbus/cardbusvar.h>
55#include <dev/cardbus/cardbus_cis.h>
56
57extern int cardbus_cis_debug;
58
59#define	DPRINTF(a) if (cardbus_cis_debug) printf a
60#define	DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
61
62#define CIS_CONFIG_SPACE	(struct resource *)~0UL
63
64static int decode_tuple_generic(device_t cbdev, device_t child, int id,
65    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
66    struct tuple_callbacks *info, void *);
67static int decode_tuple_linktarget(device_t cbdev, device_t child, int id,
68    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
69    struct tuple_callbacks *info, void *);
70static int decode_tuple_vers_1(device_t cbdev, device_t child, int id,
71    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
72    struct tuple_callbacks *info, void *);
73static int decode_tuple_funcid(device_t cbdev, device_t child, int id,
74    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
75    struct tuple_callbacks *info, void *);
76static int decode_tuple_manfid(device_t cbdev, device_t child, int id,
77    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
78    struct tuple_callbacks *info, void *);
79static int decode_tuple_funce(device_t cbdev, device_t child, int id,
80    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
81    struct tuple_callbacks *info, void *);
82static int decode_tuple_bar(device_t cbdev, device_t child, int id,
83    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
84    struct tuple_callbacks *info, void *);
85static int decode_tuple_unhandled(device_t cbdev, device_t child, int id,
86    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
87    struct tuple_callbacks *info, void *);
88static int decode_tuple_end(device_t cbdev, device_t child, int id,
89    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
90    struct tuple_callbacks *info, void *);
91
92static int	cardbus_read_tuple_conf(device_t cbdev, device_t child,
93		    uint32_t start, uint32_t *off, int *tupleid, int *len,
94		    uint8_t *tupledata);
95static int	cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
96		    uint32_t start, uint32_t *off, int *tupleid, int *len,
97		    uint8_t *tupledata);
98static int	cardbus_read_tuple(device_t cbdev, device_t child,
99		    struct resource *res, uint32_t start, uint32_t *off,
100		    int *tupleid, int *len, uint8_t *tupledata);
101static void	cardbus_read_tuple_finish(device_t cbdev, device_t child,
102		    int rid, struct resource *res);
103static struct resource	*cardbus_read_tuple_init(device_t cbdev, device_t child,
104		    uint32_t *start, int *rid);
105static int	decode_tuple(device_t cbdev, device_t child, int tupleid,
106		    int len, uint8_t *tupledata, uint32_t start,
107		    uint32_t *off, struct tuple_callbacks *callbacks,
108		    void *);
109
110#define	MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
111
112static char *funcnames[] = {
113	"Multi-Functioned",
114	"Memory",
115	"Serial Port",
116	"Parallel Port",
117	"Fixed Disk",
118	"Video Adaptor",
119	"Network Adaptor",
120	"AIMS",
121	"SCSI",
122	"Security"
123};
124
125/*
126 * Handler functions for various CIS tuples
127 */
128
129static int
130decode_tuple_generic(device_t cbdev, device_t child, int id,
131    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
132    struct tuple_callbacks *info, void *argp)
133{
134	int i;
135
136	if (cardbus_cis_debug) {
137		if (info)
138			printf("TUPLE: %s [%d]:", info->name, len);
139		else
140			printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
141
142		for (i = 0; i < len; i++) {
143			if (i % 0x10 == 0 && len > 0x10)
144				printf("\n       0x%02x:", i);
145			printf(" %02x", tupledata[i]);
146		}
147		printf("\n");
148	}
149	return (0);
150}
151
152static int
153decode_tuple_linktarget(device_t cbdev, device_t child, int id,
154    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
155    struct tuple_callbacks *info, void *argp)
156{
157	int i;
158
159	if (cardbus_cis_debug) {
160		printf("TUPLE: %s [%d]:", info->name, len);
161
162		for (i = 0; i < len; i++) {
163			if (i % 0x10 == 0 && len > 0x10)
164				printf("\n       0x%02x:", i);
165			printf(" %02x", tupledata[i]);
166		}
167		printf("\n");
168	}
169	if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
170	    tupledata[2] != 'S') {
171		printf("Invalid data for CIS Link Target!\n");
172		decode_tuple_generic(cbdev, child, id, len, tupledata,
173		    start, off, info, argp);
174		return (EINVAL);
175	}
176	return (0);
177}
178
179static int
180decode_tuple_vers_1(device_t cbdev, device_t child, int id,
181    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
182    struct tuple_callbacks *info, void *argp)
183{
184	int i;
185
186	if (cardbus_cis_debug) {
187		printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
188		printf("Product name: ");
189		for (i = 2; i < len; i++) {
190			if (tupledata[i] == '\0')
191				printf(" | ");
192			else if (tupledata[i] == 0xff)
193				break;
194			else
195				printf("%c", tupledata[i]);
196		}
197		printf("\n");
198	}
199	return (0);
200}
201
202static int
203decode_tuple_funcid(device_t cbdev, device_t child, int id,
204    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
205    struct tuple_callbacks *info, void *argp)
206{
207	struct cardbus_devinfo *dinfo = device_get_ivars(child);
208	int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
209	int i;
210
211	if (cardbus_cis_debug) {
212		printf("Functions: ");
213		for (i = 0; i < len; i++) {
214			if (tupledata[i] < numnames)
215				printf("%s", funcnames[tupledata[i]]);
216			else
217				printf("Unknown(%d)", tupledata[i]);
218			if (i < len - 1)
219				printf(", ");
220		}
221		printf("\n");
222	}
223	if (len > 0)
224		dinfo->funcid = tupledata[0];		/* use first in list */
225	return (0);
226}
227
228static int
229decode_tuple_manfid(device_t cbdev, device_t child, int id,
230    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
231    struct tuple_callbacks *info, void *argp)
232{
233	struct cardbus_devinfo *dinfo = device_get_ivars(child);
234	int i;
235
236	if (cardbus_cis_debug) {
237		printf("Manufacturer ID: ");
238		for (i = 0; i < len; i++)
239			printf("%02x", tupledata[i]);
240		printf("\n");
241	}
242
243	if (len == 5) {
244		dinfo->mfrid = tupledata[1] | (tupledata[2] << 8);
245		dinfo->prodid = tupledata[3] | (tupledata[4] << 8);
246	}
247	return (0);
248}
249
250static int
251decode_tuple_funce(device_t cbdev, device_t child, int id,
252    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
253    struct tuple_callbacks *info, void *argp)
254{
255	struct cardbus_devinfo *dinfo = device_get_ivars(child);
256	int type, i;
257
258	if (cardbus_cis_debug) {
259		printf("Function Extension: ");
260		for (i = 0; i < len; i++)
261			printf("%02x", tupledata[i]);
262		printf("\n");
263	}
264	if (len < 2)			/* too short */
265		return (0);
266	type = tupledata[0];		/* XXX <32 always? */
267	switch (dinfo->funcid) {
268	case PCCARD_FUNCTION_NETWORK:
269		switch (type) {
270		case PCCARD_TPLFE_TYPE_LAN_NID:
271			if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) {
272				/* ignore, warning? */
273				return (0);
274			}
275			bcopy(tupledata + 2, dinfo->funce.lan.nid,
276			    tupledata[1]);
277			break;
278		}
279		dinfo->fepresent |= 1<<type;
280		break;
281	}
282	return (0);
283}
284
285static int
286decode_tuple_bar(device_t cbdev, device_t child, int id,
287    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
288    struct tuple_callbacks *info, void *argp)
289{
290	struct cardbus_devinfo *dinfo = device_get_ivars(child);
291	int type;
292	uint8_t reg;
293	uint32_t bar;
294
295	if (len != 6) {
296		device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
297		return (EINVAL);
298	}
299
300	reg = *tupledata;
301	len = le32toh(*(uint32_t*)(tupledata + 2));
302	if (reg & TPL_BAR_REG_AS)
303		type = SYS_RES_IOPORT;
304	else
305		type = SYS_RES_MEMORY;
306
307	bar = reg & TPL_BAR_REG_ASI_MASK;
308	if (bar == 0) {
309		device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
310		return (EINVAL);	/* XXX Return an error? */
311	} else if (bar == 7) {
312		/* XXX Should we try to map in Option ROMs? */
313		return (0);
314	}
315
316	/* Convert from BAR type to BAR offset */
317	bar = PCIR_BAR(bar - 1);
318
319	if (type == SYS_RES_MEMORY) {
320		if (reg & TPL_BAR_REG_PREFETCHABLE)
321			dinfo->mprefetchable |= (1 << PCI_RID2BAR(bar));
322		/*
323		 * The PC Card spec says we're only supposed to honor this
324		 * hint when the cardbus bridge is a child of pci0 (the main
325		 * bus).  The PC Card spec seems to indicate that this should
326		 * only be done on x86 based machines, which suggests that on
327		 * non-x86 machines the addresses can be anywhere.  Since the
328		 * hardware can do it on non-x86 machines, it should be able
329		 * to do it on x86 machines too.  Therefore, we can and should
330		 * ignore this hint.  Furthermore, the PC Card spec recommends
331		 * always allocating memory above 1MB, contradicting the other
332		 * part of the PC Card spec, it seems.  We make note of it,
333		 * but otherwise don't use this information.
334		 *
335		 * Some Realtek cards have this set in their CIS, but fail
336		 * to actually work when mapped this way, and experience
337		 * has shown ignoring this big to be a wise choice.
338		 *
339		 * XXX We should cite chapter and verse for standard refs.
340		 */
341		if (reg & TPL_BAR_REG_BELOW1MB)
342			dinfo->mbelow1mb |= (1 << PCI_RID2BAR(bar));
343	}
344
345	return (0);
346}
347
348static int
349decode_tuple_unhandled(device_t cbdev, device_t child, int id,
350    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
351    struct tuple_callbacks *info, void *argp)
352{
353	/* Make this message suck less XXX */
354	printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
355	return (EINVAL);
356}
357
358static int
359decode_tuple_end(device_t cbdev, device_t child, int id,
360    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
361    struct tuple_callbacks *info, void *argp)
362{
363	if (cardbus_cis_debug)
364		printf("CIS reading done\n");
365	return (0);
366}
367
368/*
369 * Functions to read the a tuple from the card
370 */
371
372/*
373 * Read CIS bytes out of the config space.  We have to read it 4 bytes at a
374 * time and do the usual mask and shift to return the bytes.  The standard
375 * defines the byte order to be little endian.  pci_read_config converts it to
376 * host byte order.  This is why we have no endian conversion functions: the
377 * shifts wind up being endian neutral.  This is also why we avoid the obvious
378 * memcpy optimization.
379 */
380static int
381cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
382    uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
383{
384	int i, j;
385	uint32_t e;
386	uint32_t loc;
387
388	loc = start + *off;
389
390	e = pci_read_config(child, loc & ~0x3, 4);
391	e >>= 8 * (loc & 0x3);
392	*len = 0;
393	for (i = loc, j = -2; j < *len; j++, i++) {
394		if ((i & 0x3) == 0)
395			e = pci_read_config(child, i, 4);
396		if (j == -2)
397			*tupleid = 0xff & e;
398		else if (j == -1)
399			*len = 0xff & e;
400		else
401			tupledata[j] = 0xff & e;
402		e >>= 8;
403	}
404	*off += *len + 2;
405	return (0);
406}
407
408/*
409 * Read the CIS data out of memroy.  We indirect through the bus space
410 * routines to ensure proper byte ordering conversions when necessary.
411 */
412static int
413cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
414    uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
415{
416	int ret;
417
418	*tupleid = bus_read_1(res, start + *off);
419	*len = bus_read_1(res, start + *off + 1);
420	bus_read_region_1(res, *off + start + 2, tupledata, *len);
421	ret = 0;
422	*off += *len + 2;
423	return (ret);
424}
425
426static int
427cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
428    uint32_t start, uint32_t *off, int *tupleid, int *len,
429    uint8_t *tupledata)
430{
431	if (res == CIS_CONFIG_SPACE)
432		return (cardbus_read_tuple_conf(cbdev, child, start, off,
433		    tupleid, len, tupledata));
434	return (cardbus_read_tuple_mem(cbdev, res, start, off, tupleid, len,
435	    tupledata));
436}
437
438static void
439cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
440    struct resource *res)
441{
442	if (res != CIS_CONFIG_SPACE) {
443		bus_release_resource(child, SYS_RES_MEMORY, rid, res);
444		bus_delete_resource(child, SYS_RES_MEMORY, rid);
445	}
446}
447
448static struct resource *
449cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
450    int *rid)
451{
452	struct resource *res;
453	uint32_t space;
454
455	space = *start & PCIM_CIS_ASI_MASK;
456	switch (space) {
457	case PCIM_CIS_ASI_CONFIG:
458		DEVPRINTF((cbdev, "CIS in PCI config space\n"));
459		/* CIS in PCI config space need no initialization */
460		return (CIS_CONFIG_SPACE);
461	case PCIM_CIS_ASI_BAR0:
462	case PCIM_CIS_ASI_BAR1:
463	case PCIM_CIS_ASI_BAR2:
464	case PCIM_CIS_ASI_BAR3:
465	case PCIM_CIS_ASI_BAR4:
466	case PCIM_CIS_ASI_BAR5:
467		*rid = PCIR_BAR(space - PCIM_CIS_ASI_BAR0);
468		DEVPRINTF((cbdev, "CIS in BAR %#x\n", *rid));
469		break;
470	case PCIM_CIS_ASI_ROM:
471		*rid = PCIR_BIOS;
472		DEVPRINTF((cbdev, "CIS in option rom\n"));
473		break;
474	default:
475		device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
476		    space);
477		return (NULL);
478	}
479
480	/* allocate the memory space to read CIS */
481	res = bus_alloc_resource_any(child, SYS_RES_MEMORY, rid,
482	    rman_make_alignment_flags(4096) | RF_ACTIVE);
483	if (res == NULL) {
484		device_printf(cbdev, "Unable to allocate resource "
485		    "to read CIS.\n");
486		return (NULL);
487	}
488	DEVPRINTF((cbdev, "CIS Mapped to %#lx\n", rman_get_start(res)));
489
490	/* Flip to the right ROM image if CIS is in ROM */
491	if (space == PCIM_CIS_ASI_ROM) {
492		uint32_t imagesize;
493		uint32_t imagebase = 0;
494		uint32_t pcidata;
495		uint16_t romsig;
496		int romnum = 0;
497		int imagenum;
498
499		imagenum = (*start & PCIM_CIS_ROM_MASK) >> 28;
500		for (romnum = 0;; romnum++) {
501			romsig = bus_read_2(res,
502			    imagebase + CARDBUS_EXROM_SIGNATURE);
503			if (romsig != 0xaa55) {
504				device_printf(cbdev, "Bad header in rom %d: "
505				    "[%x] %04x\n", romnum, imagebase +
506				    CARDBUS_EXROM_SIGNATURE, romsig);
507				cardbus_read_tuple_finish(cbdev, child, *rid,
508				    res);
509				*rid = 0;
510				return (NULL);
511			}
512
513			/*
514			 * If this was the Option ROM image that we were
515			 * looking for, then we are done.
516			 */
517			if (romnum == imagenum)
518				break;
519
520			/* Find out where the next Option ROM image is */
521			pcidata = imagebase + bus_read_2(res,
522			    imagebase + CARDBUS_EXROM_DATA_PTR);
523			imagesize = bus_read_2(res,
524			    pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
525
526			if (imagesize == 0) {
527				/*
528				 * XXX some ROMs seem to have this as zero,
529				 * can we assume this means 1 block?
530				 */
531				device_printf(cbdev, "Warning, size of Option "
532				    "ROM image %d is 0 bytes, assuming 512 "
533				    "bytes.\n", romnum);
534				imagesize = 1;
535			}
536
537			/* Image size is in 512 byte units */
538			imagesize <<= 9;
539
540			if ((bus_read_1(res, pcidata +
541			    CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
542				device_printf(cbdev, "Cannot find CIS in "
543				    "Option ROM\n");
544				cardbus_read_tuple_finish(cbdev, child, *rid,
545				    res);
546				*rid = 0;
547				return (NULL);
548			}
549			imagebase += imagesize;
550		}
551		*start = imagebase + (*start & PCIM_CIS_ADDR_MASK);
552	} else {
553		*start = *start & PCIM_CIS_ADDR_MASK;
554	}
555	DEVPRINTF((cbdev, "CIS offset is %#x\n", *start));
556
557	return (res);
558}
559
560/*
561 * Dispatch the right handler function per tuple
562 */
563
564static int
565decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
566    uint8_t *tupledata, uint32_t start, uint32_t *off,
567    struct tuple_callbacks *callbacks, void *argp)
568{
569	int i;
570	for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
571		if (tupleid == callbacks[i].id)
572			return (callbacks[i].func(cbdev, child, tupleid, len,
573			    tupledata, start, off, &callbacks[i], argp));
574	}
575	return (callbacks[i].func(cbdev, child, tupleid, len,
576	    tupledata, start, off, NULL, argp));
577}
578
579int
580cardbus_parse_cis(device_t cbdev, device_t child,
581    struct tuple_callbacks *callbacks, void *argp)
582{
583	uint8_t tupledata[MAXTUPLESIZE];
584	int tupleid = CISTPL_NULL;
585	int len;
586	int expect_linktarget;
587	uint32_t start, off;
588	struct resource *res;
589	int rid;
590
591	bzero(tupledata, MAXTUPLESIZE);
592	expect_linktarget = TRUE;
593	if ((start = pci_read_config(child, PCIR_CIS, 4)) == 0) {
594		DEVPRINTF((cbdev, "Warning: CIS pointer is 0: (no CIS)\n"));
595		return (0);
596	}
597	DEVPRINTF((cbdev, "CIS pointer is %#x\n", start));
598	off = 0;
599	res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
600	if (res == NULL) {
601		device_printf(cbdev, "Unable to allocate resources for CIS\n");
602		return (ENXIO);
603	}
604
605	do {
606		if (cardbus_read_tuple(cbdev, child, res, start, &off,
607		    &tupleid, &len, tupledata) != 0) {
608			device_printf(cbdev, "Failed to read CIS.\n");
609			cardbus_read_tuple_finish(cbdev, child, rid, res);
610			return (ENXIO);
611		}
612
613		if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
614			device_printf(cbdev, "Expecting link target, got 0x%x\n",
615			    tupleid);
616			cardbus_read_tuple_finish(cbdev, child, rid, res);
617			return (EINVAL);
618		}
619		expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
620		    tupledata, start, &off, callbacks, argp);
621		if (expect_linktarget != 0) {
622			device_printf(cbdev, "Parsing failed with %d\n",
623			    expect_linktarget);
624			cardbus_read_tuple_finish(cbdev, child, rid, res);
625			return (expect_linktarget);
626		}
627	} while (tupleid != CISTPL_END);
628	cardbus_read_tuple_finish(cbdev, child, rid, res);
629	return (0);
630}
631
632int
633cardbus_do_cis(device_t cbdev, device_t child)
634{
635	struct tuple_callbacks init_callbacks[] = {
636		MAKETUPLE(LONGLINK_CB,		unhandled),
637		MAKETUPLE(INDIRECT,		unhandled),
638		MAKETUPLE(LONGLINK_MFC,		unhandled),
639		MAKETUPLE(BAR,			bar),
640		MAKETUPLE(LONGLINK_A,		unhandled),
641		MAKETUPLE(LONGLINK_C,		unhandled),
642		MAKETUPLE(LINKTARGET,		linktarget),
643		MAKETUPLE(VERS_1,		vers_1),
644		MAKETUPLE(MANFID,		manfid),
645		MAKETUPLE(FUNCID,		funcid),
646		MAKETUPLE(FUNCE,		funce),
647		MAKETUPLE(END,			end),
648		MAKETUPLE(GENERIC,		generic),
649	};
650
651	return (cardbus_parse_cis(cbdev, child, init_callbacks, NULL));
652}
653