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
32 * CIS Handling for the Cardbus Bus
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
41 #include <machine/bus.h>
42 #include <machine/resource.h>
45 #include <sys/pciio.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcireg.h>
49 #include <dev/cardbus/cardbusreg.h>
50 #include <dev/cardbus/cardbusvar.h>
51 #include <dev/cardbus/cardbus_cis.h>
55 extern int cardbus_cis_debug;
57 #define DPRINTF(a) if (cardbus_cis_debug) printf a
58 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
60 #define DECODE_PARAMS \
61 (device_t cbdev, device_t child, int id, int len, \
62 u_int8_t *tupledata, u_int32_t start, u_int32_t *off, \
63 struct tuple_callbacks *info)
65 struct tuple_callbacks {
68 int (*func) DECODE_PARAMS;
71 #define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS
72 DECODE_PROTOTYPE(generic);
73 DECODE_PROTOTYPE(nothing);
74 DECODE_PROTOTYPE(copy);
75 DECODE_PROTOTYPE(linktarget);
76 DECODE_PROTOTYPE(vers_1);
77 DECODE_PROTOTYPE(funcid);
78 DECODE_PROTOTYPE(manfid);
79 DECODE_PROTOTYPE(funce);
80 DECODE_PROTOTYPE(bar);
81 DECODE_PROTOTYPE(unhandled);
82 DECODE_PROTOTYPE(end);
83 static int cardbus_read_tuple_conf(device_t cbdev, device_t child,
84 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
86 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
87 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
89 static int cardbus_read_tuple(device_t cbdev, device_t child,
90 struct resource *res, u_int32_t start, u_int32_t *off,
91 int *tupleid, int *len, u_int8_t *tupledata);
92 static void cardbus_read_tuple_finish(device_t cbdev, device_t child,
93 int rid, struct resource *res);
94 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child,
95 u_int32_t *start, int *rid);
96 static int decode_tuple(device_t cbdev, device_t child, int tupleid,
97 int len, u_int8_t *tupledata, u_int32_t start,
98 u_int32_t *off, struct tuple_callbacks *callbacks);
99 static int cardbus_parse_cis(device_t cbdev, device_t child,
100 struct tuple_callbacks *callbacks);
101 static int barsort(const void *a, const void *b);
102 static int cardbus_alloc_resources(device_t cbdev, device_t child);
103 static void cardbus_add_map(device_t cbdev, device_t child, int reg);
104 static void cardbus_pickup_maps(device_t cbdev, device_t child);
107 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
109 static char *funcnames[] = {
122 struct cardbus_quirk {
123 u_int32_t devid; /* Vendor/device of the card */
125 #define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */
130 struct cardbus_quirk cardbus_quirks[] = {
134 static struct cis_tupleinfo *cisread_buf;
135 static int ncisread_buf;
138 * Handler functions for various CIS tuples
141 DECODE_PROTOTYPE(generic)
147 printf("TUPLE: %s [%d]:", info->name, len);
149 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
151 for (i = 0; i < len; i++) {
152 if (i % 0x10 == 0 && len > 0x10)
153 printf("\n 0x%02x:", i);
154 printf(" %02x", tupledata[i]);
161 DECODE_PROTOTYPE(nothing)
166 DECODE_PROTOTYPE(copy)
168 struct cis_tupleinfo *tmpbuf;
170 tmpbuf = malloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1),
172 if (ncisread_buf > 0) {
173 memcpy(tmpbuf, cisread_buf,
174 sizeof(struct cis_tupleinfo) * ncisread_buf);
175 free(cisread_buf, M_DEVBUF);
177 cisread_buf = tmpbuf;
179 cisread_buf[ncisread_buf].id = id;
180 cisread_buf[ncisread_buf].len = len;
181 cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, M_WAITOK);
182 memcpy(cisread_buf[ncisread_buf].data, tupledata, len);
187 DECODE_PROTOTYPE(linktarget)
192 printf("TUPLE: %s [%d]:", info->name, len);
194 for (i = 0; i < len; i++) {
195 if (i % 0x10 == 0 && len > 0x10)
196 printf("\n 0x%02x:", i);
197 printf(" %02x", tupledata[i]);
201 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
202 tupledata[2] != 'S') {
203 printf("Invalid data for CIS Link Target!\n");
204 decode_tuple_generic(cbdev, child, id, len, tupledata,
211 DECODE_PROTOTYPE(vers_1)
214 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
215 printf("Product name: ");
216 for (i = 2; i < len; i++) {
217 if (tupledata[i] == '\0')
219 else if (tupledata[i] == 0xff)
222 printf("%c", tupledata[i]);
228 DECODE_PROTOTYPE(funcid)
231 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
233 printf("Functions: ");
234 for (i = 0; i < len; i++) {
235 if (tupledata[i] < numnames)
236 printf("%s", funcnames[tupledata[i]]);
238 printf("Unknown(%d)", tupledata[i]);
246 DECODE_PROTOTYPE(manfid)
249 printf("Manufacturer ID: ");
250 for (i = 0; i < len; i++)
251 printf("%02x", tupledata[i]);
256 DECODE_PROTOTYPE(funce)
259 printf("Function Extension: ");
260 for (i = 0; i < len; i++)
261 printf("%02x", tupledata[i]);
266 DECODE_PROTOTYPE(bar)
269 printf("*** ERROR *** BAR length not 6 (%d)\n", len);
272 struct cardbus_devinfo *dinfo = device_get_ivars(child);
277 reg = *(u_int16_t*)tupledata;
278 len = *(u_int32_t*)(tupledata + 2);
279 if (reg & TPL_BAR_REG_AS) {
280 type = SYS_RES_IOPORT;
282 type = SYS_RES_MEMORY;
284 bar = (reg & TPL_BAR_REG_ASI_MASK) - 1;
285 if (bar < 0 || bar > 5 ||
286 (type == SYS_RES_IOPORT && bar == 5)) {
287 device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n",
291 bar = CARDBUS_BASE0_REG + bar * 4;
292 if (type == SYS_RES_MEMORY) {
293 if (bar & TPL_BAR_REG_PREFETCHABLE)
294 dinfo->mprefetchable |= BARBIT(bar);
295 if (bar & TPL_BAR_REG_BELOW1MB)
296 dinfo->mbelow1mb |= BARBIT(bar);
297 } else if (type == SYS_RES_IOPORT) {
298 if (bar & TPL_BAR_REG_BELOW1MB)
299 dinfo->ibelow1mb |= BARBIT(bar);
301 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, "
303 (type==SYS_RES_MEMORY)?"MEM":"IO", bar, len,
304 (type==SYS_RES_MEMORY&&dinfo->mprefetchable&BARBIT(bar))?
305 " (Prefetchable)":"",
306 type==SYS_RES_MEMORY?
307 ((dinfo->mbelow1mb&BARBIT(bar))?" (Below 1Mb)":"")
308 :(dinfo->ibelow1mb&BARBIT(bar))?" (Below 1Mb)":""
311 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
316 DECODE_PROTOTYPE(unhandled)
318 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
322 DECODE_PROTOTYPE(end)
324 printf("CIS reading done\n");
329 * Functions to read the a tuple from the card
333 cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start,
334 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
342 e = pci_read_config(child, loc - loc % 4, 4);
343 for (j = loc % 4; j > 0; j--)
346 for (i = loc, j = -2; j < *len; j++, i++) {
348 e = pci_read_config(child, i, 4);
354 tupledata[j] = 0xff & e;
362 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start,
363 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
366 bus_space_handle_t bh;
369 bt = rman_get_bustag(res);
370 bh = rman_get_bushandle(res);
372 *tupleid = bus_space_read_1(bt, bh, start + *off);
373 *len = bus_space_read_1(bt, bh, start + *off + 1);
374 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
381 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
382 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
385 if (res == (struct resource*)~0UL) {
386 return (cardbus_read_tuple_conf(cbdev, child, start, off,
387 tupleid, len, tupledata));
389 return (cardbus_read_tuple_mem(cbdev, res, start, off,
390 tupleid, len, tupledata));
395 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
396 struct resource *res)
398 if (res != (struct resource*)~0UL) {
399 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
400 pci_write_config(child, rid, 0, 4);
401 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
405 static struct resource *
406 cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start,
411 struct resource *res;
413 switch (CARDBUS_CIS_SPACE(*start)) {
414 case CARDBUS_CIS_ASI_TUPLE:
415 /* CIS in tuple space need no initialization */
416 return ((struct resource*)~0UL);
417 case CARDBUS_CIS_ASI_BAR0:
418 case CARDBUS_CIS_ASI_BAR1:
419 case CARDBUS_CIS_ASI_BAR2:
420 case CARDBUS_CIS_ASI_BAR3:
421 case CARDBUS_CIS_ASI_BAR4:
422 case CARDBUS_CIS_ASI_BAR5:
423 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
424 pci_write_config(child, *rid, ~0UL, 4);
426 case CARDBUS_CIS_ASI_ROM:
427 *rid = CARDBUS_ROM_REG;
428 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
431 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
432 CARDBUS_CIS_SPACE(*start));
436 /* figure out how much space we need */
437 testval = pci_read_config(child, *rid, 4);
439 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
442 size = CARDBUS_MAPREG_MEM_SIZE(testval);
445 /* allocate the memory space to read CIS */
446 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
447 rman_make_alignment_flags(size) | RF_ACTIVE);
449 device_printf(cbdev, "Unable to allocate resource "
453 pci_write_config(child, *rid,
454 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
455 CARDBUS_ROM_ENABLE : 0),
457 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
459 /* Flip to the right ROM image if CIS is in ROM */
460 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
462 bus_space_handle_t bh;
469 bt = rman_get_bustag(res);
470 bh = rman_get_bushandle(res);
472 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
473 for (romnum = 0;; romnum++) {
474 if (bus_space_read_2(bt, bh,
475 mystart+CARDBUS_EXROM_SIGNATURE) != 0xaa55) {
476 device_printf(cbdev, "Bad header in rom %d: "
477 "[%x] %04x\n", romnum, mystart +
478 CARDBUS_EXROM_SIGNATURE,
479 bus_space_read_2(bt, bh,
480 mystart+CARDBUS_EXROM_SIGNATURE));
481 bus_release_resource(cbdev, SYS_RES_MEMORY,
486 dataptr = mystart + bus_space_read_2(bt, bh,
487 mystart + CARDBUS_EXROM_DATA_PTR);
488 imagesize = bus_space_read_2(bt, bh,
489 dataptr + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
491 if (imagesize == 0) {
493 * XXX some ROMs seem to have this as zero,
494 * can we assume this means 1 block?
500 if (romnum == imagenum)
502 if ((bus_space_read_1(bt, bh, mystart +
503 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) == 0) {
504 device_printf(cbdev, "Cannot read CIS: "
505 "Not enough images of rom\n");
508 mystart += imagesize;
510 *start = mystart + CARDBUS_CIS_ADDR(*start);
512 *start = CARDBUS_CIS_SPACE(*start);
518 * Dispatch the right handler function per tuple
522 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
523 u_int8_t *tupledata, u_int32_t start, u_int32_t *off,
524 struct tuple_callbacks *callbacks)
527 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
528 if (tupleid == callbacks[i].id)
529 return (callbacks[i].func(cbdev, child, tupleid, len,
530 tupledata, start, off, &callbacks[i]));
533 if (tupleid < CISTPL_CUSTOMSTART) {
534 device_printf(cbdev, "Undefined tuple encountered, "
535 "CIS parsing terminated\n");
538 return (callbacks[i].func(cbdev, child, tupleid, len,
539 tupledata, start, off, NULL));
543 cardbus_parse_cis(device_t cbdev, device_t child,
544 struct tuple_callbacks *callbacks)
546 u_int8_t tupledata[MAXTUPLESIZE];
549 int expect_linktarget;
550 u_int32_t start, off;
551 struct resource *res;
554 bzero(tupledata, MAXTUPLESIZE);
555 expect_linktarget = TRUE;
556 start = pci_read_config(child, CARDBUS_CIS_REG, 4);
558 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
562 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
563 &tupleid, &len, tupledata)) {
564 device_printf(cbdev, "Failed to read CIS.\n");
565 cardbus_read_tuple_finish(cbdev, child, rid, res);
569 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
570 device_printf(cbdev, "Expecting link target, got 0x%x\n",
572 cardbus_read_tuple_finish(cbdev, child, rid, res);
575 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
576 tupledata, start, &off, callbacks);
577 if (expect_linktarget != 0) {
578 cardbus_read_tuple_finish(cbdev, child, rid, res);
579 return (expect_linktarget);
581 } while (tupleid != CISTPL_END);
582 cardbus_read_tuple_finish(cbdev, child, rid, res);
587 barsort(const void *a, const void *b)
589 return ((*(const struct resource_list_entry **)b)->count -
590 (*(const struct resource_list_entry **)a)->count);
594 cardbus_alloc_resources(device_t cbdev, device_t child)
596 struct cardbus_devinfo *dinfo = device_get_ivars(child);
598 struct resource_list_entry *rle;
599 struct resource_list_entry **barlist;
601 u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
602 struct resource *res;
607 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
612 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
615 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
616 barlist[count] = rle;
617 if (rle->type == SYS_RES_IOPORT) {
618 io_size += rle->count;
619 } else if (rle->type == SYS_RES_MEMORY) {
620 if (dinfo->mprefetchable & BARBIT(rle->rid))
621 mem_psize += rle->count;
623 mem_nsize += rle->count;
629 * We want to allocate the largest resource first, so that our
630 * allocated memory is packed.
632 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
634 /* Allocate prefetchable memory */
636 for (tmp = 0; tmp < count; tmp++) {
637 if (barlist[tmp]->res == NULL &&
638 barlist[tmp]->type == SYS_RES_MEMORY &&
639 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
640 flags = rman_make_alignment_flags(barlist[tmp]->count);
644 if (flags > 0) { /* If any prefetchable memory is requested... */
646 * First we allocate one big space for all resources of this
647 * type. We do this because our parent, pccbb, needs to open
648 * a window to forward all addresses within the window, and
649 * it would be best if nobody else has resources allocated
651 * (XXX: Perhaps there might be a better way to do this?)
654 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
655 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
657 start = rman_get_start(res);
658 end = rman_get_end(res);
659 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
661 * Now that we know the region is free, release it and hand it
662 * out piece by piece.
664 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
665 for (tmp = 0; tmp < count; tmp++) {
666 if (barlist[tmp]->res == NULL &&
667 barlist[tmp]->type == SYS_RES_MEMORY &&
668 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
669 barlist[tmp]->res = bus_alloc_resource(cbdev,
671 &barlist[tmp]->rid, start, end,
673 rman_make_alignment_flags(
674 barlist[tmp]->count));
675 if (barlist[tmp]->res == NULL) {
676 mem_nsize += barlist[tmp]->count;
677 dinfo->mprefetchable &=
678 ~BARBIT(barlist[tmp]->rid);
679 DEVPRINTF((cbdev, "Cannot pre-allocate "
680 "prefetchable memory, will try as "
681 "non-prefetchable.\n"));
683 barlist[tmp]->start =
684 rman_get_start(barlist[tmp]->res);
686 rman_get_end(barlist[tmp]->res);
687 pci_write_config(child,
689 barlist[tmp]->start, 4);
690 DEVPRINTF((cbdev, "Prefetchable memory "
691 "rid=%x at %lx-%lx\n",
700 /* Allocate non-prefetchable memory */
702 for (tmp = 0; tmp < count; tmp++) {
703 if (barlist[tmp]->res == NULL &&
704 barlist[tmp]->type == SYS_RES_MEMORY) {
705 flags = rman_make_alignment_flags(barlist[tmp]->count);
709 if (flags > 0) { /* If any non-prefetchable memory is requested... */
711 * First we allocate one big space for all resources of this
712 * type. We do this because our parent, pccbb, needs to open
713 * a window to forward all addresses within the window, and
714 * it would be best if nobody else has resources allocated
716 * (XXX: Perhaps there might be a better way to do this?)
719 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
720 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
722 start = rman_get_start(res);
723 end = rman_get_end(res);
724 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
727 * Now that we know the region is free, release it and hand it
728 * out piece by piece.
730 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
731 for (tmp = 0; tmp < count; tmp++) {
732 if (barlist[tmp]->res == NULL &&
733 barlist[tmp]->type == SYS_RES_MEMORY) {
734 barlist[tmp]->res = bus_alloc_resource(cbdev,
735 barlist[tmp]->type, &barlist[tmp]->rid,
736 start, end, barlist[tmp]->count,
737 rman_make_alignment_flags(
738 barlist[tmp]->count));
739 if (barlist[tmp]->res == NULL) {
740 DEVPRINTF((cbdev, "Cannot pre-allocate "
741 "memory for cardbus device\n"));
744 barlist[tmp]->start =
745 rman_get_start(barlist[tmp]->res);
746 barlist[tmp]->end = rman_get_end(
748 pci_write_config(child, barlist[tmp]->rid,
749 barlist[tmp]->start, 4);
750 DEVPRINTF((cbdev, "Non-prefetchable memory "
751 "rid=%x at %lx-%lx (%lx)\n",
752 barlist[tmp]->rid, barlist[tmp]->start,
753 barlist[tmp]->end, barlist[tmp]->count));
758 /* Allocate IO ports */
760 for (tmp = 0; tmp < count; tmp++) {
761 if (barlist[tmp]->res == NULL &&
762 barlist[tmp]->type == SYS_RES_IOPORT) {
763 flags = rman_make_alignment_flags(barlist[tmp]->count);
767 if (flags > 0) { /* If any IO port is requested... */
769 * First we allocate one big space for all resources of this
770 * type. We do this because our parent, pccbb, needs to open
771 * a window to forward all addresses within the window, and
772 * it would be best if nobody else has resources allocated
774 * (XXX: Perhaps there might be a better way to do this?)
777 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
778 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
779 start = rman_get_start(res);
780 end = rman_get_end(res);
781 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
783 * Now that we know the region is free, release it and hand it
784 * out piece by piece.
786 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
787 for (tmp = 0; tmp < count; tmp++) {
788 if (barlist[tmp]->res == NULL &&
789 barlist[tmp]->type == SYS_RES_IOPORT) {
790 barlist[tmp]->res = bus_alloc_resource(cbdev,
791 barlist[tmp]->type, &barlist[tmp]->rid,
792 start, end, barlist[tmp]->count,
793 rman_make_alignment_flags(
794 barlist[tmp]->count));
795 if (barlist[tmp]->res == NULL) {
796 DEVPRINTF((cbdev, "Cannot pre-allocate "
797 "IO port for cardbus device\n"));
800 barlist[tmp]->start =
801 rman_get_start(barlist[tmp]->res);
803 rman_get_end(barlist[tmp]->res);
804 pci_write_config(child, barlist[tmp]->rid,
805 barlist[tmp]->start, 4);
806 DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
807 barlist[tmp]->rid, barlist[tmp]->start,
814 /* XXX: Search CIS for IRQ description */
816 res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
818 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
819 rman_get_start(res), rman_get_end(res), 1);
820 rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
822 dinfo->pci.cfg.intline = rman_get_start(res);
823 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
829 * Adding a memory/io resource (sans CIS)
833 cardbus_add_map(device_t cbdev, device_t child, int reg)
835 struct cardbus_devinfo *dinfo = device_get_ivars(child);
836 struct resource_list_entry *rle;
841 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
846 if (reg == CARDBUS_ROM_REG)
847 testval = CARDBUS_ROM_ADDRMASK;
851 pci_write_config(child, reg, testval, 4);
852 testval = pci_read_config(child, reg, 4);
854 if (testval == ~0 || testval == 0)
857 if ((testval & 1) == 0)
858 type = SYS_RES_MEMORY;
860 type = SYS_RES_IOPORT;
862 size = CARDBUS_MAPREG_MEM_SIZE(testval);
863 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
865 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
869 cardbus_pickup_maps(device_t cbdev, device_t child)
871 struct cardbus_devinfo *dinfo = device_get_ivars(child);
872 struct cardbus_quirk *q;
876 * Try to pick up any resources that was not specified in CIS.
877 * Some devices (eg, 3c656) does not list all resources required by
878 * the driver in its CIS.
879 * XXX: should we do this or use quirks?
881 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
882 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
885 for (q = &cardbus_quirks[0]; q->devid; q++) {
886 if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
887 && q->type == CARDBUS_QUIRK_MAP_REG) {
888 cardbus_add_map(cbdev, child, q->arg1);
894 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id,
895 struct cis_tupleinfo **buff, int *nret)
897 struct tuple_callbacks cisread_callbacks[] = {
898 MAKETUPLE(NULL, nothing),
899 /* first entry will be overwritten */
900 MAKETUPLE(NULL, nothing),
901 MAKETUPLE(DEVICE, nothing),
902 MAKETUPLE(LONG_LINK_CB, unhandled),
903 MAKETUPLE(INDIRECT, unhandled),
904 MAKETUPLE(CONFIG_CB, nothing),
905 MAKETUPLE(CFTABLE_ENTRY_CB, nothing),
906 MAKETUPLE(LONGLINK_MFC, unhandled),
907 MAKETUPLE(BAR, nothing),
908 MAKETUPLE(PWR_MGMNT, nothing),
909 MAKETUPLE(EXTDEVICE, nothing),
910 MAKETUPLE(CHECKSUM, nothing),
911 MAKETUPLE(LONGLINK_A, unhandled),
912 MAKETUPLE(LONGLINK_C, unhandled),
913 MAKETUPLE(LINKTARGET, nothing),
914 MAKETUPLE(NO_LINK, nothing),
915 MAKETUPLE(VERS_1, nothing),
916 MAKETUPLE(ALTSTR, nothing),
917 MAKETUPLE(DEVICE_A, nothing),
918 MAKETUPLE(JEDEC_C, nothing),
919 MAKETUPLE(JEDEC_A, nothing),
920 MAKETUPLE(CONFIG, nothing),
921 MAKETUPLE(CFTABLE_ENTRY, nothing),
922 MAKETUPLE(DEVICE_OC, nothing),
923 MAKETUPLE(DEVICE_OA, nothing),
924 MAKETUPLE(DEVICE_GEO, nothing),
925 MAKETUPLE(DEVICE_GEO_A, nothing),
926 MAKETUPLE(MANFID, nothing),
927 MAKETUPLE(FUNCID, nothing),
928 MAKETUPLE(FUNCE, nothing),
929 MAKETUPLE(SWIL, nothing),
930 MAKETUPLE(VERS_2, nothing),
931 MAKETUPLE(FORMAT, nothing),
932 MAKETUPLE(GEOMETRY, nothing),
933 MAKETUPLE(BYTEORDER, nothing),
934 MAKETUPLE(DATE, nothing),
935 MAKETUPLE(BATTERY, nothing),
936 MAKETUPLE(ORG, nothing),
938 MAKETUPLE(GENERIC, nothing),
942 cisread_callbacks[0].id = id;
943 cisread_callbacks[0].name = "COPY";
944 cisread_callbacks[0].func = decode_tuple_copy;
947 ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
950 *nret = ncisread_buf;
955 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
958 for (i = 0; i < *nret; i++)
959 free(buff[i].data, M_DEVBUF);
961 free(buff, M_DEVBUF);
965 cardbus_do_cis(device_t cbdev, device_t child)
968 struct tuple_callbacks init_callbacks[] = {
969 MAKETUPLE(NULL, generic),
970 MAKETUPLE(DEVICE, generic),
971 MAKETUPLE(LONG_LINK_CB, unhandled),
972 MAKETUPLE(INDIRECT, unhandled),
973 MAKETUPLE(CONFIG_CB, generic),
974 MAKETUPLE(CFTABLE_ENTRY_CB, generic),
975 MAKETUPLE(LONGLINK_MFC, unhandled),
977 MAKETUPLE(PWR_MGMNT, generic),
978 MAKETUPLE(EXTDEVICE, generic),
979 MAKETUPLE(CHECKSUM, generic),
980 MAKETUPLE(LONGLINK_A, unhandled),
981 MAKETUPLE(LONGLINK_C, unhandled),
982 MAKETUPLE(LINKTARGET, linktarget),
983 MAKETUPLE(NO_LINK, generic),
984 MAKETUPLE(VERS_1, vers_1),
985 MAKETUPLE(ALTSTR, generic),
986 MAKETUPLE(DEVICE_A, generic),
987 MAKETUPLE(JEDEC_C, generic),
988 MAKETUPLE(JEDEC_A, generic),
989 MAKETUPLE(CONFIG, generic),
990 MAKETUPLE(CFTABLE_ENTRY, generic),
991 MAKETUPLE(DEVICE_OC, generic),
992 MAKETUPLE(DEVICE_OA, generic),
993 MAKETUPLE(DEVICE_GEO, generic),
994 MAKETUPLE(DEVICE_GEO_A, generic),
995 MAKETUPLE(MANFID, manfid),
996 MAKETUPLE(FUNCID, funcid),
997 MAKETUPLE(FUNCE, funce),
998 MAKETUPLE(SWIL, generic),
999 MAKETUPLE(VERS_2, generic),
1000 MAKETUPLE(FORMAT, generic),
1001 MAKETUPLE(GEOMETRY, generic),
1002 MAKETUPLE(BYTEORDER, generic),
1003 MAKETUPLE(DATE, generic),
1004 MAKETUPLE(BATTERY, generic),
1005 MAKETUPLE(ORG, generic),
1006 MAKETUPLE(END, end),
1007 MAKETUPLE(GENERIC, generic),
1010 ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1013 cardbus_pickup_maps(cbdev, child);
1014 return (cardbus_alloc_resources(cbdev, child));