xref: /freebsd/sys/dev/cardbus/cardbus_cis.c (revision 2dd5c91ebb92c0da58ca5ce91b082d931bd272c0)
1 /*-
2  * Copyright (c) 2000,2001 Jonathan Chen.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 /*
31  * CIS Handling for the Cardbus Bus
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38 
39 #include <sys/bus.h>
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/rman.h>
43 #include <sys/endian.h>
44 
45 #include <sys/pciio.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcireg.h>
48 
49 #include <dev/pccard/pccardvar.h>
50 #include <dev/pccard/pccard_cis.h>
51 
52 #include <dev/cardbus/cardbusreg.h>
53 #include <dev/cardbus/cardbusvar.h>
54 #include <dev/cardbus/cardbus_cis.h>
55 
56 extern int cardbus_cis_debug;
57 
58 #define	DPRINTF(a) if (cardbus_cis_debug) printf a
59 #define	DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
60 
61 struct tuple_callbacks;
62 
63 typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len,
64 		 uint8_t *tupledata, uint32_t start, uint32_t *off,
65 		 struct tuple_callbacks *info);
66 
67 struct tuple_callbacks {
68 	int	id;
69 	char	*name;
70 	tuple_cb *func;
71 };
72 
73 static int decode_tuple_generic(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);
76 static int decode_tuple_linktarget(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);
79 static int decode_tuple_vers_1(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);
82 static int decode_tuple_funcid(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);
85 static int decode_tuple_manfid(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);
88 static int decode_tuple_funce(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);
91 static int decode_tuple_bar(device_t cbdev, device_t child, int id,
92     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
93     struct tuple_callbacks *info);
94 static int decode_tuple_unhandled(device_t cbdev, device_t child, int id,
95     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
96     struct tuple_callbacks *info);
97 static int decode_tuple_end(device_t cbdev, device_t child, int id,
98     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
99     struct tuple_callbacks *info);
100 
101 static int	cardbus_read_tuple_conf(device_t cbdev, device_t child,
102 		    uint32_t start, uint32_t *off, int *tupleid, int *len,
103 		    uint8_t *tupledata);
104 static int	cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
105 		    uint32_t start, uint32_t *off, int *tupleid, int *len,
106 		    uint8_t *tupledata);
107 static int	cardbus_read_tuple(device_t cbdev, device_t child,
108 		    struct resource *res, uint32_t start, uint32_t *off,
109 		    int *tupleid, int *len, uint8_t *tupledata);
110 static void	cardbus_read_tuple_finish(device_t cbdev, device_t child,
111 		    int rid, struct resource *res);
112 static struct resource	*cardbus_read_tuple_init(device_t cbdev, device_t child,
113 		    uint32_t *start, int *rid);
114 static int	decode_tuple(device_t cbdev, device_t child, int tupleid,
115 		    int len, uint8_t *tupledata, uint32_t start,
116 		    uint32_t *off, struct tuple_callbacks *callbacks);
117 static int	cardbus_parse_cis(device_t cbdev, device_t child,
118 		    struct tuple_callbacks *callbacks);
119 static int	barsort(const void *a, const void *b);
120 static int	cardbus_alloc_resources(device_t cbdev, device_t child);
121 static void	cardbus_add_map(device_t cbdev, device_t child, int reg);
122 static void	cardbus_pickup_maps(device_t cbdev, device_t child);
123 
124 
125 #define	MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
126 
127 static char *funcnames[] = {
128 	"Multi-Functioned",
129 	"Memory",
130 	"Serial Port",
131 	"Parallel Port",
132 	"Fixed Disk",
133 	"Video Adaptor",
134 	"Network Adaptor",
135 	"AIMS",
136 	"SCSI",
137 	"Security"
138 };
139 
140 /*
141  * Handler functions for various CIS tuples
142  */
143 
144 static int
145 decode_tuple_generic(device_t cbdev, device_t child, int id,
146     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
147     struct tuple_callbacks *info)
148 {
149 	int i;
150 
151 	if (cardbus_cis_debug) {
152 		if (info)
153 			printf("TUPLE: %s [%d]:", info->name, len);
154 		else
155 			printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
156 
157 		for (i = 0; i < len; i++) {
158 			if (i % 0x10 == 0 && len > 0x10)
159 				printf("\n       0x%02x:", i);
160 			printf(" %02x", tupledata[i]);
161 		}
162 		printf("\n");
163 	}
164 	return (0);
165 }
166 
167 static int
168 decode_tuple_linktarget(device_t cbdev, device_t child, int id,
169     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
170     struct tuple_callbacks *info)
171 {
172 	int i;
173 
174 	if (cardbus_cis_debug) {
175 		printf("TUPLE: %s [%d]:", info->name, len);
176 
177 		for (i = 0; i < len; i++) {
178 			if (i % 0x10 == 0 && len > 0x10)
179 				printf("\n       0x%02x:", i);
180 			printf(" %02x", tupledata[i]);
181 		}
182 		printf("\n");
183 	}
184 	if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
185 	    tupledata[2] != 'S') {
186 		printf("Invalid data for CIS Link Target!\n");
187 		decode_tuple_generic(cbdev, child, id, len, tupledata,
188 		    start, off, info);
189 		return (EINVAL);
190 	}
191 	return (0);
192 }
193 
194 static int
195 decode_tuple_vers_1(device_t cbdev, device_t child, int id,
196     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
197     struct tuple_callbacks *info)
198 {
199 	int i;
200 
201 	if (cardbus_cis_debug) {
202 		printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
203 		printf("Product name: ");
204 		for (i = 2; i < len; i++) {
205 			if (tupledata[i] == '\0')
206 				printf(" | ");
207 			else if (tupledata[i] == 0xff)
208 				break;
209 			else
210 				printf("%c", tupledata[i]);
211 		}
212 		printf("\n");
213 	}
214 	return (0);
215 }
216 
217 static int
218 decode_tuple_funcid(device_t cbdev, device_t child, int id,
219     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
220     struct tuple_callbacks *info)
221 {
222 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
223 	int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
224 	int i;
225 
226 	if (cardbus_cis_debug) {
227 		printf("Functions: ");
228 		for (i = 0; i < len; i++) {
229 			if (tupledata[i] < numnames)
230 				printf("%s", funcnames[tupledata[i]]);
231 			else
232 				printf("Unknown(%d)", tupledata[i]);
233 			if (i < len-1)
234 				printf(", ");
235 		}
236 		printf("\n");
237 	}
238 	if (len > 0)
239 		dinfo->funcid = tupledata[0];		/* use first in list */
240 	return (0);
241 }
242 
243 static int
244 decode_tuple_manfid(device_t cbdev, device_t child, int id,
245     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
246     struct tuple_callbacks *info)
247 {
248 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
249 	int i;
250 
251 	if (cardbus_cis_debug) {
252 		printf("Manufacturer ID: ");
253 		for (i = 0; i < len; i++)
254 			printf("%02x", tupledata[i]);
255 		printf("\n");
256 	}
257 
258 	if (len == 5) {
259 		dinfo->mfrid = tupledata[1] | (tupledata[2] << 8);
260 		dinfo->prodid = tupledata[3] | (tupledata[4] << 8);
261 	}
262 	return (0);
263 }
264 
265 static int
266 decode_tuple_funce(device_t cbdev, device_t child, int id,
267     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
268     struct tuple_callbacks *info)
269 {
270 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
271 	int type, i;
272 
273 	if (cardbus_cis_debug) {
274 		printf("Function Extension: ");
275 		for (i = 0; i < len; i++)
276 			printf("%02x", tupledata[i]);
277 		printf("\n");
278 	}
279 	if (len < 2)			/* too short */
280 		return (0);
281 	type = tupledata[0];		/* XXX <32 always? */
282 	switch (dinfo->funcid) {
283 	case TPL_FUNC_SERIAL:
284 		if (type == TPL_FUNCE_SER_UART) {	/* NB: len known > 1 */
285 			dinfo->funce.sio.type = tupledata[1] & 0x1f;
286 		}
287 		dinfo->fepresent |= 1<<type;
288 		break;
289 	case TPL_FUNC_LAN:
290 		switch (type) {
291 		case TPL_FUNCE_LAN_TECH:
292 			dinfo->funce.lan.tech = tupledata[1];	/* XXX mask? */
293 			break;
294 #if 0
295 		case TPL_FUNCE_LAN_SPEED:
296 			for (i = 0; i < 3; i++) {
297 				if (dinfo->funce.lan.speed[i] == 0) {
298 					if (len > 4) {
299 						dinfo->funce.lan.speed[i] =
300 							...;
301 					}
302 					break;
303 				}
304 			}
305 			break;
306 #endif
307 		case TPL_FUNCE_LAN_MEDIA:
308 			for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
309 				if (dinfo->funce.lan.media[i] == 0) {
310 					/* NB: len known > 1 */
311 					dinfo->funce.lan.media[i] =
312 						tupledata[1];	/*XXX? mask */
313 					break;
314 				}
315 			}
316 			break;
317 		case TPL_FUNCE_LAN_NID:
318 			if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) {
319 				/* ignore, warning? */
320 				return (0);
321 			}
322 			bcopy(tupledata + 2, dinfo->funce.lan.nid,
323 			    tupledata[1]);
324 			break;
325 		case TPL_FUNCE_LAN_CONN:
326 			dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
327 			break;
328 		}
329 		dinfo->fepresent |= 1<<type;
330 		break;
331 	}
332 	return (0);
333 }
334 
335 static int
336 decode_tuple_bar(device_t cbdev, device_t child, int id,
337     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
338     struct tuple_callbacks *info)
339 {
340 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
341 	int type;
342 	uint8_t reg;
343 	uint32_t bar, pci_bar;
344 
345 	if (len != 6) {
346 		device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
347 		return (EINVAL);
348 	}
349 
350 	reg = *tupledata;
351 	len = le32toh(*(uint32_t*)(tupledata + 2));
352 	if (reg & TPL_BAR_REG_AS) {
353 		type = SYS_RES_IOPORT;
354 	} else {
355 		type = SYS_RES_MEMORY;
356 	}
357 
358 	bar = reg & TPL_BAR_REG_ASI_MASK;
359 	if (bar == 0) {
360 		device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
361 		return (EINVAL);	/* XXX Return an error? */
362 	} else if (bar == 7) {
363 		/* XXX Should we try to map in Option ROMs? */
364 		return (0);
365 	}
366 
367 	/* Convert from BAR type to BAR offset */
368 	bar = CARDBUS_BASE0_REG + (bar - 1) * 4;
369 
370 	if (type == SYS_RES_MEMORY) {
371 		if (reg & TPL_BAR_REG_PREFETCHABLE)
372 			dinfo->mprefetchable |= BARBIT(bar);
373 #if 0
374 		/*
375 		 * XXX: It appears from a careful reading of the spec
376 		 * that we're not supposed to honor this when the bridge
377 		 * is not on the main system bus.  PCI spec doesn't appear
378 		 * to allow for memory ranges not listed in the bridge's
379 		 * decode range to be decoded.  The PC Card spec seems to
380 		 * indicate that this should only be done on x86 based
381 		 * machines, which seems to imply that on non-x86 machines
382 		 * the adddresses can be anywhere.  This further implies that
383 		 * since the hardware can do it on non-x86 machines, it should
384 		 * be able to do it on x86 machines.  Therefore, we can and
385 		 * should ignore this hint.  Furthermore, the PC Card spec
386 		 * recommends always allocating memory above 1MB, contradicting
387 		 * the other part of the PC Card spec.
388 		 *
389 		 * NetBSD ignores this bit, but it also ignores the
390 		 * prefetchable bit too, so that's not an indication of
391 		 * correctness.
392 		 */
393 		if (reg & TPL_BAR_REG_BELOW1MB)
394 			dinfo->mbelow1mb |= BARBIT(bar);
395 #endif
396 	}
397 
398 	/*
399 	 * Sanity check the BAR length reported in the CIS with the length
400 	 * encoded in the PCI BAR.  The latter seems to be more reliable.
401 	 * XXX - This probably belongs elsewhere.
402 	 */
403 	pci_write_config(child, bar, 0xffffffff, 4);
404 	pci_bar = pci_read_config(child, bar, 4);
405 	if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) {
406 		if (type == SYS_RES_MEMORY) {
407 			pci_bar &= ~0xf;
408 		} else {
409 			pci_bar &= ~0x3;
410 		}
411 		len = 1 << (ffs(pci_bar) - 1);
412 	}
413 
414 	DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
415 	    (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
416 	    (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
417 	    " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
418 	    ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : ""));
419 
420 	resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
421 
422 	/*
423 	 * Mark the appropriate bit in the PCI command register so that
424 	 * device drivers will know which type of BARs can be used.
425 	 */
426 	pci_enable_io(child, type);
427 	return (0);
428 }
429 
430 static int
431 decode_tuple_unhandled(device_t cbdev, device_t child, int id,
432     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
433     struct tuple_callbacks *info)
434 {
435 	/* Make this message suck less XXX */
436 	printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
437 	return (-1);
438 }
439 
440 static int
441 decode_tuple_end(device_t cbdev, device_t child, int id,
442     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
443     struct tuple_callbacks *info)
444 {
445 	if (cardbus_cis_debug) {
446 		printf("CIS reading done\n");
447 	}
448 	return (0);
449 }
450 
451 /*
452  * Functions to read the a tuple from the card
453  */
454 
455 static int
456 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
457     uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
458 {
459 	int i, j;
460 	uint32_t e;
461 	uint32_t loc;
462 
463 	loc = start + *off;
464 
465 	e = pci_read_config(child, loc - loc % 4, 4);
466 	for (j = loc % 4; j > 0; j--)
467 		e >>= 8;
468 	*len = 0;
469 	for (i = loc, j = -2; j < *len; j++, i++) {
470 		if (i % 4 == 0)
471 			e = pci_read_config(child, i, 4);
472 		if (j == -2)
473 			*tupleid = 0xff & e;
474 		else if (j == -1)
475 			*len = 0xff & e;
476 		else
477 			tupledata[j] = 0xff & e;
478 		e >>= 8;
479 	}
480 	*off += *len + 2;
481 	return (0);
482 }
483 
484 static int
485 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
486     uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
487 {
488 	bus_space_tag_t bt;
489 	bus_space_handle_t bh;
490 	int ret;
491 
492 	bt = rman_get_bustag(res);
493 	bh = rman_get_bushandle(res);
494 
495 	*tupleid = bus_space_read_1(bt, bh, start + *off);
496 	*len = bus_space_read_1(bt, bh, start + *off + 1);
497 	bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
498 	ret = 0;
499 	*off += *len + 2;
500 	return (ret);
501 }
502 
503 static int
504 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
505     uint32_t start, uint32_t *off, int *tupleid, int *len,
506     uint8_t *tupledata)
507 {
508 	if (res == (struct resource*)~0UL) {
509 		return (cardbus_read_tuple_conf(cbdev, child, start, off,
510 		    tupleid, len, tupledata));
511 	} else {
512 		return (cardbus_read_tuple_mem(cbdev, res, start, off,
513 		    tupleid, len, tupledata));
514 	}
515 }
516 
517 static void
518 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
519     struct resource *res)
520 {
521 	if (res != (struct resource*)~0UL) {
522 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
523 		pci_write_config(child, rid, 0, 4);
524 		PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
525 	}
526 }
527 
528 static struct resource *
529 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
530     int *rid)
531 {
532 	uint32_t testval;
533 	uint32_t size;
534 	struct resource *res;
535 
536 	switch (CARDBUS_CIS_SPACE(*start)) {
537 	case CARDBUS_CIS_ASI_TUPLE:
538 		/* CIS in PCI config space need no initialization */
539 		return ((struct resource*)~0UL);
540 	case CARDBUS_CIS_ASI_BAR0:
541 	case CARDBUS_CIS_ASI_BAR1:
542 	case CARDBUS_CIS_ASI_BAR2:
543 	case CARDBUS_CIS_ASI_BAR3:
544 	case CARDBUS_CIS_ASI_BAR4:
545 	case CARDBUS_CIS_ASI_BAR5:
546 		*rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
547 		break;
548 	case CARDBUS_CIS_ASI_ROM:
549 		*rid = CARDBUS_ROM_REG;
550 #if 0
551 		/*
552 		 * This mask doesn't contain the bit that actually enables
553 		 * the Option ROM.
554 		 */
555 		pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
556 #endif
557 		break;
558 	default:
559 		device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
560 		    CARDBUS_CIS_SPACE(*start));
561 		return (NULL);
562 	}
563 
564 	/* figure out how much space we need */
565 	pci_write_config(child, *rid, 0xffffffff, 4);
566 	testval = pci_read_config(child, *rid, 4);
567 
568 	/*
569 	 * This bit has a different meaning depending if we are dealing
570 	 * with a normal BAR or an Option ROM BAR.
571 	 */
572 	if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
573 		device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
574 		return (NULL);
575 	}
576 
577 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
578 	/* XXX Is this some kind of hack? */
579 	if (size < 4096)
580 		size = 4096;
581 	/* allocate the memory space to read CIS */
582 	res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
583 	    rman_make_alignment_flags(size) | RF_ACTIVE);
584 	if (res == NULL) {
585 		device_printf(cbdev, "Unable to allocate resource "
586 		    "to read CIS.\n");
587 		return (NULL);
588 	}
589 	pci_write_config(child, *rid,
590 	    rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
591 		CARDBUS_ROM_ENABLE : 0),
592 	    4);
593 	PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
594 
595 	/* Flip to the right ROM image if CIS is in ROM */
596 	if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
597 		bus_space_tag_t bt;
598 		bus_space_handle_t bh;
599 		uint32_t imagesize;
600 		uint32_t imagebase = 0;
601 		uint32_t pcidata;
602 		uint16_t romsig;
603 		int romnum = 0;
604 		int imagenum;
605 
606 		bt = rman_get_bustag(res);
607 		bh = rman_get_bushandle(res);
608 
609 		imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
610 		for (romnum = 0;; romnum++) {
611 			romsig = bus_space_read_2(bt, bh,
612 			    imagebase + CARDBUS_EXROM_SIGNATURE);
613 			if (romsig != 0xaa55) {
614 				device_printf(cbdev, "Bad header in rom %d: "
615 				    "[%x] %04x\n", romnum, imagebase +
616 				    CARDBUS_EXROM_SIGNATURE, romsig);
617 				bus_release_resource(cbdev, SYS_RES_MEMORY,
618 				    *rid, res);
619 				*rid = 0;
620 				return (NULL);
621 			}
622 
623 			/*
624 			 * If this was the Option ROM image that we were
625 			 * looking for, then we are done.
626 			 */
627 			if (romnum == imagenum)
628 				break;
629 
630 			/* Find out where the next Option ROM image is */
631 			pcidata = imagebase + bus_space_read_2(bt, bh,
632 			    imagebase + CARDBUS_EXROM_DATA_PTR);
633 			imagesize = bus_space_read_2(bt, bh,
634 			    pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
635 
636 			if (imagesize == 0) {
637 				/*
638 				 * XXX some ROMs seem to have this as zero,
639 				 * can we assume this means 1 block?
640 				 */
641 				device_printf(cbdev, "Warning, size of Option "
642 				    "ROM image %d is 0 bytes, assuming 512 "
643 				    "bytes.\n", romnum);
644 				imagesize = 1;
645 			}
646 
647 			/* Image size is in 512 byte units */
648 			imagesize <<= 9;
649 
650 			if ((bus_space_read_1(bt, bh, pcidata +
651 			    CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
652 				device_printf(cbdev, "Cannot find CIS in "
653 				    "Option ROM\n");
654 				bus_release_resource(cbdev, SYS_RES_MEMORY,
655 				    *rid, res);
656 				*rid = 0;
657 				return (NULL);
658 			}
659 			imagebase += imagesize;
660 		}
661 		*start = imagebase + CARDBUS_CIS_ADDR(*start);
662 	} else {
663 		*start = CARDBUS_CIS_ADDR(*start);
664 	}
665 
666 	return (res);
667 }
668 
669 /*
670  * Dispatch the right handler function per tuple
671  */
672 
673 static int
674 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
675     uint8_t *tupledata, uint32_t start, uint32_t *off,
676     struct tuple_callbacks *callbacks)
677 {
678 	int i;
679 	for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
680 		if (tupleid == callbacks[i].id)
681 			return (callbacks[i].func(cbdev, child, tupleid, len,
682 			    tupledata, start, off, &callbacks[i]));
683 	}
684 	return (callbacks[i].func(cbdev, child, tupleid, len,
685 	    tupledata, start, off, NULL));
686 }
687 
688 static int
689 cardbus_parse_cis(device_t cbdev, device_t child,
690     struct tuple_callbacks *callbacks)
691 {
692 	uint8_t tupledata[MAXTUPLESIZE];
693 	int tupleid;
694 	int len;
695 	int expect_linktarget;
696 	uint32_t start, off;
697 	struct resource *res;
698 	int rid;
699 
700 	bzero(tupledata, MAXTUPLESIZE);
701 	expect_linktarget = TRUE;
702 	if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
703 		return (ENXIO);
704 	off = 0;
705 	res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
706 	if (res == NULL)
707 		return (ENXIO);
708 
709 	do {
710 		if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
711 		    &tupleid, &len, tupledata)) {
712 			device_printf(cbdev, "Failed to read CIS.\n");
713 			cardbus_read_tuple_finish(cbdev, child, rid, res);
714 			return (ENXIO);
715 		}
716 
717 		if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
718 			device_printf(cbdev, "Expecting link target, got 0x%x\n",
719 			    tupleid);
720 			cardbus_read_tuple_finish(cbdev, child, rid, res);
721 			return (EINVAL);
722 		}
723 		expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
724 		    tupledata, start, &off, callbacks);
725 		if (expect_linktarget != 0) {
726 			cardbus_read_tuple_finish(cbdev, child, rid, res);
727 			return (expect_linktarget);
728 		}
729 	} while (tupleid != CISTPL_END);
730 	cardbus_read_tuple_finish(cbdev, child, rid, res);
731 	return (0);
732 }
733 
734 static void
735 cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start)
736 {
737 	rle->start = start;
738 	rle->end = start + rle->count - 1;
739 	pci_write_config(child, rle->rid, rle->start, 4);
740 }
741 
742 static int
743 barsort(const void *a, const void *b)
744 {
745 	return ((*(const struct resource_list_entry * const *)b)->count -
746 	    (*(const struct resource_list_entry * const *)a)->count);
747 }
748 
749 static int
750 cardbus_alloc_resources(device_t cbdev, device_t child)
751 {
752 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
753 	int count;
754 	struct resource_list_entry *rle;
755 	struct resource_list_entry **barlist;
756 	int tmp;
757 	uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
758 	struct resource *res;
759 	uint32_t start,end;
760 	int rid, flags;
761 
762 	count = 0;
763 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
764 		count++;
765 	}
766 	if (count == 0)
767 		return (0);
768 	barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
769 	    M_WAITOK);
770 	count = 0;
771 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
772 		barlist[count] = rle;
773 		if (rle->type == SYS_RES_IOPORT) {
774 			io_size += rle->count;
775 		} else if (rle->type == SYS_RES_MEMORY) {
776 			if (dinfo->mprefetchable & BARBIT(rle->rid))
777 				mem_psize += rle->count;
778 			else
779 				mem_nsize += rle->count;
780 		}
781 		count++;
782 	}
783 
784 	/*
785 	 * We want to allocate the largest resource first, so that our
786 	 * allocated memory is packed.
787 	 */
788 	qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
789 
790 	/* Allocate prefetchable memory */
791 	flags = 0;
792 	for (tmp = 0; tmp < count; tmp++) {
793 		rle = barlist[tmp];
794 		if (rle->res == NULL &&
795 		    rle->type == SYS_RES_MEMORY &&
796 		    dinfo->mprefetchable & BARBIT(rle->rid)) {
797 			flags = rman_make_alignment_flags(rle->count);
798 			break;
799 		}
800 	}
801 	if (flags > 0) { /* If any prefetchable memory is requested... */
802 		/*
803 		 * First we allocate one big space for all resources of this
804 		 * type.  We do this because our parent, pccbb, needs to open
805 		 * a window to forward all addresses within the window, and
806 		 * it would be best if nobody else has resources allocated
807 		 * within the window.
808 		 * (XXX: Perhaps there might be a better way to do this?)
809 		 */
810 		rid = 0;
811 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
812 		    (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
813 		    mem_psize, flags);
814 		if (res == NULL) {
815 			device_printf(cbdev,
816 			    "Can't get memory for prefetch mem\n");
817 			free(barlist, M_DEVBUF);
818 			return (EIO);
819 		}
820 		start = rman_get_start(res);
821 		end = rman_get_end(res);
822 		DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
823 		/*
824 		 * Now that we know the region is free, release it and hand it
825 		 * out piece by piece.
826 		 */
827 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
828 		for (tmp = 0; tmp < count; tmp++) {
829 			rle = barlist[tmp];
830 			if (rle->type == SYS_RES_MEMORY &&
831 			    dinfo->mprefetchable & BARBIT(rle->rid)) {
832 				cardbus_do_res(rle, child, start);
833 				start += rle->count;
834 			}
835 		}
836 	}
837 
838 	/* Allocate non-prefetchable memory */
839 	flags = 0;
840 	for (tmp = 0; tmp < count; tmp++) {
841 		rle = barlist[tmp];
842 		if (rle->type == SYS_RES_MEMORY &&
843 		    (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
844 			flags = rman_make_alignment_flags(rle->count);
845 			break;
846 		}
847 	}
848 	if (flags > 0) { /* If any non-prefetchable memory is requested... */
849 		/*
850 		 * First we allocate one big space for all resources of this
851 		 * type.  We do this because our parent, pccbb, needs to open
852 		 * a window to forward all addresses within the window, and
853 		 * it would be best if nobody else has resources allocated
854 		 * within the window.
855 		 * (XXX: Perhaps there might be a better way to do this?)
856 		 */
857 		rid = 0;
858 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
859 		    ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
860 		    mem_nsize, flags);
861 		if (res == NULL) {
862 			device_printf(cbdev,
863 			    "Can't get memory for non-prefetch mem\n");
864 			free(barlist, M_DEVBUF);
865 			return (EIO);
866 		}
867 		start = rman_get_start(res);
868 		end = rman_get_end(res);
869 		DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
870 		    start, end));
871 		/*
872 		 * Now that we know the region is free, release it and hand it
873 		 * out piece by piece.
874 		 */
875 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
876 		for (tmp = 0; tmp < count; tmp++) {
877 			rle = barlist[tmp];
878 			if (rle->type == SYS_RES_MEMORY &&
879 			    (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
880 				cardbus_do_res(rle, child, start);
881 				start += rle->count;
882 			}
883 		}
884 	}
885 
886 	/* Allocate IO ports */
887 	flags = 0;
888 	for (tmp = 0; tmp < count; tmp++) {
889 		rle = barlist[tmp];
890 		if (rle->type == SYS_RES_IOPORT) {
891 			flags = rman_make_alignment_flags(rle->count);
892 			break;
893 		}
894 	}
895 	if (flags > 0) { /* If any IO port is requested... */
896 		/*
897 		 * First we allocate one big space for all resources of this
898 		 * type.  We do this because our parent, pccbb, needs to open
899 		 * a window to forward all addresses within the window, and
900 		 * it would be best if nobody else has resources allocated
901 		 * within the window.
902 		 * (XXX: Perhaps there might be a better way to do this?)
903 		 */
904 		rid = 0;
905 		res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
906 		    (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
907 		if (res == NULL) {
908 			device_printf(cbdev,
909 			    "Can't get memory for IO ports\n");
910 			free(barlist, M_DEVBUF);
911 			return (EIO);
912 		}
913 		start = rman_get_start(res);
914 		end = rman_get_end(res);
915 		DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
916 		/*
917 		 * Now that we know the region is free, release it and hand it
918 		 * out piece by piece.
919 		 */
920 		bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
921 		for (tmp = 0; tmp < count; tmp++) {
922 			rle = barlist[tmp];
923 			if (rle->type == SYS_RES_IOPORT) {
924 				cardbus_do_res(rle, child, start);
925 				start += rle->count;
926 			}
927 		}
928 	}
929 
930 	/* Allocate IRQ */
931 	rid = 0;
932 	res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE);
933 	if (res == NULL) {
934 		device_printf(cbdev, "Can't get memory for irq\n");
935 		free(barlist, M_DEVBUF);
936 		return (EIO);
937 	}
938 	start = rman_get_start(res);
939 	end = rman_get_end(res);
940 	bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
941 	resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
942 	    1);
943 	dinfo->pci.cfg.intline = rman_get_start(res);
944 	pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
945 
946 	free(barlist, M_DEVBUF);
947 	return (0);
948 }
949 
950 /*
951  * Adding a memory/io resource (sans CIS)
952  */
953 
954 static void
955 cardbus_add_map(device_t cbdev, device_t child, int reg)
956 {
957 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
958 	struct resource_list_entry *rle;
959 	uint32_t size;
960 	uint32_t testval;
961 	int type;
962 
963 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
964 		if (rle->rid == reg)
965 			return;
966 	}
967 
968 	if (reg == CARDBUS_ROM_REG)
969 		testval = CARDBUS_ROM_ADDRMASK;
970 	else
971 		testval = ~0;
972 
973 	pci_write_config(child, reg, testval, 4);
974 	testval = pci_read_config(child, reg, 4);
975 
976 	if (testval == ~0 || testval == 0)
977 		return;
978 
979 	if ((testval & 1) == 0)
980 		type = SYS_RES_MEMORY;
981 	else
982 		type = SYS_RES_IOPORT;
983 
984 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
985 	device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
986 	    reg, size);
987 	resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
988 }
989 
990 static void
991 cardbus_pickup_maps(device_t cbdev, device_t child)
992 {
993 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
994 	int reg;
995 
996 	/*
997 	 * Try to pick up any resources that was not specified in CIS.
998 	 * Maybe this isn't any longer necessary now that we have fixed
999 	 * CIS parsing and we should filter things here?  XXX
1000 	 */
1001 	for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++)
1002 		cardbus_add_map(cbdev, child, PCIR_BAR(reg));
1003 }
1004 
1005 int
1006 cardbus_do_cis(device_t cbdev, device_t child)
1007 {
1008 	int ret;
1009 	struct tuple_callbacks init_callbacks[] = {
1010 		MAKETUPLE(LONGLINK_CB,		unhandled),
1011 		MAKETUPLE(INDIRECT,		unhandled),
1012 		MAKETUPLE(LONGLINK_MFC,		unhandled),
1013 		MAKETUPLE(BAR,			bar),
1014 		MAKETUPLE(LONGLINK_A,		unhandled),
1015 		MAKETUPLE(LONGLINK_C,		unhandled),
1016 		MAKETUPLE(LINKTARGET,		linktarget),
1017 		MAKETUPLE(VERS_1,		vers_1),
1018 		MAKETUPLE(MANFID,		manfid),
1019 		MAKETUPLE(FUNCID,		funcid),
1020 		MAKETUPLE(FUNCE,		funce),
1021 		MAKETUPLE(END,			end),
1022 		MAKETUPLE(GENERIC,		generic),
1023 	};
1024 
1025 	ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1026 	if (ret < 0)
1027 		return (ret);
1028 	cardbus_pickup_maps(cbdev, child);
1029 	return (cardbus_alloc_resources(cbdev, child));
1030 }
1031