2 * Copyright (c) 2000,2001 Jonathan Chen.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
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
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.1 2004/02/10 07:55:47 joerg Exp $
33 * CIS Handling for the Cardbus Bus
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
42 #include <machine/bus.h>
43 #include <machine/resource.h>
46 #include <sys/pciio.h>
47 #include <bus/pci/pcivar.h>
48 #include <bus/pci/pcireg.h>
50 #include <dev/pccard/cardbus/cardbusreg.h>
51 #include <dev/pccard/cardbus/cardbusvar.h>
52 #include <dev/pccard/cardbus/cardbus_cis.h>
54 #include <bus/pccard/pccardvar.h>
56 extern int cardbus_cis_debug;
58 #define DPRINTF(a) if (cardbus_cis_debug) printf a
59 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
61 #define DECODE_PARAMS \
62 (device_t cbdev, device_t child, int id, int len, \
63 u_int8_t *tupledata, u_int32_t start, u_int32_t *off, \
64 struct tuple_callbacks *info)
66 struct tuple_callbacks {
69 int (*func) DECODE_PARAMS;
72 #define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS
73 DECODE_PROTOTYPE(generic);
74 DECODE_PROTOTYPE(nothing);
75 DECODE_PROTOTYPE(copy);
76 DECODE_PROTOTYPE(linktarget);
77 DECODE_PROTOTYPE(vers_1);
78 DECODE_PROTOTYPE(funcid);
79 DECODE_PROTOTYPE(manfid);
80 DECODE_PROTOTYPE(funce);
81 DECODE_PROTOTYPE(bar);
82 DECODE_PROTOTYPE(unhandled);
83 DECODE_PROTOTYPE(end);
84 static int cardbus_read_tuple_conf(device_t cbdev, device_t child,
85 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
87 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
88 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
90 static int cardbus_read_tuple(device_t cbdev, device_t child,
91 struct resource *res, u_int32_t start, u_int32_t *off,
92 int *tupleid, int *len, u_int8_t *tupledata);
93 static void cardbus_read_tuple_finish(device_t cbdev, device_t child,
94 int rid, struct resource *res);
95 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child,
96 u_int32_t *start, int *rid);
97 static int decode_tuple(device_t cbdev, device_t child, int tupleid,
98 int len, u_int8_t *tupledata, u_int32_t start,
99 u_int32_t *off, struct tuple_callbacks *callbacks);
100 static int cardbus_parse_cis(device_t cbdev, device_t child,
101 struct tuple_callbacks *callbacks);
102 static int barsort(const void *a, const void *b);
103 static int cardbus_alloc_resources(device_t cbdev, device_t child);
104 static void cardbus_add_map(device_t cbdev, device_t child, int reg);
105 static void cardbus_pickup_maps(device_t cbdev, device_t child);
108 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
110 static char *funcnames[] = {
123 struct cardbus_quirk {
124 u_int32_t devid; /* Vendor/device of the card */
126 #define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */
131 struct cardbus_quirk cardbus_quirks[] = {
135 static struct cis_tupleinfo *cisread_buf;
136 static int ncisread_buf;
139 * Handler functions for various CIS tuples
142 DECODE_PROTOTYPE(generic)
148 printf("TUPLE: %s [%d]:", info->name, len);
150 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
152 for (i = 0; i < len; i++) {
153 if (i % 0x10 == 0 && len > 0x10)
154 printf("\n 0x%02x:", i);
155 printf(" %02x", tupledata[i]);
162 DECODE_PROTOTYPE(nothing)
167 DECODE_PROTOTYPE(copy)
169 struct cis_tupleinfo *tmpbuf;
171 tmpbuf = malloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1),
173 if (ncisread_buf > 0) {
174 memcpy(tmpbuf, cisread_buf,
175 sizeof(struct cis_tupleinfo) * ncisread_buf);
176 free(cisread_buf, M_DEVBUF);
178 cisread_buf = tmpbuf;
180 cisread_buf[ncisread_buf].id = id;
181 cisread_buf[ncisread_buf].len = len;
182 cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, M_WAITOK);
183 memcpy(cisread_buf[ncisread_buf].data, tupledata, len);
188 DECODE_PROTOTYPE(linktarget)
193 printf("TUPLE: %s [%d]:", info->name, len);
195 for (i = 0; i < len; i++) {
196 if (i % 0x10 == 0 && len > 0x10)
197 printf("\n 0x%02x:", i);
198 printf(" %02x", tupledata[i]);
202 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
203 tupledata[2] != 'S') {
204 printf("Invalid data for CIS Link Target!\n");
205 decode_tuple_generic(cbdev, child, id, len, tupledata,
212 DECODE_PROTOTYPE(vers_1)
216 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
217 printf("Product name: ");
218 for (i = 2; i < len; i++) {
219 if (tupledata[i] == '\0')
221 else if (tupledata[i] == 0xff)
224 printf("%c", tupledata[i]);
230 DECODE_PROTOTYPE(funcid)
232 struct cardbus_devinfo *dinfo = device_get_ivars(child);
233 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
236 printf("Functions: ");
237 for (i = 0; i < len; i++) {
238 if (tupledata[i] < numnames)
239 printf("%s", funcnames[tupledata[i]]);
241 printf("Unknown(%d)", tupledata[i]);
247 dinfo->funcid = tupledata[0]; /* use first in list */
252 DECODE_PROTOTYPE(manfid)
254 struct cardbus_devinfo *dinfo = device_get_ivars(child);
257 printf("Manufacturer ID: ");
258 for (i = 0; i < len; i++)
259 printf("%02x", tupledata[i]);
263 dinfo->mfrid = tupledata[1] | (tupledata[2]<<8);
264 dinfo->prodid = tupledata[3] | (tupledata[4]<<8);
269 DECODE_PROTOTYPE(funce)
271 struct cardbus_devinfo *dinfo = device_get_ivars(child);
274 printf("Function Extension: ");
275 for (i = 0; i < len; i++)
276 printf("%02x", tupledata[i]);
278 if (len < 2) /* too short */
280 type = tupledata[0]; /* XXX <32 always? */
281 switch (dinfo->funcid) {
282 case TPL_FUNC_SERIAL:
283 if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */
284 dinfo->funce.sio.type = tupledata[1] & 0x1f;
286 dinfo->fepresent |= 1<<type;
290 case TPL_FUNCE_LAN_TECH:
291 dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */
294 case TPL_FUNCE_LAN_SPEED:
295 for (i = 0; i < 3; i++) {
296 if (dinfo->funce.lan.speed[i] == 0) {
298 dinfo->funce.lan.speed[i] =
306 case TPL_FUNCE_LAN_MEDIA:
307 for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
308 if (dinfo->funce.lan.media[i] == 0) {
309 /* NB: len known > 1 */
310 dinfo->funce.lan.media[i] =
311 tupledata[1]; /*XXX? mask */
316 case TPL_FUNCE_LAN_NID:
318 bcopy(&tupledata[1], dinfo->funce.lan.nid, 6);
320 case TPL_FUNCE_LAN_CONN:
321 dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
324 dinfo->fepresent |= 1<<type;
330 DECODE_PROTOTYPE(bar)
332 struct cardbus_devinfo *dinfo = device_get_ivars(child);
338 printf("*** ERROR *** BAR length not 6 (%d)\n", len);
341 reg = *(u_int16_t*)tupledata;
342 len = *(u_int32_t*)(tupledata + 2);
343 if (reg & TPL_BAR_REG_AS) {
344 type = SYS_RES_IOPORT;
346 type = SYS_RES_MEMORY;
348 bar = (reg & TPL_BAR_REG_ASI_MASK) - 1;
349 if (bar < 0 || bar > 5 ||
350 (type == SYS_RES_IOPORT && bar == 5)) {
351 device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n",
355 bar = CARDBUS_BASE0_REG + bar * 4;
356 if (type == SYS_RES_MEMORY) {
357 if (bar & TPL_BAR_REG_PREFETCHABLE)
358 dinfo->mprefetchable |= BARBIT(bar);
359 if (bar & TPL_BAR_REG_BELOW1MB)
360 dinfo->mbelow1mb |= BARBIT(bar);
361 } else if (type == SYS_RES_IOPORT) {
362 if (bar & TPL_BAR_REG_BELOW1MB)
363 dinfo->ibelow1mb |= BARBIT(bar);
365 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
366 (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
367 (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
368 " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
369 ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") :
370 (dinfo->ibelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "" ));
372 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
375 * Mark the appropriate bit in the PCI command register so that
376 * device drivers will know which type of BARs can be used.
378 pci_enable_io(child, type);
382 DECODE_PROTOTYPE(unhandled)
384 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
388 DECODE_PROTOTYPE(end)
390 printf("CIS reading done\n");
395 * Functions to read the a tuple from the card
399 cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start,
400 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
408 e = pci_read_config(child, loc - loc % 4, 4);
409 for (j = loc % 4; j > 0; j--)
412 for (i = loc, j = -2; j < *len; j++, i++) {
414 e = pci_read_config(child, i, 4);
420 tupledata[j] = 0xff & e;
428 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start,
429 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
432 bus_space_handle_t bh;
435 bt = rman_get_bustag(res);
436 bh = rman_get_bushandle(res);
438 *tupleid = bus_space_read_1(bt, bh, start + *off);
439 *len = bus_space_read_1(bt, bh, start + *off + 1);
440 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
447 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
448 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
451 if (res == (struct resource*)~0UL) {
452 return (cardbus_read_tuple_conf(cbdev, child, start, off,
453 tupleid, len, tupledata));
455 return (cardbus_read_tuple_mem(cbdev, res, start, off,
456 tupleid, len, tupledata));
461 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
462 struct resource *res)
464 if (res != (struct resource*)~0UL) {
465 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
466 pci_write_config(child, rid, 0, 4);
467 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
471 static struct resource *
472 cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start,
477 struct resource *res;
479 switch (CARDBUS_CIS_SPACE(*start)) {
480 case CARDBUS_CIS_ASI_TUPLE:
481 /* CIS in PCI config space need no initialization */
482 return ((struct resource*)~0UL);
483 case CARDBUS_CIS_ASI_BAR0:
484 case CARDBUS_CIS_ASI_BAR1:
485 case CARDBUS_CIS_ASI_BAR2:
486 case CARDBUS_CIS_ASI_BAR3:
487 case CARDBUS_CIS_ASI_BAR4:
488 case CARDBUS_CIS_ASI_BAR5:
489 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
491 case CARDBUS_CIS_ASI_ROM:
492 *rid = CARDBUS_ROM_REG;
495 * This mask doesn't contain the bit that actually enables
498 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
502 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
503 CARDBUS_CIS_SPACE(*start));
507 /* figure out how much space we need */
508 pci_write_config(child, *rid, 0xffffffff, 4);
509 testval = pci_read_config(child, *rid, 4);
512 * This bit has a different meaning depending if we are dealing
513 * with a normal BAR or an Option ROM BAR.
515 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
516 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
520 size = CARDBUS_MAPREG_MEM_SIZE(testval);
521 /* XXX Is this some kind of hack? */
524 /* allocate the memory space to read CIS */
525 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
526 rman_make_alignment_flags(size) | RF_ACTIVE);
528 device_printf(cbdev, "Unable to allocate resource "
532 pci_write_config(child, *rid,
533 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
534 CARDBUS_ROM_ENABLE : 0),
536 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
538 /* Flip to the right ROM image if CIS is in ROM */
539 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
541 bus_space_handle_t bh;
543 u_int32_t imagebase = 0;
549 bt = rman_get_bustag(res);
550 bh = rman_get_bushandle(res);
552 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
553 for (romnum = 0;; romnum++) {
554 romsig = bus_space_read_2(bt, bh,
555 imagebase + CARDBUS_EXROM_SIGNATURE);
556 if (romsig != 0xaa55) {
557 device_printf(cbdev, "Bad header in rom %d: "
558 "[%x] %04x\n", romnum, imagebase +
559 CARDBUS_EXROM_SIGNATURE, romsig);
560 bus_release_resource(cbdev, SYS_RES_MEMORY,
567 * If this was the Option ROM image that we were
568 * looking for, then we are done.
570 if (romnum == imagenum)
573 /* Find out where the next Option ROM image is */
574 pcidata = imagebase + bus_space_read_2(bt, bh,
575 imagebase + CARDBUS_EXROM_DATA_PTR);
576 imagesize = bus_space_read_2(bt, bh,
577 pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
579 if (imagesize == 0) {
581 * XXX some ROMs seem to have this as zero,
582 * can we assume this means 1 block?
584 device_printf(cbdev, "Warning, size of Option "
585 "ROM image %d is 0 bytes, assuming 512 "
590 /* Image size is in 512 byte units */
593 if ((bus_space_read_1(bt, bh, pcidata +
594 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
595 device_printf(cbdev, "Cannot find CIS in "
597 bus_release_resource(cbdev, SYS_RES_MEMORY,
602 imagebase += imagesize;
604 *start = imagebase + CARDBUS_CIS_ADDR(*start);
606 *start = CARDBUS_CIS_ADDR(*start);
613 * Dispatch the right handler function per tuple
617 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
618 u_int8_t *tupledata, u_int32_t start, u_int32_t *off,
619 struct tuple_callbacks *callbacks)
622 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
623 if (tupleid == callbacks[i].id)
624 return (callbacks[i].func(cbdev, child, tupleid, len,
625 tupledata, start, off, &callbacks[i]));
628 if (tupleid < CISTPL_CUSTOMSTART) {
629 device_printf(cbdev, "Undefined tuple encountered, "
630 "CIS parsing terminated\n");
633 return (callbacks[i].func(cbdev, child, tupleid, len,
634 tupledata, start, off, NULL));
638 cardbus_parse_cis(device_t cbdev, device_t child,
639 struct tuple_callbacks *callbacks)
641 u_int8_t tupledata[MAXTUPLESIZE];
644 int expect_linktarget;
645 u_int32_t start, off;
646 struct resource *res;
649 bzero(tupledata, MAXTUPLESIZE);
650 expect_linktarget = TRUE;
651 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
654 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
658 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
659 &tupleid, &len, tupledata)) {
660 device_printf(cbdev, "Failed to read CIS.\n");
661 cardbus_read_tuple_finish(cbdev, child, rid, res);
665 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
666 device_printf(cbdev, "Expecting link target, got 0x%x\n",
668 cardbus_read_tuple_finish(cbdev, child, rid, res);
671 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
672 tupledata, start, &off, callbacks);
673 if (expect_linktarget != 0) {
674 cardbus_read_tuple_finish(cbdev, child, rid, res);
675 return (expect_linktarget);
677 } while (tupleid != CISTPL_END);
678 cardbus_read_tuple_finish(cbdev, child, rid, res);
683 barsort(const void *a, const void *b)
685 return ((*(const struct resource_list_entry * const *)b)->count -
686 (*(const struct resource_list_entry * const *)a)->count);
690 cardbus_alloc_resources(device_t cbdev, device_t child)
692 struct cardbus_devinfo *dinfo = device_get_ivars(child);
694 struct resource_list_entry *rle;
695 struct resource_list_entry **barlist;
697 u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
698 struct resource *res;
703 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
708 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
711 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
712 barlist[count] = rle;
713 if (rle->type == SYS_RES_IOPORT) {
714 io_size += rle->count;
715 } else if (rle->type == SYS_RES_MEMORY) {
716 if (dinfo->mprefetchable & BARBIT(rle->rid))
717 mem_psize += rle->count;
719 mem_nsize += rle->count;
725 * We want to allocate the largest resource first, so that our
726 * allocated memory is packed.
728 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
730 /* Allocate prefetchable memory */
732 for (tmp = 0; tmp < count; tmp++) {
733 if (barlist[tmp]->res == NULL &&
734 barlist[tmp]->type == SYS_RES_MEMORY &&
735 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
736 flags = rman_make_alignment_flags(barlist[tmp]->count);
740 if (flags > 0) { /* If any prefetchable memory is requested... */
742 * First we allocate one big space for all resources of this
743 * type. We do this because our parent, pccbb, needs to open
744 * a window to forward all addresses within the window, and
745 * it would be best if nobody else has resources allocated
747 * (XXX: Perhaps there might be a better way to do this?)
750 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
751 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
753 start = rman_get_start(res);
754 end = rman_get_end(res);
755 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
757 * Now that we know the region is free, release it and hand it
758 * out piece by piece.
760 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
761 for (tmp = 0; tmp < count; tmp++) {
762 if (barlist[tmp]->res == NULL &&
763 barlist[tmp]->type == SYS_RES_MEMORY &&
764 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
765 barlist[tmp]->res = bus_alloc_resource(cbdev,
767 &barlist[tmp]->rid, start, end,
769 rman_make_alignment_flags(
770 barlist[tmp]->count));
771 if (barlist[tmp]->res == NULL) {
772 mem_nsize += barlist[tmp]->count;
773 dinfo->mprefetchable &=
774 ~BARBIT(barlist[tmp]->rid);
775 DEVPRINTF((cbdev, "Cannot pre-allocate "
776 "prefetchable memory, will try as "
777 "non-prefetchable.\n"));
779 barlist[tmp]->start =
780 rman_get_start(barlist[tmp]->res);
782 rman_get_end(barlist[tmp]->res);
783 pci_write_config(child,
785 barlist[tmp]->start, 4);
786 DEVPRINTF((cbdev, "Prefetchable memory "
787 "rid=%x at %lx-%lx\n",
796 /* Allocate non-prefetchable memory */
798 for (tmp = 0; tmp < count; tmp++) {
799 if (barlist[tmp]->res == NULL &&
800 barlist[tmp]->type == SYS_RES_MEMORY) {
801 flags = rman_make_alignment_flags(barlist[tmp]->count);
805 if (flags > 0) { /* If any non-prefetchable memory is requested... */
807 * First we allocate one big space for all resources of this
808 * type. We do this because our parent, pccbb, needs to open
809 * a window to forward all addresses within the window, and
810 * it would be best if nobody else has resources allocated
812 * (XXX: Perhaps there might be a better way to do this?)
815 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
816 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
818 start = rman_get_start(res);
819 end = rman_get_end(res);
820 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
823 * Now that we know the region is free, release it and hand it
824 * out piece by piece.
826 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
827 for (tmp = 0; tmp < count; tmp++) {
828 if (barlist[tmp]->res == NULL &&
829 barlist[tmp]->type == SYS_RES_MEMORY) {
830 barlist[tmp]->res = bus_alloc_resource(cbdev,
831 barlist[tmp]->type, &barlist[tmp]->rid,
832 start, end, barlist[tmp]->count,
833 rman_make_alignment_flags(
834 barlist[tmp]->count));
835 if (barlist[tmp]->res == NULL) {
836 DEVPRINTF((cbdev, "Cannot pre-allocate "
837 "memory for cardbus device\n"));
838 free(barlist, M_DEVBUF);
841 barlist[tmp]->start =
842 rman_get_start(barlist[tmp]->res);
843 barlist[tmp]->end = rman_get_end(
845 pci_write_config(child, barlist[tmp]->rid,
846 barlist[tmp]->start, 4);
847 DEVPRINTF((cbdev, "Non-prefetchable memory "
848 "rid=%x at %lx-%lx (%lx)\n",
849 barlist[tmp]->rid, barlist[tmp]->start,
850 barlist[tmp]->end, barlist[tmp]->count));
855 /* Allocate IO ports */
857 for (tmp = 0; tmp < count; tmp++) {
858 if (barlist[tmp]->res == NULL &&
859 barlist[tmp]->type == SYS_RES_IOPORT) {
860 flags = rman_make_alignment_flags(barlist[tmp]->count);
864 if (flags > 0) { /* If any IO port is requested... */
866 * First we allocate one big space for all resources of this
867 * type. We do this because our parent, pccbb, needs to open
868 * a window to forward all addresses within the window, and
869 * it would be best if nobody else has resources allocated
871 * (XXX: Perhaps there might be a better way to do this?)
874 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
875 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
876 start = rman_get_start(res);
877 end = rman_get_end(res);
878 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
880 * Now that we know the region is free, release it and hand it
881 * out piece by piece.
883 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
884 for (tmp = 0; tmp < count; tmp++) {
885 if (barlist[tmp]->res == NULL &&
886 barlist[tmp]->type == SYS_RES_IOPORT) {
887 barlist[tmp]->res = bus_alloc_resource(cbdev,
888 barlist[tmp]->type, &barlist[tmp]->rid,
889 start, end, barlist[tmp]->count,
890 rman_make_alignment_flags(
891 barlist[tmp]->count));
892 if (barlist[tmp]->res == NULL) {
893 DEVPRINTF((cbdev, "Cannot pre-allocate "
894 "IO port for cardbus device\n"));
895 free(barlist, M_DEVBUF);
898 barlist[tmp]->start =
899 rman_get_start(barlist[tmp]->res);
901 rman_get_end(barlist[tmp]->res);
902 pci_write_config(child, barlist[tmp]->rid,
903 barlist[tmp]->start, 4);
904 DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
905 barlist[tmp]->rid, barlist[tmp]->start,
913 res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
915 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
916 rman_get_start(res), rman_get_end(res), 1);
917 rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
919 dinfo->pci.cfg.intline = rman_get_start(res);
920 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
922 free(barlist, M_DEVBUF);
927 * Adding a memory/io resource (sans CIS)
931 cardbus_add_map(device_t cbdev, device_t child, int reg)
933 struct cardbus_devinfo *dinfo = device_get_ivars(child);
934 struct resource_list_entry *rle;
939 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
944 if (reg == CARDBUS_ROM_REG)
945 testval = CARDBUS_ROM_ADDRMASK;
949 pci_write_config(child, reg, testval, 4);
950 testval = pci_read_config(child, reg, 4);
952 if (testval == ~0 || testval == 0)
955 if ((testval & 1) == 0)
956 type = SYS_RES_MEMORY;
958 type = SYS_RES_IOPORT;
960 size = CARDBUS_MAPREG_MEM_SIZE(testval);
961 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
963 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
967 cardbus_pickup_maps(device_t cbdev, device_t child)
969 struct cardbus_devinfo *dinfo = device_get_ivars(child);
970 struct cardbus_quirk *q;
974 * Try to pick up any resources that was not specified in CIS.
975 * Some devices (eg, 3c656) does not list all resources required by
976 * the driver in its CIS.
977 * XXX: should we do this or use quirks?
979 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
980 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
983 for (q = &cardbus_quirks[0]; q->devid; q++) {
984 if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
985 && q->type == CARDBUS_QUIRK_MAP_REG) {
986 cardbus_add_map(cbdev, child, q->arg1);
992 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id,
993 struct cis_tupleinfo **buff, int *nret)
995 struct tuple_callbacks cisread_callbacks[] = {
996 MAKETUPLE(NULL, nothing),
997 /* first entry will be overwritten */
998 MAKETUPLE(NULL, nothing),
999 MAKETUPLE(DEVICE, nothing),
1000 MAKETUPLE(LONG_LINK_CB, unhandled),
1001 MAKETUPLE(INDIRECT, unhandled),
1002 MAKETUPLE(CONFIG_CB, nothing),
1003 MAKETUPLE(CFTABLE_ENTRY_CB, nothing),
1004 MAKETUPLE(LONGLINK_MFC, unhandled),
1005 MAKETUPLE(BAR, nothing),
1006 MAKETUPLE(PWR_MGMNT, nothing),
1007 MAKETUPLE(EXTDEVICE, nothing),
1008 MAKETUPLE(CHECKSUM, nothing),
1009 MAKETUPLE(LONGLINK_A, unhandled),
1010 MAKETUPLE(LONGLINK_C, unhandled),
1011 MAKETUPLE(LINKTARGET, nothing),
1012 MAKETUPLE(NO_LINK, nothing),
1013 MAKETUPLE(VERS_1, nothing),
1014 MAKETUPLE(ALTSTR, nothing),
1015 MAKETUPLE(DEVICE_A, nothing),
1016 MAKETUPLE(JEDEC_C, nothing),
1017 MAKETUPLE(JEDEC_A, nothing),
1018 MAKETUPLE(CONFIG, nothing),
1019 MAKETUPLE(CFTABLE_ENTRY, nothing),
1020 MAKETUPLE(DEVICE_OC, nothing),
1021 MAKETUPLE(DEVICE_OA, nothing),
1022 MAKETUPLE(DEVICE_GEO, nothing),
1023 MAKETUPLE(DEVICE_GEO_A, nothing),
1024 MAKETUPLE(MANFID, nothing),
1025 MAKETUPLE(FUNCID, nothing),
1026 MAKETUPLE(FUNCE, nothing),
1027 MAKETUPLE(SWIL, nothing),
1028 MAKETUPLE(VERS_2, nothing),
1029 MAKETUPLE(FORMAT, nothing),
1030 MAKETUPLE(GEOMETRY, nothing),
1031 MAKETUPLE(BYTEORDER, nothing),
1032 MAKETUPLE(DATE, nothing),
1033 MAKETUPLE(BATTERY, nothing),
1034 MAKETUPLE(ORG, nothing),
1035 MAKETUPLE(END, end),
1036 MAKETUPLE(GENERIC, nothing),
1040 cisread_callbacks[0].id = id;
1041 cisread_callbacks[0].name = "COPY";
1042 cisread_callbacks[0].func = decode_tuple_copy;
1045 ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
1047 *buff = cisread_buf;
1048 *nret = ncisread_buf;
1053 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
1056 for (i = 0; i < *nret; i++)
1057 free(buff[i].data, M_DEVBUF);
1059 free(buff, M_DEVBUF);
1063 cardbus_do_cis(device_t cbdev, device_t child)
1066 struct tuple_callbacks init_callbacks[] = {
1067 MAKETUPLE(NULL, generic),
1068 MAKETUPLE(DEVICE, generic),
1069 MAKETUPLE(LONG_LINK_CB, unhandled),
1070 MAKETUPLE(INDIRECT, unhandled),
1071 MAKETUPLE(CONFIG_CB, generic),
1072 MAKETUPLE(CFTABLE_ENTRY_CB, generic),
1073 MAKETUPLE(LONGLINK_MFC, unhandled),
1074 MAKETUPLE(BAR, bar),
1075 MAKETUPLE(PWR_MGMNT, generic),
1076 MAKETUPLE(EXTDEVICE, generic),
1077 MAKETUPLE(CHECKSUM, generic),
1078 MAKETUPLE(LONGLINK_A, unhandled),
1079 MAKETUPLE(LONGLINK_C, unhandled),
1080 MAKETUPLE(LINKTARGET, linktarget),
1081 MAKETUPLE(NO_LINK, generic),
1082 MAKETUPLE(VERS_1, vers_1),
1083 MAKETUPLE(ALTSTR, generic),
1084 MAKETUPLE(DEVICE_A, generic),
1085 MAKETUPLE(JEDEC_C, generic),
1086 MAKETUPLE(JEDEC_A, generic),
1087 MAKETUPLE(CONFIG, generic),
1088 MAKETUPLE(CFTABLE_ENTRY, generic),
1089 MAKETUPLE(DEVICE_OC, generic),
1090 MAKETUPLE(DEVICE_OA, generic),
1091 MAKETUPLE(DEVICE_GEO, generic),
1092 MAKETUPLE(DEVICE_GEO_A, generic),
1093 MAKETUPLE(MANFID, manfid),
1094 MAKETUPLE(FUNCID, funcid),
1095 MAKETUPLE(FUNCE, funce),
1096 MAKETUPLE(SWIL, generic),
1097 MAKETUPLE(VERS_2, generic),
1098 MAKETUPLE(FORMAT, generic),
1099 MAKETUPLE(GEOMETRY, generic),
1100 MAKETUPLE(BYTEORDER, generic),
1101 MAKETUPLE(DATE, generic),
1102 MAKETUPLE(BATTERY, generic),
1103 MAKETUPLE(ORG, generic),
1104 MAKETUPLE(END, end),
1105 MAKETUPLE(GENERIC, generic),
1108 ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1111 cardbus_pickup_maps(cbdev, child);
1112 return (cardbus_alloc_resources(cbdev, child));