xref: /freebsd/sys/dev/cardbus/cardbus_cis.c (revision 4b2eaea43fec8e8792be611dea204071a10b655a)
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  * $FreeBSD$
29  */
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 
45 #include <sys/pciio.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcireg.h>
48 
49 #include <dev/cardbus/cardbusreg.h>
50 #include <dev/cardbus/cardbusvar.h>
51 #include <dev/cardbus/cardbus_cis.h>
52 
53 #include <dev/pccard/pccardvar.h>
54 
55 extern int cardbus_cis_debug;
56 
57 #define	DPRINTF(a) if (cardbus_cis_debug) printf a
58 #define	DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
59 
60 #define	DECODE_PARAMS							\
61 		(device_t cbdev, device_t child, int id, int len,	\
62 		 uint8_t *tupledata, uint32_t start, uint32_t *off,	\
63 		 struct tuple_callbacks *info)
64 
65 struct tuple_callbacks {
66 	int	id;
67 	char	*name;
68 	int	(*func) DECODE_PARAMS;
69 };
70 
71 #define	DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS
72 DECODE_PROTOTYPE(generic);
73 DECODE_PROTOTYPE(nothing);
74 DECODE_PROTOTYPE(copy);
75 DECODE_PROTOTYPE(linktarget);
76 DECODE_PROTOTYPE(vers_1);
77 DECODE_PROTOTYPE(funcid);
78 DECODE_PROTOTYPE(manfid);
79 DECODE_PROTOTYPE(funce);
80 DECODE_PROTOTYPE(bar);
81 DECODE_PROTOTYPE(unhandled);
82 DECODE_PROTOTYPE(end);
83 static int	cardbus_read_tuple_conf(device_t cbdev, device_t child,
84 		    uint32_t start, uint32_t *off, int *tupleid, int *len,
85 		    uint8_t *tupledata);
86 static int	cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
87 		    uint32_t start, uint32_t *off, int *tupleid, int *len,
88 		    uint8_t *tupledata);
89 static int	cardbus_read_tuple(device_t cbdev, device_t child,
90 		    struct resource *res, uint32_t start, uint32_t *off,
91 		    int *tupleid, int *len, uint8_t *tupledata);
92 static void	cardbus_read_tuple_finish(device_t cbdev, device_t child,
93 		    int rid, struct resource *res);
94 static struct resource	*cardbus_read_tuple_init(device_t cbdev, device_t child,
95 		    uint32_t *start, int *rid);
96 static int	decode_tuple(device_t cbdev, device_t child, int tupleid,
97 		    int len, uint8_t *tupledata, uint32_t start,
98 		    uint32_t *off, struct tuple_callbacks *callbacks);
99 static int	cardbus_parse_cis(device_t cbdev, device_t child,
100 		    struct tuple_callbacks *callbacks);
101 static int	barsort(const void *a, const void *b);
102 static int	cardbus_alloc_resources(device_t cbdev, device_t child);
103 static void	cardbus_add_map(device_t cbdev, device_t child, int reg);
104 static void	cardbus_pickup_maps(device_t cbdev, device_t child);
105 
106 
107 #define	MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
108 
109 static char *funcnames[] = {
110 	"Multi-Functioned",
111 	"Memory",
112 	"Serial Port",
113 	"Parallel Port",
114 	"Fixed Disk",
115 	"Video Adaptor",
116 	"Network Adaptor",
117 	"AIMS",
118 	"SCSI",
119 	"Security"
120 };
121 
122 struct cardbus_quirk {
123 	uint32_t devid;	/* Vendor/device of the card */
124 	int	type;
125 #define	CARDBUS_QUIRK_MAP_REG	1 /* PCI map register in weird place */
126 	int	arg1;
127 	int	arg2;
128 };
129 
130 struct cardbus_quirk cardbus_quirks[] = {
131 	{ 0 }
132 };
133 
134 static struct cis_tupleinfo *cisread_buf;
135 static int ncisread_buf;
136 
137 /*
138  * Handler functions for various CIS tuples
139  */
140 
141 DECODE_PROTOTYPE(generic)
142 {
143 #ifdef CARDBUS_DEBUG
144 	int i;
145 
146 	if (info)
147 		printf("TUPLE: %s [%d]:", info->name, len);
148 	else
149 		printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
150 
151 	for (i = 0; i < len; i++) {
152 		if (i % 0x10 == 0 && len > 0x10)
153 			printf("\n       0x%02x:", i);
154 		printf(" %02x", tupledata[i]);
155 	}
156 	printf("\n");
157 #endif
158 	return (0);
159 }
160 
161 DECODE_PROTOTYPE(nothing)
162 {
163 	return (0);
164 }
165 
166 DECODE_PROTOTYPE(copy)
167 {
168 	struct cis_tupleinfo *tmpbuf;
169 
170 	tmpbuf = malloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1),
171 	    M_DEVBUF, 0);
172 	if (ncisread_buf > 0) {
173 		memcpy(tmpbuf, cisread_buf,
174 		    sizeof(struct cis_tupleinfo) * ncisread_buf);
175 		free(cisread_buf, M_DEVBUF);
176 	}
177 	cisread_buf = tmpbuf;
178 
179 	cisread_buf[ncisread_buf].id = id;
180 	cisread_buf[ncisread_buf].len = len;
181 	cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, 0);
182 	memcpy(cisread_buf[ncisread_buf].data, tupledata, len);
183 	ncisread_buf++;
184 	return (0);
185 }
186 
187 DECODE_PROTOTYPE(linktarget)
188 {
189 #ifdef CARDBUS_DEBUG
190 	int i;
191 
192 	printf("TUPLE: %s [%d]:", info->name, len);
193 
194 	for (i = 0; i < len; i++) {
195 		if (i % 0x10 == 0 && len > 0x10)
196 			printf("\n       0x%02x:", i);
197 		printf(" %02x", tupledata[i]);
198 	}
199 	printf("\n");
200 #endif
201 	if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
202 	    tupledata[2] != 'S') {
203 		printf("Invalid data for CIS Link Target!\n");
204 		decode_tuple_generic(cbdev, child, id, len, tupledata,
205 		    start, off, info);
206 		return (EINVAL);
207 	}
208 	return (0);
209 }
210 
211 DECODE_PROTOTYPE(vers_1)
212 {
213 	int i;
214 
215 	printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
216 	printf("Product name: ");
217 	for (i = 2; i < len; i++) {
218 		if (tupledata[i] == '\0')
219 			printf(" | ");
220 		else if (tupledata[i] == 0xff)
221 			break;
222 		else
223 			printf("%c", tupledata[i]);
224 	}
225 	printf("\n");
226 	return (0);
227 }
228 
229 DECODE_PROTOTYPE(funcid)
230 {
231 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
232 	int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
233 	int i;
234 
235 	printf("Functions: ");
236 	for (i = 0; i < len; i++) {
237 		if (tupledata[i] < numnames)
238 			printf("%s", funcnames[tupledata[i]]);
239 		else
240 			printf("Unknown(%d)", tupledata[i]);
241 		if (i < len-1)
242 			printf(", ");
243 	}
244 
245 	if (len > 0)
246 		dinfo->funcid = tupledata[0];		/* use first in list */
247 	printf("\n");
248 	return (0);
249 }
250 
251 DECODE_PROTOTYPE(manfid)
252 {
253 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
254 	int i;
255 
256 	printf("Manufacturer ID: ");
257 	for (i = 0; i < len; i++)
258 		printf("%02x", tupledata[i]);
259 	printf("\n");
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 DECODE_PROTOTYPE(funce)
269 {
270 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
271 	int type, i;
272 
273 	printf("Function Extension: ");
274 	for (i = 0; i < len; i++)
275 		printf("%02x", tupledata[i]);
276 	printf("\n");
277 	if (len < 2)			/* too short */
278 		return (0);
279 	type = tupledata[0];		/* XXX <32 always? */
280 	switch (dinfo->funcid) {
281 	case TPL_FUNC_SERIAL:
282 		if (type == TPL_FUNCE_SER_UART) {	/* NB: len known > 1 */
283 			dinfo->funce.sio.type = tupledata[1] & 0x1f;
284 		}
285 		dinfo->fepresent |= 1<<type;
286 		break;
287 	case TPL_FUNC_LAN:
288 		switch (type) {
289 		case TPL_FUNCE_LAN_TECH:
290 			dinfo->funce.lan.tech = tupledata[1];	/* XXX mask? */
291 			break;
292 #if 0
293 		case TPL_FUNCE_LAN_SPEED:
294 			for (i = 0; i < 3; i++) {
295 				if (dinfo->funce.lan.speed[i] == 0) {
296 					if (len > 4) {
297 						dinfo->funce.lan.speed[i] =
298 							...;
299 					}
300 					break;
301 				}
302 			}
303 			break;
304 #endif
305 		case TPL_FUNCE_LAN_MEDIA:
306 			for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
307 				if (dinfo->funce.lan.media[i] == 0) {
308 					/* NB: len known > 1 */
309 					dinfo->funce.lan.media[i] =
310 						tupledata[1];	/*XXX? mask */
311 					break;
312 				}
313 			}
314 			break;
315 		case TPL_FUNCE_LAN_NID:
316 			if (len > 6)
317 				bcopy(&tupledata[1], dinfo->funce.lan.nid, 6);
318 			break;
319 		case TPL_FUNCE_LAN_CONN:
320 			dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
321 			break;
322 		}
323 		dinfo->fepresent |= 1<<type;
324 		break;
325 	}
326 	return (0);
327 }
328 
329 DECODE_PROTOTYPE(bar)
330 {
331 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
332 	int type;
333 	int reg;
334 	uint32_t bar;
335 
336 	if (len != 6) {
337 		printf("*** ERROR *** BAR length not 6 (%d)\n", len);
338 		return (EINVAL);
339 	}
340 	reg = *(uint16_t*)tupledata;
341 	len = *(uint32_t*)(tupledata + 2);
342 	if (reg & TPL_BAR_REG_AS) {
343 		type = SYS_RES_IOPORT;
344 	} else {
345 		type = SYS_RES_MEMORY;
346 	}
347 	bar = (reg & TPL_BAR_REG_ASI_MASK) - 1;
348 	if (bar < 0 || bar > 5 ||
349 	    (type == SYS_RES_IOPORT && bar == 5)) {
350 		device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n",
351 		    reg, bar);
352 		return (0);
353 	}
354 	bar = CARDBUS_BASE0_REG + bar * 4;
355 	if (type == SYS_RES_MEMORY) {
356 		if (bar & TPL_BAR_REG_PREFETCHABLE)
357 			dinfo->mprefetchable |= BARBIT(bar);
358 		if (bar & TPL_BAR_REG_BELOW1MB)
359 			dinfo->mbelow1mb |= BARBIT(bar);
360 	} else if (type == SYS_RES_IOPORT) {
361 		if (bar & TPL_BAR_REG_BELOW1MB)
362 			dinfo->ibelow1mb |= BARBIT(bar);
363 	}
364 	DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
365 	    (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
366 	    (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
367 	    " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
368 	    ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") :
369 	    (dinfo->ibelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "" ));
370 
371 	resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
372 
373 	/*
374 	 * Mark the appropriate bit in the PCI command register so that
375 	 * device drivers will know which type of BARs can be used.
376 	 */
377 	pci_enable_io(child, type);
378 	return (0);
379 }
380 
381 DECODE_PROTOTYPE(unhandled)
382 {
383 	printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
384 	return (-1);
385 }
386 
387 DECODE_PROTOTYPE(end)
388 {
389 	printf("CIS reading done\n");
390 	return (0);
391 }
392 
393 /*
394  * Functions to read the a tuple from the card
395  */
396 
397 static int
398 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
399     uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
400 {
401 	int i, j;
402 	uint32_t e;
403 	uint32_t loc;
404 
405 	loc = start + *off;
406 
407 	e = pci_read_config(child, loc - loc % 4, 4);
408 	for (j = loc % 4; j > 0; j--)
409 		e >>= 8;
410 	*len = 0;
411 	for (i = loc, j = -2; j < *len; j++, i++) {
412 		if (i % 4 == 0)
413 			e = pci_read_config(child, i, 4);
414 		if (j == -2)
415 			*tupleid = 0xff & e;
416 		else if (j == -1)
417 			*len = 0xff & e;
418 		else
419 			tupledata[j] = 0xff & e;
420 		e >>= 8;
421 	}
422 	*off += *len + 2;
423 	return (0);
424 }
425 
426 static int
427 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
428     uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
429 {
430 	bus_space_tag_t bt;
431 	bus_space_handle_t bh;
432 	int ret;
433 
434 	bt = rman_get_bustag(res);
435 	bh = rman_get_bushandle(res);
436 
437 	*tupleid = bus_space_read_1(bt, bh, start + *off);
438 	*len = bus_space_read_1(bt, bh, start + *off + 1);
439 	bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
440 	ret = 0;
441 	*off += *len + 2;
442 	return (ret);
443 }
444 
445 static int
446 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
447     uint32_t start, uint32_t *off, int *tupleid, int *len,
448     uint8_t *tupledata)
449 {
450 	if (res == (struct resource*)~0UL) {
451 		return (cardbus_read_tuple_conf(cbdev, child, start, off,
452 		    tupleid, len, tupledata));
453 	} else {
454 		return (cardbus_read_tuple_mem(cbdev, res, start, off,
455 		    tupleid, len, tupledata));
456 	}
457 }
458 
459 static void
460 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
461     struct resource *res)
462 {
463 	if (res != (struct resource*)~0UL) {
464 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
465 		pci_write_config(child, rid, 0, 4);
466 		PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
467 	}
468 }
469 
470 static struct resource *
471 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
472     int *rid)
473 {
474 	uint32_t testval;
475 	uint32_t size;
476 	struct resource *res;
477 
478 	switch (CARDBUS_CIS_SPACE(*start)) {
479 	case CARDBUS_CIS_ASI_TUPLE:
480 		/* CIS in PCI config space need no initialization */
481 		return ((struct resource*)~0UL);
482 	case CARDBUS_CIS_ASI_BAR0:
483 	case CARDBUS_CIS_ASI_BAR1:
484 	case CARDBUS_CIS_ASI_BAR2:
485 	case CARDBUS_CIS_ASI_BAR3:
486 	case CARDBUS_CIS_ASI_BAR4:
487 	case CARDBUS_CIS_ASI_BAR5:
488 		*rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
489 		break;
490 	case CARDBUS_CIS_ASI_ROM:
491 		*rid = CARDBUS_ROM_REG;
492 #if 0
493 		/*
494 		 * This mask doesn't contain the bit that actually enables
495 		 * the Option ROM.
496 		 */
497 		pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
498 #endif
499 		break;
500 	default:
501 		device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
502 		    CARDBUS_CIS_SPACE(*start));
503 		return (NULL);
504 	}
505 
506 	/* figure out how much space we need */
507 	pci_write_config(child, *rid, 0xffffffff, 4);
508 	testval = pci_read_config(child, *rid, 4);
509 
510 	/*
511 	 * This bit has a different meaning depending if we are dealing
512 	 * with a normal BAR or an Option ROM BAR.
513 	 */
514 	if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
515 		device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
516 		return (NULL);
517 	}
518 
519 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
520 	/* XXX Is this some kind of hack? */
521 	if (size < 4096)
522 		size = 4096;
523 	/* allocate the memory space to read CIS */
524 	res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
525 	    rman_make_alignment_flags(size) | RF_ACTIVE);
526 	if (res == NULL) {
527 		device_printf(cbdev, "Unable to allocate resource "
528 		    "to read CIS.\n");
529 		return (NULL);
530 	}
531 	pci_write_config(child, *rid,
532 	    rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
533 		CARDBUS_ROM_ENABLE : 0),
534 	    4);
535 	PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
536 
537 	/* Flip to the right ROM image if CIS is in ROM */
538 	if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
539 		bus_space_tag_t bt;
540 		bus_space_handle_t bh;
541 		uint32_t imagesize;
542 		uint32_t imagebase = 0;
543 		uint32_t pcidata;
544 		uint16_t romsig;
545 		int romnum = 0;
546 		int imagenum;
547 
548 		bt = rman_get_bustag(res);
549 		bh = rman_get_bushandle(res);
550 
551 		imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
552 		for (romnum = 0;; romnum++) {
553 			romsig = bus_space_read_2(bt, bh,
554 			    imagebase + CARDBUS_EXROM_SIGNATURE);
555 			if (romsig != 0xaa55) {
556 				device_printf(cbdev, "Bad header in rom %d: "
557 				    "[%x] %04x\n", romnum, imagebase +
558 				    CARDBUS_EXROM_SIGNATURE, romsig);
559 				bus_release_resource(cbdev, SYS_RES_MEMORY,
560 				    *rid, res);
561 				*rid = 0;
562 				return (NULL);
563 			}
564 
565 			/*
566 			 * If this was the Option ROM image that we were
567 			 * looking for, then we are done.
568 			 */
569 			if (romnum == imagenum)
570 				break;
571 
572 			/* Find out where the next Option ROM image is */
573 			pcidata = imagebase + bus_space_read_2(bt, bh,
574 			    imagebase + CARDBUS_EXROM_DATA_PTR);
575 			imagesize = bus_space_read_2(bt, bh,
576 			    pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
577 
578 			if (imagesize == 0) {
579 				/*
580 				 * XXX some ROMs seem to have this as zero,
581 				 * can we assume this means 1 block?
582 				 */
583 				device_printf(cbdev, "Warning, size of Option "
584 				    "ROM image %d is 0 bytes, assuming 512 "
585 				    "bytes.\n", romnum);
586 				imagesize = 1;
587 			}
588 
589 			/* Image size is in 512 byte units */
590 			imagesize <<= 9;
591 
592 			if ((bus_space_read_1(bt, bh, pcidata +
593 			    CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
594 				device_printf(cbdev, "Cannot find CIS in "
595 				    "Option ROM\n");
596 				bus_release_resource(cbdev, SYS_RES_MEMORY,
597 				    *rid, res);
598 				*rid = 0;
599 				return (NULL);
600 			}
601 			imagebase += imagesize;
602 		}
603 		*start = imagebase + CARDBUS_CIS_ADDR(*start);
604 	} else {
605 		*start = CARDBUS_CIS_ADDR(*start);
606 	}
607 
608 	return (res);
609 }
610 
611 /*
612  * Dispatch the right handler function per tuple
613  */
614 
615 static int
616 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
617     uint8_t *tupledata, uint32_t start, uint32_t *off,
618     struct tuple_callbacks *callbacks)
619 {
620 	int i;
621 	for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
622 		if (tupleid == callbacks[i].id)
623 			return (callbacks[i].func(cbdev, child, tupleid, len,
624 			    tupledata, start, off, &callbacks[i]));
625 	}
626 
627 	if (tupleid < CISTPL_CUSTOMSTART) {
628 		device_printf(cbdev, "Undefined tuple encountered, "
629 		    "CIS parsing terminated\n");
630 		return (EINVAL);
631 	}
632 	return (callbacks[i].func(cbdev, child, tupleid, len,
633 	    tupledata, start, off, NULL));
634 }
635 
636 static int
637 cardbus_parse_cis(device_t cbdev, device_t child,
638     struct tuple_callbacks *callbacks)
639 {
640 	uint8_t tupledata[MAXTUPLESIZE];
641 	int tupleid;
642 	int len;
643 	int expect_linktarget;
644 	uint32_t start, off;
645 	struct resource *res;
646 	int rid;
647 
648 	bzero(tupledata, MAXTUPLESIZE);
649 	expect_linktarget = TRUE;
650 	if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
651 		return (ENXIO);
652 	off = 0;
653 	res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
654 	if (res == NULL)
655 		return (ENXIO);
656 	do {
657 		if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
658 		    &tupleid, &len, tupledata)) {
659 			device_printf(cbdev, "Failed to read CIS.\n");
660 			cardbus_read_tuple_finish(cbdev, child, rid, res);
661 			return (ENXIO);
662 		}
663 
664 		if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
665 			device_printf(cbdev, "Expecting link target, got 0x%x\n",
666 			    tupleid);
667 			cardbus_read_tuple_finish(cbdev, child, rid, res);
668 			return (EINVAL);
669 		}
670 		expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
671 		    tupledata, start, &off, callbacks);
672 		if (expect_linktarget != 0) {
673 			cardbus_read_tuple_finish(cbdev, child, rid, res);
674 			return (expect_linktarget);
675 		}
676 	} while (tupleid != CISTPL_END);
677 	cardbus_read_tuple_finish(cbdev, child, rid, res);
678 	return (0);
679 }
680 
681 static int
682 barsort(const void *a, const void *b)
683 {
684 	return ((*(const struct resource_list_entry * const *)b)->count -
685 	    (*(const struct resource_list_entry * const *)a)->count);
686 }
687 
688 static int
689 cardbus_alloc_resources(device_t cbdev, device_t child)
690 {
691 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
692 	int count;
693 	struct resource_list_entry *rle;
694 	struct resource_list_entry **barlist;
695 	int tmp;
696 	uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
697 	struct resource *res;
698 	uint32_t start,end;
699 	int rid, flags;
700 
701 	count = 0;
702 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
703 		count++;
704 	}
705 	if (count == 0)
706 		return (0);
707 	barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
708 	    0);
709 	count = 0;
710 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
711 		barlist[count] = rle;
712 		if (rle->type == SYS_RES_IOPORT) {
713 			io_size += rle->count;
714 		} else if (rle->type == SYS_RES_MEMORY) {
715 			if (dinfo->mprefetchable & BARBIT(rle->rid))
716 				mem_psize += rle->count;
717 			else
718 				mem_nsize += rle->count;
719 		}
720 		count++;
721 	}
722 
723 	/*
724 	 * We want to allocate the largest resource first, so that our
725 	 * allocated memory is packed.
726 	 */
727 	qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
728 
729 	/* Allocate prefetchable memory */
730 	flags = 0;
731 	for (tmp = 0; tmp < count; tmp++) {
732 		if (barlist[tmp]->res == NULL &&
733 		    barlist[tmp]->type == SYS_RES_MEMORY &&
734 		    dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
735 			flags = rman_make_alignment_flags(barlist[tmp]->count);
736 			break;
737 		}
738 	}
739 	if (flags > 0) { /* If any prefetchable memory is requested... */
740 		/*
741 		 * First we allocate one big space for all resources of this
742 		 * type.  We do this because our parent, pccbb, needs to open
743 		 * a window to forward all addresses within the window, and
744 		 * it would be best if nobody else has resources allocated
745 		 * within the window.
746 		 * (XXX: Perhaps there might be a better way to do this?)
747 		 */
748 		rid = 0;
749 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
750 		    (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
751 		    mem_psize, flags);
752 		start = rman_get_start(res);
753 		end = rman_get_end(res);
754 		DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
755 		/*
756 		 * Now that we know the region is free, release it and hand it
757 		 * out piece by piece.
758 		 */
759 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
760 		for (tmp = 0; tmp < count; tmp++) {
761 			if (barlist[tmp]->res == NULL &&
762 			    barlist[tmp]->type == SYS_RES_MEMORY &&
763 			    dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
764 				barlist[tmp]->res = bus_alloc_resource(cbdev,
765 				    barlist[tmp]->type,
766 				    &barlist[tmp]->rid, start, end,
767 				    barlist[tmp]->count,
768 				    rman_make_alignment_flags(
769 				    barlist[tmp]->count));
770 				if (barlist[tmp]->res == NULL) {
771 					mem_nsize += barlist[tmp]->count;
772 					dinfo->mprefetchable &=
773 					    ~BARBIT(barlist[tmp]->rid);
774 					DEVPRINTF((cbdev, "Cannot pre-allocate "
775 					    "prefetchable memory, will try as "
776 					    "non-prefetchable.\n"));
777 				} else {
778 					barlist[tmp]->start =
779 					    rman_get_start(barlist[tmp]->res);
780 					barlist[tmp]->end =
781 					    rman_get_end(barlist[tmp]->res);
782 					pci_write_config(child,
783 					    barlist[tmp]->rid,
784 					    barlist[tmp]->start, 4);
785 					DEVPRINTF((cbdev, "Prefetchable memory "
786 					    "rid=%x at %lx-%lx\n",
787 					    barlist[tmp]->rid,
788 					    barlist[tmp]->start,
789 					    barlist[tmp]->end));
790 				}
791 			}
792 		}
793 	}
794 
795 	/* Allocate non-prefetchable memory */
796 	flags = 0;
797 	for (tmp = 0; tmp < count; tmp++) {
798 		if (barlist[tmp]->res == NULL &&
799 		    barlist[tmp]->type == SYS_RES_MEMORY) {
800 			flags = rman_make_alignment_flags(barlist[tmp]->count);
801 			break;
802 		}
803 	}
804 	if (flags > 0) { /* If any non-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_nsize, flags);
817 		start = rman_get_start(res);
818 		end = rman_get_end(res);
819 		DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
820 		    start, end));
821 		/*
822 		 * Now that we know the region is free, release it and hand it
823 		 * out piece by piece.
824 		 */
825 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
826 		for (tmp = 0; tmp < count; tmp++) {
827 			if (barlist[tmp]->res == NULL &&
828 			    barlist[tmp]->type == SYS_RES_MEMORY) {
829 				barlist[tmp]->res = bus_alloc_resource(cbdev,
830 				    barlist[tmp]->type, &barlist[tmp]->rid,
831 				    start, end, barlist[tmp]->count,
832 				    rman_make_alignment_flags(
833 				    barlist[tmp]->count));
834 				if (barlist[tmp]->res == NULL) {
835 					DEVPRINTF((cbdev, "Cannot pre-allocate "
836 					    "memory for cardbus device\n"));
837 					free(barlist, M_DEVBUF);
838 					return (ENOMEM);
839 				}
840 				barlist[tmp]->start =
841 				    rman_get_start(barlist[tmp]->res);
842 				barlist[tmp]->end = rman_get_end(
843 					barlist[tmp]->res);
844 				pci_write_config(child, barlist[tmp]->rid,
845 				    barlist[tmp]->start, 4);
846 				DEVPRINTF((cbdev, "Non-prefetchable memory "
847 				    "rid=%x at %lx-%lx (%lx)\n",
848 				    barlist[tmp]->rid, barlist[tmp]->start,
849 				    barlist[tmp]->end, barlist[tmp]->count));
850 			}
851 		}
852 	}
853 
854 	/* Allocate IO ports */
855 	flags = 0;
856 	for (tmp = 0; tmp < count; tmp++) {
857 		if (barlist[tmp]->res == NULL &&
858 		    barlist[tmp]->type == SYS_RES_IOPORT) {
859 			flags = rman_make_alignment_flags(barlist[tmp]->count);
860 			break;
861 		}
862 	}
863 	if (flags > 0) { /* If any IO port is requested... */
864 		/*
865 		 * First we allocate one big space for all resources of this
866 		 * type.  We do this because our parent, pccbb, needs to open
867 		 * a window to forward all addresses within the window, and
868 		 * it would be best if nobody else has resources allocated
869 		 * within the window.
870 		 * (XXX: Perhaps there might be a better way to do this?)
871 		 */
872 		rid = 0;
873 		res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
874 		    (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
875 		start = rman_get_start(res);
876 		end = rman_get_end(res);
877 		DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
878 		/*
879 		 * Now that we know the region is free, release it and hand it
880 		 * out piece by piece.
881 		 */
882 		bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
883 		for (tmp = 0; tmp < count; tmp++) {
884 			if (barlist[tmp]->res == NULL &&
885 			    barlist[tmp]->type == SYS_RES_IOPORT) {
886 				barlist[tmp]->res = bus_alloc_resource(cbdev,
887 				    barlist[tmp]->type, &barlist[tmp]->rid,
888 				    start, end, barlist[tmp]->count,
889 				    rman_make_alignment_flags(
890 				    barlist[tmp]->count));
891 				if (barlist[tmp]->res == NULL) {
892 					DEVPRINTF((cbdev, "Cannot pre-allocate "
893 					    "IO port for cardbus device\n"));
894 					free(barlist, M_DEVBUF);
895 					return (ENOMEM);
896 				}
897 				barlist[tmp]->start =
898 				    rman_get_start(barlist[tmp]->res);
899 				barlist[tmp]->end =
900 				    rman_get_end(barlist[tmp]->res);
901 			pci_write_config(child, barlist[tmp]->rid,
902 			    barlist[tmp]->start, 4);
903 			DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
904 			    barlist[tmp]->rid, barlist[tmp]->start,
905 			    barlist[tmp]->end));
906 			}
907 		}
908 	}
909 
910 	/* Allocate IRQ */
911 	rid = 0;
912 	res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
913 	    RF_SHAREABLE);
914 	resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
915 	    rman_get_start(res), rman_get_end(res), 1);
916 	rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
917 	rle->res = res;
918 	dinfo->pci.cfg.intline = rman_get_start(res);
919 	pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
920 
921 	free(barlist, M_DEVBUF);
922 	return (0);
923 }
924 
925 /*
926  * Adding a memory/io resource (sans CIS)
927  */
928 
929 static void
930 cardbus_add_map(device_t cbdev, device_t child, int reg)
931 {
932 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
933 	struct resource_list_entry *rle;
934 	uint32_t size;
935 	uint32_t testval;
936 	int type;
937 
938 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
939 		if (rle->rid == reg)
940 			return;
941 	}
942 
943 	if (reg == CARDBUS_ROM_REG)
944 		testval = CARDBUS_ROM_ADDRMASK;
945 	else
946 		testval = ~0;
947 
948 	pci_write_config(child, reg, testval, 4);
949 	testval = pci_read_config(child, reg, 4);
950 
951 	if (testval == ~0 || testval == 0)
952 		return;
953 
954 	if ((testval & 1) == 0)
955 		type = SYS_RES_MEMORY;
956 	else
957 		type = SYS_RES_IOPORT;
958 
959 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
960 	device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
961 	    reg, size);
962 	resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
963 }
964 
965 static void
966 cardbus_pickup_maps(device_t cbdev, device_t child)
967 {
968 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
969 	struct cardbus_quirk *q;
970 	int reg;
971 
972 	/*
973 	 * Try to pick up any resources that was not specified in CIS.
974 	 * Some devices (eg, 3c656) does not list all resources required by
975 	 * the driver in its CIS.
976 	 * XXX: should we do this or use quirks?
977 	 */
978 	for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
979 		cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
980 	}
981 
982 	for (q = &cardbus_quirks[0]; q->devid; q++) {
983 		if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
984 		    && q->type == CARDBUS_QUIRK_MAP_REG) {
985 			cardbus_add_map(cbdev, child, q->arg1);
986 		}
987 	}
988 }
989 
990 int
991 cardbus_cis_read(device_t cbdev, device_t child, uint8_t id,
992     struct cis_tupleinfo **buff, int *nret)
993 {
994 	struct tuple_callbacks cisread_callbacks[] = {
995 		MAKETUPLE(NULL,			nothing),
996 		/* first entry will be overwritten */
997 		MAKETUPLE(NULL,			nothing),
998 		MAKETUPLE(DEVICE,		nothing),
999 		MAKETUPLE(LONG_LINK_CB,		unhandled),
1000 		MAKETUPLE(INDIRECT,		unhandled),
1001 		MAKETUPLE(CONFIG_CB,		nothing),
1002 		MAKETUPLE(CFTABLE_ENTRY_CB,	nothing),
1003 		MAKETUPLE(LONGLINK_MFC,		unhandled),
1004 		MAKETUPLE(BAR,			nothing),
1005 		MAKETUPLE(PWR_MGMNT,		nothing),
1006 		MAKETUPLE(EXTDEVICE,		nothing),
1007 		MAKETUPLE(CHECKSUM,		nothing),
1008 		MAKETUPLE(LONGLINK_A,		unhandled),
1009 		MAKETUPLE(LONGLINK_C,		unhandled),
1010 		MAKETUPLE(LINKTARGET,		nothing),
1011 		MAKETUPLE(NO_LINK,		nothing),
1012 		MAKETUPLE(VERS_1,		nothing),
1013 		MAKETUPLE(ALTSTR,		nothing),
1014 		MAKETUPLE(DEVICE_A,		nothing),
1015 		MAKETUPLE(JEDEC_C,		nothing),
1016 		MAKETUPLE(JEDEC_A,		nothing),
1017 		MAKETUPLE(CONFIG,		nothing),
1018 		MAKETUPLE(CFTABLE_ENTRY,	nothing),
1019 		MAKETUPLE(DEVICE_OC,		nothing),
1020 		MAKETUPLE(DEVICE_OA,		nothing),
1021 		MAKETUPLE(DEVICE_GEO,		nothing),
1022 		MAKETUPLE(DEVICE_GEO_A,		nothing),
1023 		MAKETUPLE(MANFID,		nothing),
1024 		MAKETUPLE(FUNCID,		nothing),
1025 		MAKETUPLE(FUNCE,		nothing),
1026 		MAKETUPLE(SWIL,			nothing),
1027 		MAKETUPLE(VERS_2,		nothing),
1028 		MAKETUPLE(FORMAT,		nothing),
1029 		MAKETUPLE(GEOMETRY,		nothing),
1030 		MAKETUPLE(BYTEORDER,		nothing),
1031 		MAKETUPLE(DATE,			nothing),
1032 		MAKETUPLE(BATTERY,		nothing),
1033 		MAKETUPLE(ORG,			nothing),
1034 		MAKETUPLE(END,			end),
1035 		MAKETUPLE(GENERIC,		nothing),
1036 	};
1037 	int ret;
1038 
1039 	cisread_callbacks[0].id = id;
1040 	cisread_callbacks[0].name = "COPY";
1041 	cisread_callbacks[0].func = decode_tuple_copy;
1042 	ncisread_buf = 0;
1043 	cisread_buf = NULL;
1044 	ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
1045 
1046 	*buff = cisread_buf;
1047 	*nret = ncisread_buf;
1048 	return (ret);
1049 }
1050 
1051 void
1052 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
1053 {
1054 	int i;
1055 	for (i = 0; i < *nret; i++)
1056 		free(buff[i].data, M_DEVBUF);
1057 	if (*nret > 0)
1058 		free(buff, M_DEVBUF);
1059 }
1060 
1061 int
1062 cardbus_do_cis(device_t cbdev, device_t child)
1063 {
1064 	int ret;
1065 	struct tuple_callbacks init_callbacks[] = {
1066 		MAKETUPLE(NULL,			generic),
1067 		MAKETUPLE(DEVICE,		generic),
1068 		MAKETUPLE(LONG_LINK_CB,		unhandled),
1069 		MAKETUPLE(INDIRECT,		unhandled),
1070 		MAKETUPLE(CONFIG_CB,		generic),
1071 		MAKETUPLE(CFTABLE_ENTRY_CB,	generic),
1072 		MAKETUPLE(LONGLINK_MFC,		unhandled),
1073 		MAKETUPLE(BAR,			bar),
1074 		MAKETUPLE(PWR_MGMNT,		generic),
1075 		MAKETUPLE(EXTDEVICE,		generic),
1076 		MAKETUPLE(CHECKSUM,		generic),
1077 		MAKETUPLE(LONGLINK_A,		unhandled),
1078 		MAKETUPLE(LONGLINK_C,		unhandled),
1079 		MAKETUPLE(LINKTARGET,		linktarget),
1080 		MAKETUPLE(NO_LINK,		generic),
1081 		MAKETUPLE(VERS_1,		vers_1),
1082 		MAKETUPLE(ALTSTR,		generic),
1083 		MAKETUPLE(DEVICE_A,		generic),
1084 		MAKETUPLE(JEDEC_C,		generic),
1085 		MAKETUPLE(JEDEC_A,		generic),
1086 		MAKETUPLE(CONFIG,		generic),
1087 		MAKETUPLE(CFTABLE_ENTRY,	generic),
1088 		MAKETUPLE(DEVICE_OC,		generic),
1089 		MAKETUPLE(DEVICE_OA,		generic),
1090 		MAKETUPLE(DEVICE_GEO,		generic),
1091 		MAKETUPLE(DEVICE_GEO_A,		generic),
1092 		MAKETUPLE(MANFID,		manfid),
1093 		MAKETUPLE(FUNCID,		funcid),
1094 		MAKETUPLE(FUNCE,		funce),
1095 		MAKETUPLE(SWIL,			generic),
1096 		MAKETUPLE(VERS_2,		generic),
1097 		MAKETUPLE(FORMAT,		generic),
1098 		MAKETUPLE(GEOMETRY,		generic),
1099 		MAKETUPLE(BYTEORDER,		generic),
1100 		MAKETUPLE(DATE,			generic),
1101 		MAKETUPLE(BATTERY,		generic),
1102 		MAKETUPLE(ORG,			generic),
1103 		MAKETUPLE(END,			end),
1104 		MAKETUPLE(GENERIC,		generic),
1105 	};
1106 
1107 	ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1108 	if (ret < 0)
1109 		return (ret);
1110 	cardbus_pickup_maps(cbdev, child);
1111 	return (cardbus_alloc_resources(cbdev, child));
1112 }
1113