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