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.5 2006/12/22 23:26:22 swildner 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>
43 #include <sys/pciio.h>
44 #include <bus/pci/pcivar.h>
45 #include <bus/pci/pcireg.h>
47 #include <dev/pccard/cardbus/cardbusreg.h>
48 #include <dev/pccard/cardbus/cardbusvar.h>
49 #include <dev/pccard/cardbus/cardbus_cis.h>
51 #include <bus/pccard/pccardvar.h>
53 extern int cardbus_cis_debug;
55 #define DPRINTF(a) if (cardbus_cis_debug) kprintf a
56 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
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)
63 struct tuple_callbacks {
66 int (*func) DECODE_PARAMS;
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,
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,
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);
105 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
107 static char *funcnames[] = {
120 struct cardbus_quirk {
121 u_int32_t devid; /* Vendor/device of the card */
123 #define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */
128 struct cardbus_quirk cardbus_quirks[] = {
132 static struct cis_tupleinfo *cisread_buf;
133 static int ncisread_buf;
136 * Handler functions for various CIS tuples
139 DECODE_PROTOTYPE(generic)
145 kprintf("TUPLE: %s [%d]:", info->name, len);
147 kprintf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
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]);
159 DECODE_PROTOTYPE(nothing)
164 DECODE_PROTOTYPE(copy)
166 struct cis_tupleinfo *tmpbuf;
168 tmpbuf = kmalloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1),
170 if (ncisread_buf > 0) {
171 memcpy(tmpbuf, cisread_buf,
172 sizeof(struct cis_tupleinfo) * ncisread_buf);
173 kfree(cisread_buf, M_DEVBUF);
175 cisread_buf = tmpbuf;
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);
185 DECODE_PROTOTYPE(linktarget)
190 kprintf("TUPLE: %s [%d]:", info->name, len);
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]);
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,
209 DECODE_PROTOTYPE(vers_1)
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')
218 else if (tupledata[i] == 0xff)
221 kprintf("%c", tupledata[i]);
227 DECODE_PROTOTYPE(funcid)
229 struct cardbus_devinfo *dinfo = device_get_ivars(child);
230 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
233 kprintf("Functions: ");
234 for (i = 0; i < len; i++) {
235 if (tupledata[i] < numnames)
236 kprintf("%s", funcnames[tupledata[i]]);
238 kprintf("Unknown(%d)", tupledata[i]);
244 dinfo->funcid = tupledata[0]; /* use first in list */
249 DECODE_PROTOTYPE(manfid)
251 struct cardbus_devinfo *dinfo = device_get_ivars(child);
254 kprintf("Manufacturer ID: ");
255 for (i = 0; i < len; i++)
256 kprintf("%02x", tupledata[i]);
260 dinfo->mfrid = tupledata[1] | (tupledata[2]<<8);
261 dinfo->prodid = tupledata[3] | (tupledata[4]<<8);
266 DECODE_PROTOTYPE(funce)
268 struct cardbus_devinfo *dinfo = device_get_ivars(child);
271 kprintf("Function Extension: ");
272 for (i = 0; i < len; i++)
273 kprintf("%02x", tupledata[i]);
275 if (len < 2) /* too short */
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;
283 dinfo->fepresent |= 1<<type;
287 case TPL_FUNCE_LAN_TECH:
288 dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */
291 case TPL_FUNCE_LAN_SPEED:
292 for (i = 0; i < 3; i++) {
293 if (dinfo->funce.lan.speed[i] == 0) {
295 dinfo->funce.lan.speed[i] =
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 */
313 case TPL_FUNCE_LAN_NID:
315 bcopy(&tupledata[1], dinfo->funce.lan.nid, 6);
317 case TPL_FUNCE_LAN_CONN:
318 dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
321 dinfo->fepresent |= 1<<type;
327 DECODE_PROTOTYPE(bar)
329 struct cardbus_devinfo *dinfo = device_get_ivars(child);
335 kprintf("*** ERROR *** BAR length not 6 (%d)\n", len);
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;
343 type = SYS_RES_MEMORY;
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",
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);
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)" : "" ));
369 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
372 * Mark the appropriate bit in the PCI command register so that
373 * device drivers will know which type of BARs can be used.
375 pci_enable_io(child, type);
379 DECODE_PROTOTYPE(unhandled)
381 kprintf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
385 DECODE_PROTOTYPE(end)
387 kprintf("CIS reading done\n");
392 * Functions to read the a tuple from the card
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)
405 e = pci_read_config(child, loc - loc % 4, 4);
406 for (j = loc % 4; j > 0; j--)
409 for (i = loc, j = -2; j < *len; j++, i++) {
411 e = pci_read_config(child, i, 4);
417 tupledata[j] = 0xff & e;
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)
429 bus_space_handle_t bh;
432 bt = rman_get_bustag(res);
433 bh = rman_get_bushandle(res);
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);
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,
448 if (res == (struct resource*)~0UL) {
449 return (cardbus_read_tuple_conf(cbdev, child, start, off,
450 tupleid, len, tupledata));
452 return (cardbus_read_tuple_mem(cbdev, res, start, off,
453 tupleid, len, tupledata));
458 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
459 struct resource *res)
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);
468 static struct resource *
469 cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start,
474 struct resource *res;
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;
488 case CARDBUS_CIS_ASI_ROM:
489 *rid = CARDBUS_ROM_REG;
492 * This mask doesn't contain the bit that actually enables
495 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
499 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
500 CARDBUS_CIS_SPACE(*start));
504 /* figure out how much space we need */
505 pci_write_config(child, *rid, 0xffffffff, 4);
506 testval = pci_read_config(child, *rid, 4);
509 * This bit has a different meaning depending if we are dealing
510 * with a normal BAR or an Option ROM BAR.
512 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
513 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
517 size = CARDBUS_MAPREG_MEM_SIZE(testval);
518 /* XXX Is this some kind of hack? */
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);
525 device_printf(cbdev, "Unable to allocate resource "
529 pci_write_config(child, *rid,
530 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
531 CARDBUS_ROM_ENABLE : 0),
533 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
535 /* Flip to the right ROM image if CIS is in ROM */
536 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
538 bus_space_handle_t bh;
540 u_int32_t imagebase = 0;
546 bt = rman_get_bustag(res);
547 bh = rman_get_bushandle(res);
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,
564 * If this was the Option ROM image that we were
565 * looking for, then we are done.
567 if (romnum == imagenum)
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);
576 if (imagesize == 0) {
578 * XXX some ROMs seem to have this as zero,
579 * can we assume this means 1 block?
581 device_printf(cbdev, "Warning, size of Option "
582 "ROM image %d is 0 bytes, assuming 512 "
587 /* Image size is in 512 byte units */
590 if ((bus_space_read_1(bt, bh, pcidata +
591 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
592 device_printf(cbdev, "Cannot find CIS in "
594 bus_release_resource(cbdev, SYS_RES_MEMORY,
599 imagebase += imagesize;
601 *start = imagebase + CARDBUS_CIS_ADDR(*start);
603 *start = CARDBUS_CIS_ADDR(*start);
610 * Dispatch the right handler function per tuple
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)
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]));
625 if (tupleid < CISTPL_CUSTOMSTART) {
626 device_printf(cbdev, "Undefined tuple encountered, "
627 "CIS parsing terminated\n");
630 return (callbacks[i].func(cbdev, child, tupleid, len,
631 tupledata, start, off, NULL));
635 cardbus_parse_cis(device_t cbdev, device_t child,
636 struct tuple_callbacks *callbacks)
638 u_int8_t tupledata[MAXTUPLESIZE];
641 int expect_linktarget;
642 u_int32_t start, off;
643 struct resource *res;
646 bzero(tupledata, MAXTUPLESIZE);
647 expect_linktarget = TRUE;
648 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
651 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
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);
662 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
663 device_printf(cbdev, "Expecting link target, got 0x%x\n",
665 cardbus_read_tuple_finish(cbdev, child, rid, res);
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);
674 } while (tupleid != CISTPL_END);
675 cardbus_read_tuple_finish(cbdev, child, rid, res);
680 barsort(const void *a, const void *b)
682 return ((*(const struct resource_list_entry * const *)b)->count -
683 (*(const struct resource_list_entry * const *)a)->count);
687 cardbus_alloc_resources(device_t cbdev, device_t child)
689 struct cardbus_devinfo *dinfo = device_get_ivars(child);
691 struct resource_list_entry *rle;
692 struct resource_list_entry **barlist;
694 u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
695 struct resource *res;
700 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
705 barlist = kmalloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
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;
716 mem_nsize += rle->count;
722 * We want to allocate the largest resource first, so that our
723 * allocated memory is packed.
725 kqsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
727 /* Allocate prefetchable memory */
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);
737 if (flags > 0) { /* If any prefetchable memory is requested... */
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
744 * (XXX: Perhaps there might be a better way to do this?)
747 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
748 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
750 start = rman_get_start(res);
751 end = rman_get_end(res);
752 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
754 * Now that we know the region is free, release it and hand it
755 * out piece by piece.
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,
764 &barlist[tmp]->rid, start, end,
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"));
776 barlist[tmp]->start =
777 rman_get_start(barlist[tmp]->res);
779 rman_get_end(barlist[tmp]->res);
780 pci_write_config(child,
782 barlist[tmp]->start, 4);
783 DEVPRINTF((cbdev, "Prefetchable memory "
784 "rid=%x at %lx-%lx\n",
793 /* Allocate non-prefetchable memory */
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);
802 if (flags > 0) { /* If any non-prefetchable memory is requested... */
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
809 * (XXX: Perhaps there might be a better way to do this?)
812 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
813 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
815 start = rman_get_start(res);
816 end = rman_get_end(res);
817 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
820 * Now that we know the region is free, release it and hand it
821 * out piece by piece.
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);
838 barlist[tmp]->start =
839 rman_get_start(barlist[tmp]->res);
840 barlist[tmp]->end = rman_get_end(
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));
852 /* Allocate IO ports */
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);
861 if (flags > 0) { /* If any IO port is requested... */
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
868 * (XXX: Perhaps there might be a better way to do this?)
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));
877 * Now that we know the region is free, release it and hand it
878 * out piece by piece.
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);
895 barlist[tmp]->start =
896 rman_get_start(barlist[tmp]->res);
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,
910 res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
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);
916 dinfo->pci.cfg.intline = rman_get_start(res);
917 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
919 kfree(barlist, M_DEVBUF);
924 * Adding a memory/io resource (sans CIS)
928 cardbus_add_map(device_t cbdev, device_t child, int reg)
930 struct cardbus_devinfo *dinfo = device_get_ivars(child);
931 struct resource_list_entry *rle;
936 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
941 if (reg == CARDBUS_ROM_REG)
942 testval = CARDBUS_ROM_ADDRMASK;
946 pci_write_config(child, reg, testval, 4);
947 testval = pci_read_config(child, reg, 4);
949 if (testval == ~0 || testval == 0)
952 if ((testval & 1) == 0)
953 type = SYS_RES_MEMORY;
955 type = SYS_RES_IOPORT;
957 size = CARDBUS_MAPREG_MEM_SIZE(testval);
958 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
960 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
964 cardbus_pickup_maps(device_t cbdev, device_t child)
966 struct cardbus_devinfo *dinfo = device_get_ivars(child);
967 struct cardbus_quirk *q;
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?
976 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
977 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
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);
989 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id,
990 struct cis_tupleinfo **buff, int *nret)
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),
1037 cisread_callbacks[0].id = id;
1038 cisread_callbacks[0].name = "COPY";
1039 cisread_callbacks[0].func = decode_tuple_copy;
1042 ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
1044 *buff = cisread_buf;
1045 *nret = ncisread_buf;
1050 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
1053 for (i = 0; i < *nret; i++)
1054 kfree(buff[i].data, M_DEVBUF);
1056 kfree(buff, M_DEVBUF);
1060 cardbus_do_cis(device_t cbdev, device_t child)
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),
1105 ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1108 cardbus_pickup_maps(cbdev, child);
1109 return (cardbus_alloc_resources(cbdev, child));