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