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