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 $
30 * CIS Handling for the Cardbus Bus
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
40 #include <sys/endian.h>
42 #include <sys/pciio.h>
43 #include <bus/pci/pcivar.h>
44 #include <bus/pci/pcireg.h>
46 #include <bus/pccard/pccardvar.h>
47 #include <bus/pccard/pccard_cis.h>
49 #include <dev/pccard/cardbus/cardbusreg.h>
50 #include <dev/pccard/cardbus/cardbusvar.h>
51 #include <dev/pccard/cardbus/cardbus_cis.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 struct tuple_callbacks
;
60 typedef int (tuple_cb
) (device_t cbdev
, device_t child
, int id
, int len
,
61 uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
62 struct tuple_callbacks
*info
);
64 struct tuple_callbacks
{
70 static int decode_tuple_generic(device_t cbdev
, device_t child
, int id
,
71 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
72 struct tuple_callbacks
*info
);
73 static int decode_tuple_linktarget(device_t cbdev
, device_t child
, int id
,
74 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
75 struct tuple_callbacks
*info
);
76 static int decode_tuple_vers_1(device_t cbdev
, device_t child
, int id
,
77 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
78 struct tuple_callbacks
*info
);
79 static int decode_tuple_funcid(device_t cbdev
, device_t child
, int id
,
80 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
81 struct tuple_callbacks
*info
);
82 static int decode_tuple_manfid(device_t cbdev
, device_t child
, int id
,
83 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
84 struct tuple_callbacks
*info
);
85 static int decode_tuple_funce(device_t cbdev
, device_t child
, int id
,
86 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
87 struct tuple_callbacks
*info
);
88 static int decode_tuple_bar(device_t cbdev
, device_t child
, int id
,
89 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
90 struct tuple_callbacks
*info
);
91 static int decode_tuple_unhandled(device_t cbdev
, device_t child
, int id
,
92 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
93 struct tuple_callbacks
*info
);
94 static int decode_tuple_end(device_t cbdev
, device_t child
, int id
,
95 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
96 struct tuple_callbacks
*info
);
98 static int cardbus_read_tuple_conf(device_t cbdev
, device_t child
,
99 uint32_t start
, uint32_t *off
, int *tupleid
, int *len
,
101 static int cardbus_read_tuple_mem(device_t cbdev
, struct resource
*res
,
102 uint32_t start
, uint32_t *off
, int *tupleid
, int *len
,
104 static int cardbus_read_tuple(device_t cbdev
, device_t child
,
105 struct resource
*res
, uint32_t start
, uint32_t *off
,
106 int *tupleid
, int *len
, uint8_t *tupledata
);
107 static void cardbus_read_tuple_finish(device_t cbdev
, device_t child
,
108 int rid
, struct resource
*res
);
109 static struct resource
*cardbus_read_tuple_init(device_t cbdev
, device_t child
,
110 uint32_t *start
, int *rid
);
111 static int decode_tuple(device_t cbdev
, device_t child
, int tupleid
,
112 int len
, uint8_t *tupledata
, uint32_t start
,
113 uint32_t *off
, struct tuple_callbacks
*callbacks
);
114 static int cardbus_parse_cis(device_t cbdev
, device_t child
,
115 struct tuple_callbacks
*callbacks
);
117 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
119 static char *funcnames
[] = {
133 * Handler functions for various CIS tuples
137 decode_tuple_generic(device_t cbdev
, device_t child
, int id
,
138 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
139 struct tuple_callbacks
*info
)
143 if (cardbus_cis_debug
) {
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
]);
160 decode_tuple_linktarget(device_t cbdev
, device_t child
, int id
,
161 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
162 struct tuple_callbacks
*info
)
166 if (cardbus_cis_debug
) {
167 kprintf("TUPLE: %s [%d]:", info
->name
, len
);
169 for (i
= 0; i
< len
; i
++) {
170 if (i
% 0x10 == 0 && len
> 0x10)
171 kprintf("\n 0x%02x:", i
);
172 kprintf(" %02x", tupledata
[i
]);
176 if (len
!= 3 || tupledata
[0] != 'C' || tupledata
[1] != 'I' ||
177 tupledata
[2] != 'S') {
178 kprintf("Invalid data for CIS Link Target!\n");
179 decode_tuple_generic(cbdev
, child
, id
, len
, tupledata
,
187 decode_tuple_vers_1(device_t cbdev
, device_t child
, int id
,
188 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
189 struct tuple_callbacks
*info
)
193 if (cardbus_cis_debug
) {
194 kprintf("Product version: %d.%d\n", tupledata
[0], tupledata
[1]);
195 kprintf("Product name: ");
196 for (i
= 2; i
< len
; i
++) {
197 if (tupledata
[i
] == '\0')
199 else if (tupledata
[i
] == 0xff)
202 kprintf("%c", tupledata
[i
]);
210 decode_tuple_funcid(device_t cbdev
, device_t child
, int id
,
211 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
212 struct tuple_callbacks
*info
)
214 struct cardbus_devinfo
*dinfo
= device_get_ivars(child
);
215 int numnames
= NELEM(funcnames
);
218 if (cardbus_cis_debug
) {
219 kprintf("Functions: ");
220 for (i
= 0; i
< len
; i
++) {
221 if (tupledata
[i
] < numnames
)
222 kprintf("%s", funcnames
[tupledata
[i
]]);
224 kprintf("Unknown(%d)", tupledata
[i
]);
231 dinfo
->funcid
= tupledata
[0]; /* use first in list */
236 decode_tuple_manfid(device_t cbdev
, device_t child
, int id
,
237 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
238 struct tuple_callbacks
*info
)
240 struct cardbus_devinfo
*dinfo
= device_get_ivars(child
);
243 if (cardbus_cis_debug
) {
244 kprintf("Manufacturer ID: ");
245 for (i
= 0; i
< len
; i
++)
246 kprintf("%02x", tupledata
[i
]);
251 dinfo
->mfrid
= tupledata
[1] | (tupledata
[2] << 8);
252 dinfo
->prodid
= tupledata
[3] | (tupledata
[4] << 8);
258 decode_tuple_funce(device_t cbdev
, device_t child
, int id
,
259 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
260 struct tuple_callbacks
*info
)
262 struct cardbus_devinfo
*dinfo
= device_get_ivars(child
);
265 if (cardbus_cis_debug
) {
266 kprintf("Function Extension: ");
267 for (i
= 0; i
< len
; i
++)
268 kprintf("%02x", tupledata
[i
]);
271 if (len
< 2) /* too short */
273 type
= tupledata
[0]; /* XXX <32 always? */
274 switch (dinfo
->funcid
) {
275 case PCCARD_FUNCTION_NETWORK
:
277 case PCCARD_TPLFE_TYPE_LAN_NID
:
278 if (tupledata
[1] > sizeof(dinfo
->funce
.lan
.nid
)) {
279 /* ignore, warning? */
282 bcopy(tupledata
+ 2, dinfo
->funce
.lan
.nid
,
286 dinfo
->fepresent
|= 1<<type
;
293 decode_tuple_bar(device_t cbdev
, device_t child
, int id
,
294 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
295 struct tuple_callbacks
*info
)
297 struct cardbus_devinfo
*dinfo
= device_get_ivars(child
);
300 uint32_t bar
, pci_bar
;
303 device_printf(cbdev
, "CIS BAR length not 6 (%d)\n", len
);
308 len
= le32toh(*(uint32_t*)(tupledata
+ 2));
309 if (reg
& TPL_BAR_REG_AS
) {
310 type
= SYS_RES_IOPORT
;
312 type
= SYS_RES_MEMORY
;
315 bar
= reg
& TPL_BAR_REG_ASI_MASK
;
317 device_printf(cbdev
, "Invalid BAR type 0 in CIS\n");
318 return (EINVAL
); /* XXX Return an error? */
319 } else if (bar
== 7) {
320 /* XXX Should we try to map in Option ROMs? */
324 /* Convert from BAR type to BAR offset */
325 bar
= CARDBUS_BASE0_REG
+ (bar
- 1) * 4;
327 if (type
== SYS_RES_MEMORY
) {
328 if (reg
& TPL_BAR_REG_PREFETCHABLE
)
329 dinfo
->mprefetchable
|= BARBIT(bar
);
332 * XXX: It appears from a careful reading of the spec
333 * that we're not supposed to honor this when the bridge
334 * is not on the main system bus. PCI spec doesn't appear
335 * to allow for memory ranges not listed in the bridge's
336 * decode range to be decoded. The PC Card spec seems to
337 * indicate that this should only be done on x86 based
338 * machines, which seems to imply that on non-x86 machines
339 * the adddresses can be anywhere. This further implies that
340 * since the hardware can do it on non-x86 machines, it should
341 * be able to do it on x86 machines. Therefore, we can and
342 * should ignore this hint. Furthermore, the PC Card spec
343 * recommends always allocating memory above 1MB, contradicting
344 * the other part of the PC Card spec.
346 * NetBSD ignores this bit, but it also ignores the
347 * prefetchable bit too, so that's not an indication of
350 if (reg
& TPL_BAR_REG_BELOW1MB
)
351 dinfo
->mbelow1mb
|= BARBIT(bar
);
356 * Sanity check the BAR length reported in the CIS with the length
357 * encoded in the PCI BAR. The latter seems to be more reliable.
358 * XXX - This probably belongs elsewhere.
360 pci_write_config(child
, bar
, 0xffffffff, 4);
361 pci_bar
= pci_read_config(child
, bar
, 4);
362 if ((pci_bar
!= 0x0) && (pci_bar
!= 0xffffffff)) {
363 if (type
== SYS_RES_MEMORY
) {
368 len
= 1 << (ffs(pci_bar
) - 1);
371 DEVPRINTF((cbdev
, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
372 (type
== SYS_RES_MEMORY
) ? "MEM" : "IO", bar
, len
,
373 (type
== SYS_RES_MEMORY
&& dinfo
->mprefetchable
& BARBIT(bar
)) ?
374 " (Prefetchable)" : "", type
== SYS_RES_MEMORY
?
375 ((dinfo
->mbelow1mb
& BARBIT(bar
)) ? " (Below 1Mb)" : "") : ""));
377 resource_list_add(&dinfo
->pci
.resources
, type
, bar
, 0UL, ~0UL, len
, -1);
380 * Mark the appropriate bit in the PCI command register so that
381 * device drivers will know which type of BARs can be used.
383 pci_enable_io(child
, type
);
388 decode_tuple_unhandled(device_t cbdev
, device_t child
, int id
,
389 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
390 struct tuple_callbacks
*info
)
392 /* Make this message suck less XXX */
393 kprintf("TUPLE: %s [%d] is unhandled! Bailing...", info
->name
, len
);
398 decode_tuple_end(device_t cbdev
, device_t child
, int id
,
399 int len
, uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
400 struct tuple_callbacks
*info
)
402 if (cardbus_cis_debug
)
403 kprintf("CIS reading done\n");
408 * Functions to read the a tuple from the card
412 cardbus_read_tuple_conf(device_t cbdev
, device_t child
, uint32_t start
,
413 uint32_t *off
, int *tupleid
, int *len
, uint8_t *tupledata
)
421 e
= pci_read_config(child
, loc
- loc
% 4, 4);
422 for (j
= loc
% 4; j
> 0; j
--)
425 for (i
= loc
, j
= -2; j
< *len
; j
++, i
++) {
427 e
= pci_read_config(child
, i
, 4);
433 tupledata
[j
] = 0xff & e
;
441 cardbus_read_tuple_mem(device_t cbdev
, struct resource
*res
, uint32_t start
,
442 uint32_t *off
, int *tupleid
, int *len
, uint8_t *tupledata
)
445 bus_space_handle_t bh
;
448 bt
= rman_get_bustag(res
);
449 bh
= rman_get_bushandle(res
);
451 *tupleid
= bus_space_read_1(bt
, bh
, start
+ *off
);
452 *len
= bus_space_read_1(bt
, bh
, start
+ *off
+ 1);
453 bus_space_read_region_1(bt
, bh
, *off
+ start
+ 2, tupledata
, *len
);
460 cardbus_read_tuple(device_t cbdev
, device_t child
, struct resource
*res
,
461 uint32_t start
, uint32_t *off
, int *tupleid
, int *len
,
464 if (res
== (struct resource
*)~0UL) {
465 return (cardbus_read_tuple_conf(cbdev
, child
, start
, off
,
466 tupleid
, len
, tupledata
));
468 return (cardbus_read_tuple_mem(cbdev
, res
, start
, off
,
469 tupleid
, len
, tupledata
));
474 cardbus_read_tuple_finish(device_t cbdev
, device_t child
, int rid
,
475 struct resource
*res
)
477 if (res
!= (struct resource
*)~0UL) {
478 bus_release_resource(cbdev
, SYS_RES_MEMORY
, rid
, res
);
479 pci_write_config(child
, rid
, 0, 4);
480 PCI_DISABLE_IO(cbdev
, child
, SYS_RES_MEMORY
);
484 static struct resource
*
485 cardbus_read_tuple_init(device_t cbdev
, device_t child
, uint32_t *start
,
490 struct resource
*res
;
492 switch (CARDBUS_CIS_SPACE(*start
)) {
493 case CARDBUS_CIS_ASI_TUPLE
:
494 /* CIS in PCI config space need no initialization */
495 return ((struct resource
*)~0UL);
496 case CARDBUS_CIS_ASI_BAR0
:
497 case CARDBUS_CIS_ASI_BAR1
:
498 case CARDBUS_CIS_ASI_BAR2
:
499 case CARDBUS_CIS_ASI_BAR3
:
500 case CARDBUS_CIS_ASI_BAR4
:
501 case CARDBUS_CIS_ASI_BAR5
:
502 *rid
= CARDBUS_BASE0_REG
+ (CARDBUS_CIS_SPACE(*start
) - 1) * 4;
504 case CARDBUS_CIS_ASI_ROM
:
505 *rid
= CARDBUS_ROM_REG
;
508 * This mask doesn't contain the bit that actually enables
511 pci_write_config(child
, *rid
, CARDBUS_ROM_ADDRMASK
, 4);
515 device_printf(cbdev
, "Unable to read CIS: Unknown space: %d\n",
516 CARDBUS_CIS_SPACE(*start
));
520 /* figure out how much space we need */
521 pci_write_config(child
, *rid
, 0xffffffff, 4);
522 testval
= pci_read_config(child
, *rid
, 4);
525 * This bit has a different meaning depending if we are dealing
526 * with a normal BAR or an Option ROM BAR.
528 if (((testval
& 0x1) == 0x1) && (*rid
!= CARDBUS_ROM_REG
)) {
529 device_printf(cbdev
, "CIS Space is IO, expecting memory.\n");
533 size
= CARDBUS_MAPREG_MEM_SIZE(testval
);
534 /* XXX Is this some kind of hack? */
537 /* allocate the memory space to read CIS */
538 res
= bus_alloc_resource(cbdev
, SYS_RES_MEMORY
, rid
, 0, ~0, size
,
539 rman_make_alignment_flags(size
) | RF_ACTIVE
);
541 device_printf(cbdev
, "Unable to allocate resource "
545 pci_write_config(child
, *rid
,
546 rman_get_start(res
) | ((*rid
== CARDBUS_ROM_REG
)?
547 CARDBUS_ROM_ENABLE
: 0),
549 PCI_ENABLE_IO(cbdev
, child
, SYS_RES_MEMORY
);
551 /* Flip to the right ROM image if CIS is in ROM */
552 if (CARDBUS_CIS_SPACE(*start
) == CARDBUS_CIS_ASI_ROM
) {
554 bus_space_handle_t bh
;
556 uint32_t imagebase
= 0;
562 bt
= rman_get_bustag(res
);
563 bh
= rman_get_bushandle(res
);
565 imagenum
= CARDBUS_CIS_ASI_ROM_IMAGE(*start
);
566 for (romnum
= 0;; romnum
++) {
567 romsig
= bus_space_read_2(bt
, bh
,
568 imagebase
+ CARDBUS_EXROM_SIGNATURE
);
569 if (romsig
!= 0xaa55) {
570 device_printf(cbdev
, "Bad header in rom %d: "
571 "[%x] %04x\n", romnum
, imagebase
+
572 CARDBUS_EXROM_SIGNATURE
, romsig
);
573 bus_release_resource(cbdev
, SYS_RES_MEMORY
,
580 * If this was the Option ROM image that we were
581 * looking for, then we are done.
583 if (romnum
== imagenum
)
586 /* Find out where the next Option ROM image is */
587 pcidata
= imagebase
+ bus_space_read_2(bt
, bh
,
588 imagebase
+ CARDBUS_EXROM_DATA_PTR
);
589 imagesize
= bus_space_read_2(bt
, bh
,
590 pcidata
+ CARDBUS_EXROM_DATA_IMAGE_LENGTH
);
592 if (imagesize
== 0) {
594 * XXX some ROMs seem to have this as zero,
595 * can we assume this means 1 block?
597 device_printf(cbdev
, "Warning, size of Option "
598 "ROM image %d is 0 bytes, assuming 512 "
603 /* Image size is in 512 byte units */
606 if ((bus_space_read_1(bt
, bh
, pcidata
+
607 CARDBUS_EXROM_DATA_INDICATOR
) & 0x80) != 0) {
608 device_printf(cbdev
, "Cannot find CIS in "
610 bus_release_resource(cbdev
, SYS_RES_MEMORY
,
615 imagebase
+= imagesize
;
617 *start
= imagebase
+ CARDBUS_CIS_ADDR(*start
);
619 *start
= CARDBUS_CIS_ADDR(*start
);
626 * Dispatch the right handler function per tuple
630 decode_tuple(device_t cbdev
, device_t child
, int tupleid
, int len
,
631 uint8_t *tupledata
, uint32_t start
, uint32_t *off
,
632 struct tuple_callbacks
*callbacks
)
635 for (i
= 0; callbacks
[i
].id
!= CISTPL_GENERIC
; i
++) {
636 if (tupleid
== callbacks
[i
].id
)
637 return (callbacks
[i
].func(cbdev
, child
, tupleid
, len
,
638 tupledata
, start
, off
, &callbacks
[i
]));
640 return (callbacks
[i
].func(cbdev
, child
, tupleid
, len
,
641 tupledata
, start
, off
, NULL
));
645 cardbus_parse_cis(device_t cbdev
, device_t child
,
646 struct tuple_callbacks
*callbacks
)
648 uint8_t tupledata
[MAXTUPLESIZE
];
649 int tupleid
= CISTPL_NULL
;
651 int expect_linktarget
;
653 struct resource
*res
;
656 bzero(tupledata
, MAXTUPLESIZE
);
657 expect_linktarget
= TRUE
;
658 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
);