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