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