xref: /freebsd/sys/dev/cardbus/cardbus_cis.c (revision 6d9fcd03be9d12ba58aa72276c309fd4bd02b26c)
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 (reg & TPL_BAR_REG_BELOW1MB)
427 			dinfo->mbelow1mb |= BARBIT(bar);
428 	}
429 
430 	/*
431 	 * Sanity check the BAR length reported in the CIS with the length
432 	 * encoded in the PCI BAR.  The latter seems to be more reliable.
433 	 * XXX - This probably belongs elsewhere.
434 	 */
435 	pci_write_config(child, bar, 0xffffffff, 4);
436 	pci_bar = pci_read_config(child, bar, 4);
437 	if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) {
438 		if (type == SYS_RES_MEMORY) {
439 			pci_bar &= ~0xf;
440 		} else {
441 			pci_bar &= ~0x3;
442 		}
443 		len = 1 << (ffs(pci_bar) - 1);
444 	}
445 
446 	DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
447 	    (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
448 	    (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
449 	    " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
450 	    ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : ""));
451 
452 	resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
453 
454 	/*
455 	 * Mark the appropriate bit in the PCI command register so that
456 	 * device drivers will know which type of BARs can be used.
457 	 */
458 	pci_enable_io(child, type);
459 	return (0);
460 }
461 
462 static int
463 decode_tuple_unhandled(device_t cbdev, device_t child, int id,
464     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
465     struct tuple_callbacks *info)
466 {
467 	/* Make this message suck less XXX */
468 	printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
469 	return (-1);
470 }
471 
472 static int
473 decode_tuple_end(device_t cbdev, device_t child, int id,
474     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
475     struct tuple_callbacks *info)
476 {
477 	if (cardbus_cis_debug) {
478 		printf("CIS reading done\n");
479 	}
480 	return (0);
481 }
482 
483 /*
484  * Functions to read the a tuple from the card
485  */
486 
487 static int
488 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
489     uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
490 {
491 	int i, j;
492 	uint32_t e;
493 	uint32_t loc;
494 
495 	loc = start + *off;
496 
497 	e = pci_read_config(child, loc - loc % 4, 4);
498 	for (j = loc % 4; j > 0; j--)
499 		e >>= 8;
500 	*len = 0;
501 	for (i = loc, j = -2; j < *len; j++, i++) {
502 		if (i % 4 == 0)
503 			e = pci_read_config(child, i, 4);
504 		if (j == -2)
505 			*tupleid = 0xff & e;
506 		else if (j == -1)
507 			*len = 0xff & e;
508 		else
509 			tupledata[j] = 0xff & e;
510 		e >>= 8;
511 	}
512 	*off += *len + 2;
513 	return (0);
514 }
515 
516 static int
517 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
518     uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
519 {
520 	bus_space_tag_t bt;
521 	bus_space_handle_t bh;
522 	int ret;
523 
524 	bt = rman_get_bustag(res);
525 	bh = rman_get_bushandle(res);
526 
527 	*tupleid = bus_space_read_1(bt, bh, start + *off);
528 	*len = bus_space_read_1(bt, bh, start + *off + 1);
529 	bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
530 	ret = 0;
531 	*off += *len + 2;
532 	return (ret);
533 }
534 
535 static int
536 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
537     uint32_t start, uint32_t *off, int *tupleid, int *len,
538     uint8_t *tupledata)
539 {
540 	if (res == (struct resource*)~0UL) {
541 		return (cardbus_read_tuple_conf(cbdev, child, start, off,
542 		    tupleid, len, tupledata));
543 	} else {
544 		return (cardbus_read_tuple_mem(cbdev, res, start, off,
545 		    tupleid, len, tupledata));
546 	}
547 }
548 
549 static void
550 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
551     struct resource *res)
552 {
553 	if (res != (struct resource*)~0UL) {
554 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
555 		pci_write_config(child, rid, 0, 4);
556 		PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
557 	}
558 }
559 
560 static struct resource *
561 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
562     int *rid)
563 {
564 	uint32_t testval;
565 	uint32_t size;
566 	struct resource *res;
567 
568 	switch (CARDBUS_CIS_SPACE(*start)) {
569 	case CARDBUS_CIS_ASI_TUPLE:
570 		/* CIS in PCI config space need no initialization */
571 		return ((struct resource*)~0UL);
572 	case CARDBUS_CIS_ASI_BAR0:
573 	case CARDBUS_CIS_ASI_BAR1:
574 	case CARDBUS_CIS_ASI_BAR2:
575 	case CARDBUS_CIS_ASI_BAR3:
576 	case CARDBUS_CIS_ASI_BAR4:
577 	case CARDBUS_CIS_ASI_BAR5:
578 		*rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
579 		break;
580 	case CARDBUS_CIS_ASI_ROM:
581 		*rid = CARDBUS_ROM_REG;
582 #if 0
583 		/*
584 		 * This mask doesn't contain the bit that actually enables
585 		 * the Option ROM.
586 		 */
587 		pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
588 #endif
589 		break;
590 	default:
591 		device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
592 		    CARDBUS_CIS_SPACE(*start));
593 		return (NULL);
594 	}
595 
596 	/* figure out how much space we need */
597 	pci_write_config(child, *rid, 0xffffffff, 4);
598 	testval = pci_read_config(child, *rid, 4);
599 
600 	/*
601 	 * This bit has a different meaning depending if we are dealing
602 	 * with a normal BAR or an Option ROM BAR.
603 	 */
604 	if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
605 		device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
606 		return (NULL);
607 	}
608 
609 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
610 	/* XXX Is this some kind of hack? */
611 	if (size < 4096)
612 		size = 4096;
613 	/* allocate the memory space to read CIS */
614 	res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
615 	    rman_make_alignment_flags(size) | RF_ACTIVE);
616 	if (res == NULL) {
617 		device_printf(cbdev, "Unable to allocate resource "
618 		    "to read CIS.\n");
619 		return (NULL);
620 	}
621 	pci_write_config(child, *rid,
622 	    rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
623 		CARDBUS_ROM_ENABLE : 0),
624 	    4);
625 	PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
626 
627 	/* Flip to the right ROM image if CIS is in ROM */
628 	if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
629 		bus_space_tag_t bt;
630 		bus_space_handle_t bh;
631 		uint32_t imagesize;
632 		uint32_t imagebase = 0;
633 		uint32_t pcidata;
634 		uint16_t romsig;
635 		int romnum = 0;
636 		int imagenum;
637 
638 		bt = rman_get_bustag(res);
639 		bh = rman_get_bushandle(res);
640 
641 		imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
642 		for (romnum = 0;; romnum++) {
643 			romsig = bus_space_read_2(bt, bh,
644 			    imagebase + CARDBUS_EXROM_SIGNATURE);
645 			if (romsig != 0xaa55) {
646 				device_printf(cbdev, "Bad header in rom %d: "
647 				    "[%x] %04x\n", romnum, imagebase +
648 				    CARDBUS_EXROM_SIGNATURE, romsig);
649 				bus_release_resource(cbdev, SYS_RES_MEMORY,
650 				    *rid, res);
651 				*rid = 0;
652 				return (NULL);
653 			}
654 
655 			/*
656 			 * If this was the Option ROM image that we were
657 			 * looking for, then we are done.
658 			 */
659 			if (romnum == imagenum)
660 				break;
661 
662 			/* Find out where the next Option ROM image is */
663 			pcidata = imagebase + bus_space_read_2(bt, bh,
664 			    imagebase + CARDBUS_EXROM_DATA_PTR);
665 			imagesize = bus_space_read_2(bt, bh,
666 			    pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
667 
668 			if (imagesize == 0) {
669 				/*
670 				 * XXX some ROMs seem to have this as zero,
671 				 * can we assume this means 1 block?
672 				 */
673 				device_printf(cbdev, "Warning, size of Option "
674 				    "ROM image %d is 0 bytes, assuming 512 "
675 				    "bytes.\n", romnum);
676 				imagesize = 1;
677 			}
678 
679 			/* Image size is in 512 byte units */
680 			imagesize <<= 9;
681 
682 			if ((bus_space_read_1(bt, bh, pcidata +
683 			    CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
684 				device_printf(cbdev, "Cannot find CIS in "
685 				    "Option ROM\n");
686 				bus_release_resource(cbdev, SYS_RES_MEMORY,
687 				    *rid, res);
688 				*rid = 0;
689 				return (NULL);
690 			}
691 			imagebase += imagesize;
692 		}
693 		*start = imagebase + CARDBUS_CIS_ADDR(*start);
694 	} else {
695 		*start = CARDBUS_CIS_ADDR(*start);
696 	}
697 
698 	return (res);
699 }
700 
701 /*
702  * Dispatch the right handler function per tuple
703  */
704 
705 static int
706 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
707     uint8_t *tupledata, uint32_t start, uint32_t *off,
708     struct tuple_callbacks *callbacks)
709 {
710 	int i;
711 	for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
712 		if (tupleid == callbacks[i].id)
713 			return (callbacks[i].func(cbdev, child, tupleid, len,
714 			    tupledata, start, off, &callbacks[i]));
715 	}
716 
717 	if (tupleid < CISTPL_CUSTOMSTART) {
718 		device_printf(cbdev, "Undefined tuple encountered, "
719 		    "CIS parsing terminated\n");
720 		return (EINVAL);
721 	}
722 	return (callbacks[i].func(cbdev, child, tupleid, len,
723 	    tupledata, start, off, NULL));
724 }
725 
726 static int
727 cardbus_parse_cis(device_t cbdev, device_t child,
728     struct tuple_callbacks *callbacks)
729 {
730 	uint8_t tupledata[MAXTUPLESIZE];
731 	int tupleid;
732 	int len;
733 	int expect_linktarget;
734 	uint32_t start, off;
735 	struct resource *res;
736 	int rid;
737 
738 	bzero(tupledata, MAXTUPLESIZE);
739 	expect_linktarget = TRUE;
740 	if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
741 		return (ENXIO);
742 	off = 0;
743 	res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
744 	if (res == NULL)
745 		return (ENXIO);
746 
747 	do {
748 		if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
749 		    &tupleid, &len, tupledata)) {
750 			device_printf(cbdev, "Failed to read CIS.\n");
751 			cardbus_read_tuple_finish(cbdev, child, rid, res);
752 			return (ENXIO);
753 		}
754 
755 		if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
756 			device_printf(cbdev, "Expecting link target, got 0x%x\n",
757 			    tupleid);
758 			cardbus_read_tuple_finish(cbdev, child, rid, res);
759 			return (EINVAL);
760 		}
761 		expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
762 		    tupledata, start, &off, callbacks);
763 		if (expect_linktarget != 0) {
764 			cardbus_read_tuple_finish(cbdev, child, rid, res);
765 			return (expect_linktarget);
766 		}
767 	} while (tupleid != CISTPL_END);
768 	cardbus_read_tuple_finish(cbdev, child, rid, res);
769 	return (0);
770 }
771 
772 static void
773 cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start)
774 {
775 	rle->start = start;
776 	rle->end = start + rle->count - 1;
777 	pci_write_config(child, rle->rid, rle->start, 4);
778 }
779 
780 static int
781 barsort(const void *a, const void *b)
782 {
783 	return ((*(const struct resource_list_entry * const *)b)->count -
784 	    (*(const struct resource_list_entry * const *)a)->count);
785 }
786 
787 static int
788 cardbus_alloc_resources(device_t cbdev, device_t child)
789 {
790 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
791 	int count;
792 	struct resource_list_entry *rle;
793 	struct resource_list_entry **barlist;
794 	int tmp;
795 	uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
796 	struct resource *res;
797 	uint32_t start,end;
798 	int rid, flags;
799 
800 	count = 0;
801 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
802 		count++;
803 	}
804 	if (count == 0)
805 		return (0);
806 	barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
807 	    M_WAITOK);
808 	count = 0;
809 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
810 		barlist[count] = rle;
811 		if (rle->type == SYS_RES_IOPORT) {
812 			io_size += rle->count;
813 		} else if (rle->type == SYS_RES_MEMORY) {
814 			if (dinfo->mprefetchable & BARBIT(rle->rid))
815 				mem_psize += rle->count;
816 			else
817 				mem_nsize += rle->count;
818 		}
819 		count++;
820 	}
821 
822 	/*
823 	 * We want to allocate the largest resource first, so that our
824 	 * allocated memory is packed.
825 	 */
826 	qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
827 
828 	/* Allocate prefetchable memory */
829 	flags = 0;
830 	for (tmp = 0; tmp < count; tmp++) {
831 		rle = barlist[tmp];
832 		if (rle->res == NULL &&
833 		    rle->type == SYS_RES_MEMORY &&
834 		    dinfo->mprefetchable & BARBIT(rle->rid)) {
835 			flags = rman_make_alignment_flags(rle->count);
836 			break;
837 		}
838 	}
839 	if (flags > 0) { /* If any prefetchable memory is requested... */
840 		/*
841 		 * First we allocate one big space for all resources of this
842 		 * type.  We do this because our parent, pccbb, needs to open
843 		 * a window to forward all addresses within the window, and
844 		 * it would be best if nobody else has resources allocated
845 		 * within the window.
846 		 * (XXX: Perhaps there might be a better way to do this?)
847 		 */
848 		rid = 0;
849 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
850 		    (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
851 		    mem_psize, flags);
852 		if (res == NULL) {
853 			device_printf(cbdev,
854 			    "Can't get memory for prefetch mem\n");
855 			return (EIO);
856 		}
857 		start = rman_get_start(res);
858 		end = rman_get_end(res);
859 		DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
860 		/*
861 		 * Now that we know the region is free, release it and hand it
862 		 * out piece by piece.
863 		 */
864 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
865 		for (tmp = 0; tmp < count; tmp++) {
866 			rle = barlist[tmp];
867 			if (rle->type == SYS_RES_MEMORY &&
868 			    dinfo->mprefetchable & BARBIT(rle->rid)) {
869 				cardbus_do_res(rle, child, start);
870 				start += rle->count;
871 			}
872 		}
873 	}
874 
875 	/* Allocate non-prefetchable memory */
876 	flags = 0;
877 	for (tmp = 0; tmp < count; tmp++) {
878 		rle = barlist[tmp];
879 		if (rle->type == SYS_RES_MEMORY &&
880 		    (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
881 			flags = rman_make_alignment_flags(rle->count);
882 			break;
883 		}
884 	}
885 	if (flags > 0) { /* If any non-prefetchable memory is requested... */
886 		/*
887 		 * First we allocate one big space for all resources of this
888 		 * type.  We do this because our parent, pccbb, needs to open
889 		 * a window to forward all addresses within the window, and
890 		 * it would be best if nobody else has resources allocated
891 		 * within the window.
892 		 * (XXX: Perhaps there might be a better way to do this?)
893 		 */
894 		rid = 0;
895 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
896 		    ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
897 		    mem_nsize, flags);
898 		if (res == NULL) {
899 			device_printf(cbdev,
900 			    "Can't get memory for non-prefetch mem\n");
901 			return (EIO);
902 		}
903 		start = rman_get_start(res);
904 		end = rman_get_end(res);
905 		DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
906 		    start, end));
907 		/*
908 		 * Now that we know the region is free, release it and hand it
909 		 * out piece by piece.
910 		 */
911 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
912 		for (tmp = 0; tmp < count; tmp++) {
913 			rle = barlist[tmp];
914 			if (rle->type == SYS_RES_MEMORY &&
915 			    (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
916 				cardbus_do_res(rle, child, start);
917 				start += rle->count;
918 			}
919 		}
920 	}
921 
922 	/* Allocate IO ports */
923 	flags = 0;
924 	for (tmp = 0; tmp < count; tmp++) {
925 		rle = barlist[tmp];
926 		if (rle->type == SYS_RES_IOPORT) {
927 			flags = rman_make_alignment_flags(rle->count);
928 			break;
929 		}
930 	}
931 	if (flags > 0) { /* If any IO port is requested... */
932 		/*
933 		 * First we allocate one big space for all resources of this
934 		 * type.  We do this because our parent, pccbb, needs to open
935 		 * a window to forward all addresses within the window, and
936 		 * it would be best if nobody else has resources allocated
937 		 * within the window.
938 		 * (XXX: Perhaps there might be a better way to do this?)
939 		 */
940 		rid = 0;
941 		res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
942 		    (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
943 		if (res == NULL) {
944 			device_printf(cbdev,
945 			    "Can't get memory for IO ports\n");
946 			return (EIO);
947 		}
948 		start = rman_get_start(res);
949 		end = rman_get_end(res);
950 		DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
951 		/*
952 		 * Now that we know the region is free, release it and hand it
953 		 * out piece by piece.
954 		 */
955 		bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
956 		for (tmp = 0; tmp < count; tmp++) {
957 			rle = barlist[tmp];
958 			if (rle->type == SYS_RES_IOPORT) {
959 				cardbus_do_res(rle, child, start);
960 				start += rle->count;
961 			}
962 		}
963 	}
964 
965 	/* Allocate IRQ */
966 	rid = 0;
967 	res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
968 	    RF_SHAREABLE);
969 	if (res == NULL) {
970 		device_printf(cbdev, "Can't get memory for irq\n");
971 		return (EIO);
972 	}
973 	start = rman_get_start(res);
974 	end = rman_get_end(res);
975 	bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
976 	resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
977 	    1);
978 	dinfo->pci.cfg.intline = rman_get_start(res);
979 	pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
980 
981 	free(barlist, M_DEVBUF);
982 	return (0);
983 }
984 
985 /*
986  * Adding a memory/io resource (sans CIS)
987  */
988 
989 static void
990 cardbus_add_map(device_t cbdev, device_t child, int reg)
991 {
992 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
993 	struct resource_list_entry *rle;
994 	uint32_t size;
995 	uint32_t testval;
996 	int type;
997 
998 	SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
999 		if (rle->rid == reg)
1000 			return;
1001 	}
1002 
1003 	if (reg == CARDBUS_ROM_REG)
1004 		testval = CARDBUS_ROM_ADDRMASK;
1005 	else
1006 		testval = ~0;
1007 
1008 	pci_write_config(child, reg, testval, 4);
1009 	testval = pci_read_config(child, reg, 4);
1010 
1011 	if (testval == ~0 || testval == 0)
1012 		return;
1013 
1014 	if ((testval & 1) == 0)
1015 		type = SYS_RES_MEMORY;
1016 	else
1017 		type = SYS_RES_IOPORT;
1018 
1019 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
1020 	device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
1021 	    reg, size);
1022 	resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
1023 }
1024 
1025 static void
1026 cardbus_pickup_maps(device_t cbdev, device_t child)
1027 {
1028 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
1029 	struct cardbus_quirk *q;
1030 	int reg;
1031 
1032 	/*
1033 	 * Try to pick up any resources that was not specified in CIS.
1034 	 * Some devices (eg, 3c656) does not list all resources required by
1035 	 * the driver in its CIS.
1036 	 * XXX: should we do this or use quirks?
1037 	 */
1038 	for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
1039 		cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
1040 	}
1041 
1042 	for (q = &cardbus_quirks[0]; q->devid; q++) {
1043 		if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
1044 		    && q->type == CARDBUS_QUIRK_MAP_REG) {
1045 			cardbus_add_map(cbdev, child, q->arg1);
1046 		}
1047 	}
1048 }
1049 
1050 int
1051 cardbus_cis_read(device_t cbdev, device_t child, uint8_t id,
1052     struct cis_tupleinfo **buff, int *nret)
1053 {
1054 	struct tuple_callbacks cisread_callbacks[] = {
1055 		MAKETUPLE(NULL,			nothing),
1056 		/* first entry will be overwritten */
1057 		MAKETUPLE(NULL,			nothing),
1058 		MAKETUPLE(DEVICE,		nothing),
1059 		MAKETUPLE(LONG_LINK_CB,		unhandled),
1060 		MAKETUPLE(INDIRECT,		unhandled),
1061 		MAKETUPLE(CONFIG_CB,		nothing),
1062 		MAKETUPLE(CFTABLE_ENTRY_CB,	nothing),
1063 		MAKETUPLE(LONGLINK_MFC,		unhandled),
1064 		MAKETUPLE(BAR,			nothing),
1065 		MAKETUPLE(PWR_MGMNT,		nothing),
1066 		MAKETUPLE(EXTDEVICE,		nothing),
1067 		MAKETUPLE(CHECKSUM,		nothing),
1068 		MAKETUPLE(LONGLINK_A,		unhandled),
1069 		MAKETUPLE(LONGLINK_C,		unhandled),
1070 		MAKETUPLE(LINKTARGET,		nothing),
1071 		MAKETUPLE(NO_LINK,		nothing),
1072 		MAKETUPLE(VERS_1,		nothing),
1073 		MAKETUPLE(ALTSTR,		nothing),
1074 		MAKETUPLE(DEVICE_A,		nothing),
1075 		MAKETUPLE(JEDEC_C,		nothing),
1076 		MAKETUPLE(JEDEC_A,		nothing),
1077 		MAKETUPLE(CONFIG,		nothing),
1078 		MAKETUPLE(CFTABLE_ENTRY,	nothing),
1079 		MAKETUPLE(DEVICE_OC,		nothing),
1080 		MAKETUPLE(DEVICE_OA,		nothing),
1081 		MAKETUPLE(DEVICE_GEO,		nothing),
1082 		MAKETUPLE(DEVICE_GEO_A,		nothing),
1083 		MAKETUPLE(MANFID,		nothing),
1084 		MAKETUPLE(FUNCID,		nothing),
1085 		MAKETUPLE(FUNCE,		nothing),
1086 		MAKETUPLE(SWIL,			nothing),
1087 		MAKETUPLE(VERS_2,		nothing),
1088 		MAKETUPLE(FORMAT,		nothing),
1089 		MAKETUPLE(GEOMETRY,		nothing),
1090 		MAKETUPLE(BYTEORDER,		nothing),
1091 		MAKETUPLE(DATE,			nothing),
1092 		MAKETUPLE(BATTERY,		nothing),
1093 		MAKETUPLE(ORG,			nothing),
1094 		MAKETUPLE(END,			end),
1095 		MAKETUPLE(GENERIC,		nothing),
1096 	};
1097 	int ret;
1098 
1099 	cisread_callbacks[0].id = id;
1100 	cisread_callbacks[0].name = "COPY";
1101 	cisread_callbacks[0].func = decode_tuple_copy;
1102 	ncisread_buf = 0;
1103 	cisread_buf = NULL;
1104 	ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
1105 
1106 	*buff = cisread_buf;
1107 	*nret = ncisread_buf;
1108 	return (ret);
1109 }
1110 
1111 void
1112 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
1113 {
1114 	int i;
1115 	for (i = 0; i < *nret; i++)
1116 		free(buff[i].data, M_DEVBUF);
1117 	if (*nret > 0)
1118 		free(buff, M_DEVBUF);
1119 }
1120 
1121 int
1122 cardbus_do_cis(device_t cbdev, device_t child)
1123 {
1124 	int ret;
1125 	struct tuple_callbacks init_callbacks[] = {
1126 		MAKETUPLE(NULL,			generic),
1127 		MAKETUPLE(DEVICE,		generic),
1128 		MAKETUPLE(LONG_LINK_CB,		unhandled),
1129 		MAKETUPLE(INDIRECT,		unhandled),
1130 		MAKETUPLE(CONFIG_CB,		generic),
1131 		MAKETUPLE(CFTABLE_ENTRY_CB,	generic),
1132 		MAKETUPLE(LONGLINK_MFC,		unhandled),
1133 		MAKETUPLE(BAR,			bar),
1134 		MAKETUPLE(PWR_MGMNT,		generic),
1135 		MAKETUPLE(EXTDEVICE,		generic),
1136 		MAKETUPLE(CHECKSUM,		generic),
1137 		MAKETUPLE(LONGLINK_A,		unhandled),
1138 		MAKETUPLE(LONGLINK_C,		unhandled),
1139 		MAKETUPLE(LINKTARGET,		linktarget),
1140 		MAKETUPLE(NO_LINK,		generic),
1141 		MAKETUPLE(VERS_1,		vers_1),
1142 		MAKETUPLE(ALTSTR,		generic),
1143 		MAKETUPLE(DEVICE_A,		generic),
1144 		MAKETUPLE(JEDEC_C,		generic),
1145 		MAKETUPLE(JEDEC_A,		generic),
1146 		MAKETUPLE(CONFIG,		generic),
1147 		MAKETUPLE(CFTABLE_ENTRY,	generic),
1148 		MAKETUPLE(DEVICE_OC,		generic),
1149 		MAKETUPLE(DEVICE_OA,		generic),
1150 		MAKETUPLE(DEVICE_GEO,		generic),
1151 		MAKETUPLE(DEVICE_GEO_A,		generic),
1152 		MAKETUPLE(MANFID,		manfid),
1153 		MAKETUPLE(FUNCID,		funcid),
1154 		MAKETUPLE(FUNCE,		funce),
1155 		MAKETUPLE(SWIL,			generic),
1156 		MAKETUPLE(VERS_2,		generic),
1157 		MAKETUPLE(FORMAT,		generic),
1158 		MAKETUPLE(GEOMETRY,		generic),
1159 		MAKETUPLE(BYTEORDER,		generic),
1160 		MAKETUPLE(DATE,			generic),
1161 		MAKETUPLE(BATTERY,		generic),
1162 		MAKETUPLE(ORG,			generic),
1163 		MAKETUPLE(END,			end),
1164 		MAKETUPLE(GENERIC,		generic),
1165 	};
1166 
1167 	ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1168 	if (ret < 0)
1169 		return (ret);
1170 	cardbus_pickup_maps(cbdev, child);
1171 	return (cardbus_alloc_resources(cbdev, child));
1172 }
1173