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 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.c,v 1.50 2005/02/20 20:36:16 imp Exp $
27 * $DragonFly: src/sys/dev/pccard/cardbus/cardbus_cis.c,v 1.6 2007/07/05 12:08:54 sephe Exp $
31 * CIS Handling for the Cardbus Bus
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
41 #include <sys/endian.h>
43 #include <sys/pciio.h>
44 #include <bus/pci/pcivar.h>
45 #include <bus/pci/pcireg.h>
47 #include <bus/pccard/pccardvar.h>
48 #include <bus/pccard/pccard_cis.h>
50 #include <dev/pccard/cardbus/cardbusreg.h>
51 #include <dev/pccard/cardbus/cardbusvar.h>
52 #include <dev/pccard/cardbus/cardbus_cis.h>
54 extern int cardbus_cis_debug;
56 #define DPRINTF(a) if (cardbus_cis_debug) kprintf a
57 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
59 struct tuple_callbacks;
61 typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len,
62 uint8_t *tupledata, uint32_t start, uint32_t *off,
63 struct tuple_callbacks *info);
65 struct tuple_callbacks {
71 static int decode_tuple_generic(device_t cbdev, device_t child, int id,
72 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
73 struct tuple_callbacks *info);
74 static int decode_tuple_linktarget(device_t cbdev, device_t child, int id,
75 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
76 struct tuple_callbacks *info);
77 static int decode_tuple_vers_1(device_t cbdev, device_t child, int id,
78 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
79 struct tuple_callbacks *info);
80 static int decode_tuple_funcid(device_t cbdev, device_t child, int id,
81 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
82 struct tuple_callbacks *info);
83 static int decode_tuple_manfid(device_t cbdev, device_t child, int id,
84 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
85 struct tuple_callbacks *info);
86 static int decode_tuple_funce(device_t cbdev, device_t child, int id,
87 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
88 struct tuple_callbacks *info);
89 static int decode_tuple_bar(device_t cbdev, device_t child, int id,
90 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
91 struct tuple_callbacks *info);
92 static int decode_tuple_unhandled(device_t cbdev, device_t child, int id,
93 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
94 struct tuple_callbacks *info);
95 static int decode_tuple_end(device_t cbdev, device_t child, int id,
96 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
97 struct tuple_callbacks *info);
99 static int cardbus_read_tuple_conf(device_t cbdev, device_t child,
100 uint32_t start, uint32_t *off, int *tupleid, int *len,
102 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
103 uint32_t start, uint32_t *off, int *tupleid, int *len,
105 static int cardbus_read_tuple(device_t cbdev, device_t child,
106 struct resource *res, uint32_t start, uint32_t *off,
107 int *tupleid, int *len, uint8_t *tupledata);
108 static void cardbus_read_tuple_finish(device_t cbdev, device_t child,
109 int rid, struct resource *res);
110 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child,
111 uint32_t *start, int *rid);
112 static int decode_tuple(device_t cbdev, device_t child, int tupleid,
113 int len, uint8_t *tupledata, uint32_t start,
114 uint32_t *off, struct tuple_callbacks *callbacks);
115 static int cardbus_parse_cis(device_t cbdev, device_t child,
116 struct tuple_callbacks *callbacks);
118 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
120 static char *funcnames[] = {
134 * Handler functions for various CIS tuples
138 decode_tuple_generic(device_t cbdev, device_t child, int id,
139 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
140 struct tuple_callbacks *info)
144 if (cardbus_cis_debug) {
146 kprintf("TUPLE: %s [%d]:", info->name, len);
148 kprintf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
150 for (i = 0; i < len; i++) {
151 if (i % 0x10 == 0 && len > 0x10)
152 kprintf("\n 0x%02x:", i);
153 kprintf(" %02x", tupledata[i]);
161 decode_tuple_linktarget(device_t cbdev, device_t child, int id,
162 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
163 struct tuple_callbacks *info)
167 if (cardbus_cis_debug) {
168 kprintf("TUPLE: %s [%d]:", info->name, len);
170 for (i = 0; i < len; i++) {
171 if (i % 0x10 == 0 && len > 0x10)
172 kprintf("\n 0x%02x:", i);
173 kprintf(" %02x", tupledata[i]);
177 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
178 tupledata[2] != 'S') {
179 kprintf("Invalid data for CIS Link Target!\n");
180 decode_tuple_generic(cbdev, child, id, len, tupledata,
188 decode_tuple_vers_1(device_t cbdev, device_t child, int id,
189 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
190 struct tuple_callbacks *info)
194 if (cardbus_cis_debug) {
195 kprintf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
196 kprintf("Product name: ");
197 for (i = 2; i < len; i++) {
198 if (tupledata[i] == '\0')
200 else if (tupledata[i] == 0xff)
203 kprintf("%c", tupledata[i]);
211 decode_tuple_funcid(device_t cbdev, device_t child, int id,
212 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
213 struct tuple_callbacks *info)
215 struct cardbus_devinfo *dinfo = device_get_ivars(child);
216 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
219 if (cardbus_cis_debug) {
220 kprintf("Functions: ");
221 for (i = 0; i < len; i++) {
222 if (tupledata[i] < numnames)
223 kprintf("%s", funcnames[tupledata[i]]);
225 kprintf("Unknown(%d)", tupledata[i]);
232 dinfo->funcid = tupledata[0]; /* use first in list */
237 decode_tuple_manfid(device_t cbdev, device_t child, int id,
238 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
239 struct tuple_callbacks *info)
241 struct cardbus_devinfo *dinfo = device_get_ivars(child);
244 if (cardbus_cis_debug) {
245 kprintf("Manufacturer ID: ");
246 for (i = 0; i < len; i++)
247 kprintf("%02x", tupledata[i]);
252 dinfo->mfrid = tupledata[1] | (tupledata[2] << 8);
253 dinfo->prodid = tupledata[3] | (tupledata[4] << 8);
259 decode_tuple_funce(device_t cbdev, device_t child, int id,
260 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
261 struct tuple_callbacks *info)
263 struct cardbus_devinfo *dinfo = device_get_ivars(child);
266 if (cardbus_cis_debug) {
267 kprintf("Function Extension: ");
268 for (i = 0; i < len; i++)
269 kprintf("%02x", tupledata[i]);
272 if (len < 2) /* too short */
274 type = tupledata[0]; /* XXX <32 always? */
275 switch (dinfo->funcid) {
276 case PCCARD_FUNCTION_NETWORK:
278 case PCCARD_TPLFE_TYPE_LAN_NID:
279 if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) {
280 /* ignore, warning? */
283 bcopy(tupledata + 2, dinfo->funce.lan.nid,
287 dinfo->fepresent |= 1<<type;
294 decode_tuple_bar(device_t cbdev, device_t child, int id,
295 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
296 struct tuple_callbacks *info)
298 struct cardbus_devinfo *dinfo = device_get_ivars(child);
301 uint32_t bar, pci_bar;
304 device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
309 len = le32toh(*(uint32_t*)(tupledata + 2));
310 if (reg & TPL_BAR_REG_AS) {
311 type = SYS_RES_IOPORT;
313 type = SYS_RES_MEMORY;
316 bar = reg & TPL_BAR_REG_ASI_MASK;
318 device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
319 return (EINVAL); /* XXX Return an error? */
320 } else if (bar == 7) {
321 /* XXX Should we try to map in Option ROMs? */
325 /* Convert from BAR type to BAR offset */
326 bar = CARDBUS_BASE0_REG + (bar - 1) * 4;
328 if (type == SYS_RES_MEMORY) {
329 if (reg & TPL_BAR_REG_PREFETCHABLE)
330 dinfo->mprefetchable |= BARBIT(bar);
333 * XXX: It appears from a careful reading of the spec
334 * that we're not supposed to honor this when the bridge
335 * is not on the main system bus. PCI spec doesn't appear
336 * to allow for memory ranges not listed in the bridge's
337 * decode range to be decoded. The PC Card spec seems to
338 * indicate that this should only be done on x86 based
339 * machines, which seems to imply that on non-x86 machines
340 * the adddresses can be anywhere. This further implies that
341 * since the hardware can do it on non-x86 machines, it should
342 * be able to do it on x86 machines. Therefore, we can and
343 * should ignore this hint. Furthermore, the PC Card spec
344 * recommends always allocating memory above 1MB, contradicting
345 * the other part of the PC Card spec.
347 * NetBSD ignores this bit, but it also ignores the
348 * prefetchable bit too, so that's not an indication of
351 if (reg & TPL_BAR_REG_BELOW1MB)
352 dinfo->mbelow1mb |= BARBIT(bar);
357 * Sanity check the BAR length reported in the CIS with the length
358 * encoded in the PCI BAR. The latter seems to be more reliable.
359 * XXX - This probably belongs elsewhere.
361 pci_write_config(child, bar, 0xffffffff, 4);
362 pci_bar = pci_read_config(child, bar, 4);
363 if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) {
364 if (type == SYS_RES_MEMORY) {
369 len = 1 << (ffs(pci_bar) - 1);
372 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
373 (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
374 (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
375 " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
376 ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : ""));
378 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
381 * Mark the appropriate bit in the PCI command register so that
382 * device drivers will know which type of BARs can be used.
384 pci_enable_io(child, type);
389 decode_tuple_unhandled(device_t cbdev, device_t child, int id,
390 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
391 struct tuple_callbacks *info)
393 /* Make this message suck less XXX */
394 kprintf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
399 decode_tuple_end(device_t cbdev, device_t child, int id,
400 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
401 struct tuple_callbacks *info)
403 if (cardbus_cis_debug)
404 kprintf("CIS reading done\n");
409 * Functions to read the a tuple from the card
413 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
414 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
422 e = pci_read_config(child, loc - loc % 4, 4);
423 for (j = loc % 4; j > 0; j--)
426 for (i = loc, j = -2; j < *len; j++, i++) {
428 e = pci_read_config(child, i, 4);
434 tupledata[j] = 0xff & e;
442 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
443 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
446 bus_space_handle_t bh;
449 bt = rman_get_bustag(res);
450 bh = rman_get_bushandle(res);
452 *tupleid = bus_space_read_1(bt, bh, start + *off);
453 *len = bus_space_read_1(bt, bh, start + *off + 1);
454 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
461 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
462 uint32_t start, uint32_t *off, int *tupleid, int *len,
465 if (res == (struct resource*)~0UL) {
466 return (cardbus_read_tuple_conf(cbdev, child, start, off,
467 tupleid, len, tupledata));
469 return (cardbus_read_tuple_mem(cbdev, res, start, off,
470 tupleid, len, tupledata));
475 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
476 struct resource *res)
478 if (res != (struct resource*)~0UL) {
479 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
480 pci_write_config(child, rid, 0, 4);
481 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
485 static struct resource *
486 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
491 struct resource *res;
493 switch (CARDBUS_CIS_SPACE(*start)) {
494 case CARDBUS_CIS_ASI_TUPLE:
495 /* CIS in PCI config space need no initialization */
496 return ((struct resource*)~0UL);
497 case CARDBUS_CIS_ASI_BAR0:
498 case CARDBUS_CIS_ASI_BAR1:
499 case CARDBUS_CIS_ASI_BAR2:
500 case CARDBUS_CIS_ASI_BAR3:
501 case CARDBUS_CIS_ASI_BAR4:
502 case CARDBUS_CIS_ASI_BAR5:
503 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
505 case CARDBUS_CIS_ASI_ROM:
506 *rid = CARDBUS_ROM_REG;
509 * This mask doesn't contain the bit that actually enables
512 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
516 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
517 CARDBUS_CIS_SPACE(*start));
521 /* figure out how much space we need */
522 pci_write_config(child, *rid, 0xffffffff, 4);
523 testval = pci_read_config(child, *rid, 4);
526 * This bit has a different meaning depending if we are dealing
527 * with a normal BAR or an Option ROM BAR.
529 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
530 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
534 size = CARDBUS_MAPREG_MEM_SIZE(testval);
535 /* XXX Is this some kind of hack? */
538 /* allocate the memory space to read CIS */
539 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
540 rman_make_alignment_flags(size) | RF_ACTIVE);
542 device_printf(cbdev, "Unable to allocate resource "
546 pci_write_config(child, *rid,
547 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
548 CARDBUS_ROM_ENABLE : 0),
550 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
552 /* Flip to the right ROM image if CIS is in ROM */
553 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
555 bus_space_handle_t bh;
557 uint32_t imagebase = 0;
563 bt = rman_get_bustag(res);
564 bh = rman_get_bushandle(res);
566 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
567 for (romnum = 0;; romnum++) {
568 romsig = bus_space_read_2(bt, bh,
569 imagebase + CARDBUS_EXROM_SIGNATURE);
570 if (romsig != 0xaa55) {
571 device_printf(cbdev, "Bad header in rom %d: "
572 "[%x] %04x\n", romnum, imagebase +
573 CARDBUS_EXROM_SIGNATURE, romsig);
574 bus_release_resource(cbdev, SYS_RES_MEMORY,
581 * If this was the Option ROM image that we were
582 * looking for, then we are done.
584 if (romnum == imagenum)
587 /* Find out where the next Option ROM image is */
588 pcidata = imagebase + bus_space_read_2(bt, bh,
589 imagebase + CARDBUS_EXROM_DATA_PTR);
590 imagesize = bus_space_read_2(bt, bh,
591 pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
593 if (imagesize == 0) {
595 * XXX some ROMs seem to have this as zero,
596 * can we assume this means 1 block?
598 device_printf(cbdev, "Warning, size of Option "
599 "ROM image %d is 0 bytes, assuming 512 "
604 /* Image size is in 512 byte units */
607 if ((bus_space_read_1(bt, bh, pcidata +
608 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
609 device_printf(cbdev, "Cannot find CIS in "
611 bus_release_resource(cbdev, SYS_RES_MEMORY,
616 imagebase += imagesize;
618 *start = imagebase + CARDBUS_CIS_ADDR(*start);
620 *start = CARDBUS_CIS_ADDR(*start);
627 * Dispatch the right handler function per tuple
631 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
632 uint8_t *tupledata, uint32_t start, uint32_t *off,
633 struct tuple_callbacks *callbacks)
636 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
637 if (tupleid == callbacks[i].id)
638 return (callbacks[i].func(cbdev, child, tupleid, len,
639 tupledata, start, off, &callbacks[i]));
641 return (callbacks[i].func(cbdev, child, tupleid, len,
642 tupledata, start, off, NULL));
646 cardbus_parse_cis(device_t cbdev, device_t child,
647 struct tuple_callbacks *callbacks)
649 uint8_t tupledata[MAXTUPLESIZE];
652 int expect_linktarget;
654 struct resource *res;
657 bzero(tupledata, MAXTUPLESIZE);
658 expect_linktarget = TRUE;
659 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0) {
660 device_printf(cbdev, "CIS pointer is 0!\n");
664 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
666 device_printf(cbdev, "Unable to allocate resources for CIS\n");
671 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
672 &tupleid, &len, tupledata)) {
673 device_printf(cbdev, "Failed to read CIS.\n");
674 cardbus_read_tuple_finish(cbdev, child, rid, res);
678 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
679 device_printf(cbdev, "Expecting link target, got 0x%x\n",
681 cardbus_read_tuple_finish(cbdev, child, rid, res);
684 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
685 tupledata, start, &off, callbacks);
686 if (expect_linktarget != 0) {
687 device_printf(cbdev, "Parsing failed with %d\n",
689 cardbus_read_tuple_finish(cbdev, child, rid, res);
690 return (expect_linktarget);
692 } while (tupleid != CISTPL_END);
693 cardbus_read_tuple_finish(cbdev, child, rid, res);
698 cardbus_do_cis(device_t cbdev, device_t child)
701 struct tuple_callbacks init_callbacks[] = {
702 MAKETUPLE(LONGLINK_CB, unhandled),
703 MAKETUPLE(INDIRECT, unhandled),
704 MAKETUPLE(LONGLINK_MFC, unhandled),
706 MAKETUPLE(LONGLINK_A, unhandled),
707 MAKETUPLE(LONGLINK_C, unhandled),
708 MAKETUPLE(LINKTARGET, linktarget),
709 MAKETUPLE(VERS_1, vers_1),
710 MAKETUPLE(MANFID, manfid),
711 MAKETUPLE(FUNCID, funcid),
712 MAKETUPLE(FUNCE, funce),
714 MAKETUPLE(GENERIC, generic),
717 ret = cardbus_parse_cis(cbdev, child, init_callbacks);