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