1*d47bcd29Schs /* $NetBSD: pcmcia_cis_quirks.c,v 1.36 2019/11/10 21:16:36 chs Exp $ */
21a6e9eabSmarc
31a6e9eabSmarc /*
41a6e9eabSmarc * Copyright (c) 1998 Marc Horowitz. All rights reserved.
51a6e9eabSmarc *
61a6e9eabSmarc * Redistribution and use in source and binary forms, with or without
71a6e9eabSmarc * modification, are permitted provided that the following conditions
81a6e9eabSmarc * are met:
91a6e9eabSmarc * 1. Redistributions of source code must retain the above copyright
101a6e9eabSmarc * notice, this list of conditions and the following disclaimer.
111a6e9eabSmarc * 2. Redistributions in binary form must reproduce the above copyright
121a6e9eabSmarc * notice, this list of conditions and the following disclaimer in the
131a6e9eabSmarc * documentation and/or other materials provided with the distribution.
141a6e9eabSmarc * 3. All advertising materials mentioning features or use of this software
151a6e9eabSmarc * must display the following acknowledgement:
161a6e9eabSmarc * This product includes software developed by Marc Horowitz.
171a6e9eabSmarc * 4. The name of the author may not be used to endorse or promote products
181a6e9eabSmarc * derived from this software without specific prior written permission.
191a6e9eabSmarc *
201a6e9eabSmarc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
211a6e9eabSmarc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
221a6e9eabSmarc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
231a6e9eabSmarc * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
241a6e9eabSmarc * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
251a6e9eabSmarc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
261a6e9eabSmarc * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
271a6e9eabSmarc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
281a6e9eabSmarc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
291a6e9eabSmarc * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
301a6e9eabSmarc */
311a6e9eabSmarc
32ab5d9d2bSlukem #include <sys/cdefs.h>
33*d47bcd29Schs __KERNEL_RCSID(0, "$NetBSD: pcmcia_cis_quirks.c,v 1.36 2019/11/10 21:16:36 chs Exp $");
34ab5d9d2bSlukem
351a6e9eabSmarc #include <sys/param.h>
361a6e9eabSmarc #include <sys/systm.h>
371a6e9eabSmarc #include <sys/device.h>
38d5e42fa3Senami #include <sys/kernel.h>
391a6e9eabSmarc #include <sys/mbuf.h>
401a6e9eabSmarc
411a6e9eabSmarc #include <dev/pcmcia/pcmciadevs.h>
421a6e9eabSmarc #include <dev/pcmcia/pcmciareg.h>
431a6e9eabSmarc #include <dev/pcmcia/pcmciachip.h>
441a6e9eabSmarc #include <dev/pcmcia/pcmciavar.h>
451a6e9eabSmarc
461a6e9eabSmarc /* There are cards out there whose CIS flat-out lies. This file
471a6e9eabSmarc contains struct pcmcia_function chains for those devices. */
481a6e9eabSmarc
491a6e9eabSmarc /* these structures are just static templates which are then copied
501a6e9eabSmarc into "live" allocated structures */
511a6e9eabSmarc
5234c8ae80Sjdolecek static const struct pcmcia_function pcmcia_3cxem556_func0 = {
532ef37e3fSchristos .number = 0, /* function number */
542ef37e3fSchristos .function = PCMCIA_FUNCTION_NETWORK,
552ef37e3fSchristos .last_config_index = 0x07, /* last cfe number */
562ef37e3fSchristos .ccr_base = 0x800, /* ccr_base */
572ef37e3fSchristos .ccr_mask = 0x63, /* ccr_mask */
581a6e9eabSmarc };
591a6e9eabSmarc
6034c8ae80Sjdolecek static const struct pcmcia_config_entry pcmcia_3cxem556_func0_cfe0 = {
612ef37e3fSchristos .number = 0x07, /* cfe number */
622ef37e3fSchristos .flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL,
632ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
642ef37e3fSchristos .num_iospace = 1, /* num_iospace */
652ef37e3fSchristos .iomask = 4, /* iomask */
662ef37e3fSchristos .iospace = { { .length = 0x0010, .start = 0 } }, /* iospace */
672ef37e3fSchristos .irqmask = 0xffff, /* irqmask */
681a6e9eabSmarc };
691a6e9eabSmarc
7034c8ae80Sjdolecek static const struct pcmcia_function pcmcia_3cxem556_func1 = {
712ef37e3fSchristos .number = 1, /* function number */
722ef37e3fSchristos .function = PCMCIA_FUNCTION_SERIAL,
732ef37e3fSchristos .last_config_index = 0x27, /* last cfe number */
742ef37e3fSchristos .ccr_base = 0x900, /* ccr_base */
752ef37e3fSchristos .ccr_mask = 0x63, /* ccr_mask */
761a6e9eabSmarc };
771a6e9eabSmarc
7834c8ae80Sjdolecek static const struct pcmcia_config_entry pcmcia_3cxem556_func1_cfe0 = {
792ef37e3fSchristos .number = 0x27, /* cfe number */
802ef37e3fSchristos .flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL,
812ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
822ef37e3fSchristos .num_iospace = 1, /* num_iospace */
832ef37e3fSchristos .iomask = 3, /* iomask */
842ef37e3fSchristos .iospace = { { .length = 0x0008, .start = 0 } }, /* iospace */
852ef37e3fSchristos .irqmask = 0xffff, /* irqmask */
861a6e9eabSmarc };
871a6e9eabSmarc
8834c8ae80Sjdolecek static const struct pcmcia_function pcmcia_3ccfem556bi_func0 = {
892ef37e3fSchristos .number = 0, /* function number */
902ef37e3fSchristos .function = PCMCIA_FUNCTION_NETWORK,
912ef37e3fSchristos .last_config_index = 0x07, /* last cfe number */
922ef37e3fSchristos .ccr_base = 0x1000, /* ccr_base */
932ef37e3fSchristos .ccr_mask = 0x267, /* ccr_mask */
94f4f5698fSthorpej };
95f4f5698fSthorpej
9634c8ae80Sjdolecek static const struct pcmcia_config_entry pcmcia_3ccfem556bi_func0_cfe0 = {
972ef37e3fSchristos .number = 0x07, /* cfe number */
982ef37e3fSchristos .flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL,
992ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
1002ef37e3fSchristos .num_iospace = 1, /* num_iospace */
1012ef37e3fSchristos .iomask = 5, /* iomask */
1022ef37e3fSchristos .iospace = { { .length = 0x0020, .start = 0 } }, /* iospace */
103f4f5698fSthorpej };
104f4f5698fSthorpej
10534c8ae80Sjdolecek static const struct pcmcia_function pcmcia_3ccfem556bi_func1 = {
1062ef37e3fSchristos .number = 1, /* function number */
1072ef37e3fSchristos .function = PCMCIA_FUNCTION_SERIAL,
1082ef37e3fSchristos .last_config_index = 0x27, /* last cfe number */
1092ef37e3fSchristos .ccr_base = 0x1100, /* ccr_base */
1102ef37e3fSchristos .ccr_mask = 0x277, /* ccr_mask */
111f4f5698fSthorpej };
112f4f5698fSthorpej
11334c8ae80Sjdolecek static const struct pcmcia_config_entry pcmcia_3ccfem556bi_func1_cfe0 = {
1142ef37e3fSchristos .number = 0x27, /* cfe number */
1152ef37e3fSchristos .flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL,
1162ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
1172ef37e3fSchristos .num_iospace = 1, /* num_iospace */
1182ef37e3fSchristos .iomask = 3, /* iomask */
1192ef37e3fSchristos .iospace = { { .length = 0x0008, .start = 0 } }, /* iospace */
1202ef37e3fSchristos .irqmask = 0xffff, /* irqmask */
121f4f5698fSthorpej };
122f4f5698fSthorpej
12334c8ae80Sjdolecek static const struct pcmcia_function pcmcia_sveclancard_func0 = {
1242ef37e3fSchristos .number = 0, /* function number */
1252ef37e3fSchristos .function = PCMCIA_FUNCTION_NETWORK,
1262ef37e3fSchristos .last_config_index = 0x1, /* last cfe number */
1272ef37e3fSchristos .ccr_base = 0x100, /* ccr_base */
1282ef37e3fSchristos .ccr_mask = 0x1, /* ccr_mask */
1295d9e7724Smarc };
1305d9e7724Smarc
13134c8ae80Sjdolecek static const struct pcmcia_config_entry pcmcia_sveclancard_func0_cfe0 = {
1322ef37e3fSchristos .number = 0x1, /* cfe number */
1332ef37e3fSchristos .flags = PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_RDYBSY_ACTIVE |
1345d9e7724Smarc PCMCIA_CFE_WP_ACTIVE | PCMCIA_CFE_BVD_ACTIVE | PCMCIA_CFE_IO16,
1352ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
1362ef37e3fSchristos .num_iospace = 1, /* num_iospace */
1372ef37e3fSchristos .iomask = 5, /* iomask */
1382ef37e3fSchristos .iospace = { { .length = 0x20, .start = 0x300 } }, /* iospace */
1392ef37e3fSchristos .irqmask = 0xdeb8, /* irqmask */
1405d9e7724Smarc };
1415d9e7724Smarc
14234c8ae80Sjdolecek static const struct pcmcia_function pcmcia_ndc_nd5100_func0 = {
1432ef37e3fSchristos .number = 0, /* function number */
1442ef37e3fSchristos .function = PCMCIA_FUNCTION_NETWORK,
1452ef37e3fSchristos .last_config_index = 0x23, /* last cfe number */
1462ef37e3fSchristos .ccr_base = 0x3f8, /* ccr_base */
1472ef37e3fSchristos .ccr_mask = 0x3, /* ccr_mask */
148e083abcaSscw };
149e083abcaSscw
15034c8ae80Sjdolecek static const struct pcmcia_config_entry pcmcia_ndc_nd5100_func0_cfe0 = {
1512ef37e3fSchristos .number = 0x20, /* cfe number */
1522ef37e3fSchristos .flags = PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_IO16 |
1532ef37e3fSchristos PCMCIA_CFE_IRQLEVEL,
1542ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
1552ef37e3fSchristos .num_iospace = 1, /* num_iospace */
1562ef37e3fSchristos .iomask = 5, /* iomask */
1572ef37e3fSchristos .iospace = { { .length = 0x20, .start = 0x300 } }, /* iospace */
1582ef37e3fSchristos .irqmask = 0xdeb8, /* irqmask */
159e083abcaSscw };
160e083abcaSscw
16146a9744dSichiro static const struct pcmcia_function pcmcia_emtac_a2424i_func0 = {
1622ef37e3fSchristos .number = 0, /* function number */
1632ef37e3fSchristos .function = PCMCIA_FUNCTION_NETWORK,
1642ef37e3fSchristos .last_config_index = 0x21, /* last cfe number */
1652ef37e3fSchristos .ccr_base = 0x3e0, /* ccr_base */
1662ef37e3fSchristos .ccr_mask = 0x1, /* ccr_mask */
16746a9744dSichiro };
16846a9744dSichiro
16946a9744dSichiro static const struct pcmcia_config_entry pcmcia_emtac_a2424i_func0_cfe0 = {
1702ef37e3fSchristos .number = 0x21, /* cfe number */
1712ef37e3fSchristos .flags = PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL | PCMCIA_CFE_IRQPULSE,
1722ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
1732ef37e3fSchristos .num_iospace = 1, /* num_iospace */
1742ef37e3fSchristos .iomask = 6, /* iomask */
1752ef37e3fSchristos .iospace = { { .length = 0x40, .start = 0x100 } }, /* iospace */
1762ef37e3fSchristos .irqmask = 0xffff, /* irqmask */
17746a9744dSichiro };
17846a9744dSichiro
179c4552cabSichiro static const struct pcmcia_function pcmcia_fujitsu_j181_func0 = {
1802ef37e3fSchristos .number = 0, /* function number */
1812ef37e3fSchristos .function = PCMCIA_FUNCTION_NETWORK,
1822ef37e3fSchristos .last_config_index = 0x21, /* last cfe number */
1832ef37e3fSchristos .ccr_base = 0xfe0, /* ccr_base */
1842ef37e3fSchristos .ccr_mask = 0xf, /* ccr_mask */
185ff638ce5Sichiro };
186ff638ce5Sichiro
187c4552cabSichiro static const struct pcmcia_config_entry pcmcia_fujitsu_j181_func0_cfe0 = {
1882ef37e3fSchristos .number = 0xc, /* cfe number */
1892ef37e3fSchristos .flags = PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_WP_ACTIVE |
1902ef37e3fSchristos PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL |
1912ef37e3fSchristos PCMCIA_CFE_IRQPULSE,
1922ef37e3fSchristos .iftype = PCMCIA_IFTYPE_IO,
1932ef37e3fSchristos .num_iospace = 1, /* num_iospace */
1942ef37e3fSchristos .iomask = 10, /* iomask */
1952ef37e3fSchristos .iospace = { { .length = 0x20, .start = 0x140 } }, /* iospace */
1962ef37e3fSchristos .irqmask = 0xffff, /* irqmask */
197ff638ce5Sichiro };
198ff638ce5Sichiro
1998c2cbf1aSichiro static const struct pcmcia_function pcmcia_necinfrontia_ax420n_func0 = {
2008c2cbf1aSichiro .number = 0, /* function number */
2018c2cbf1aSichiro .function = PCMCIA_FUNCTION_SERIAL,
2028c2cbf1aSichiro .last_config_index = 0x38, /* last cfe number */
2038c2cbf1aSichiro .ccr_base = 0x200, /* ccr_base */
2048c2cbf1aSichiro .ccr_mask = 0x1f, /* ccr_mask */
2058c2cbf1aSichiro };
2068c2cbf1aSichiro
2078c2cbf1aSichiro static const struct pcmcia_config_entry pcmcia_necinfrontia_ax420n_func0_cfe0 = {
2088c2cbf1aSichiro .number = 0x25, /* cfe number */
2098c2cbf1aSichiro .flags = PCMCIA_CFE_RDYBSY_ACTIVE | PCMCIA_CFE_IO8 |
2108c2cbf1aSichiro PCMCIA_CFE_IRQLEVEL | PCMCIA_CFE_POWERDOWN |
2118c2cbf1aSichiro PCMCIA_CFE_AUDIO,
2128c2cbf1aSichiro .iftype = PCMCIA_IFTYPE_IO,
2138c2cbf1aSichiro .num_iospace = 1, /* num_iospace */
2148c2cbf1aSichiro .iomask = 10, /* iomask */
2158c2cbf1aSichiro .iospace = { { .length = 0x8, .start = 0x3f8 } }, /* iospace */
2168c2cbf1aSichiro .irqmask = 0x86bc, /* irqmask */
2178c2cbf1aSichiro };
2188c2cbf1aSichiro
21934c8ae80Sjdolecek static const struct pcmcia_cis_quirk pcmcia_cis_quirks[] = {
2208c2cbf1aSichiro { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556,
2218c2cbf1aSichiro PCMCIA_CIS_INVALID,
2221a6e9eabSmarc &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 },
2238c2cbf1aSichiro { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556,
2248c2cbf1aSichiro PCMCIA_CIS_INVALID,
2251a6e9eabSmarc &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 },
2268c2cbf1aSichiro { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT,
2278c2cbf1aSichiro PCMCIA_CIS_INVALID,
22836224362Stron &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 },
2298c2cbf1aSichiro { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT,
2308c2cbf1aSichiro PCMCIA_CIS_INVALID,
23136224362Stron &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 },
232f4f5698fSthorpej { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
233f4f5698fSthorpej PCMCIA_CIS_INVALID,
234f4f5698fSthorpej &pcmcia_3ccfem556bi_func0, &pcmcia_3ccfem556bi_func0_cfe0 },
235f4f5698fSthorpej { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
236f4f5698fSthorpej PCMCIA_CIS_INVALID,
237f4f5698fSthorpej &pcmcia_3ccfem556bi_func1, &pcmcia_3ccfem556bi_func1_cfe0 },
2388c2cbf1aSichiro { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
2398c2cbf1aSichiro PCMCIA_CIS_SVEC_LANCARD,
2405d9e7724Smarc &pcmcia_sveclancard_func0, &pcmcia_sveclancard_func0_cfe0 },
2418c2cbf1aSichiro { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
2428c2cbf1aSichiro PCMCIA_CIS_NDC_ND5100_E,
243e083abcaSscw &pcmcia_ndc_nd5100_func0, &pcmcia_ndc_nd5100_func0_cfe0 },
2448c2cbf1aSichiro { PCMCIA_VENDOR_EMTAC, PCMCIA_PRODUCT_EMTAC_WLAN,
2458c2cbf1aSichiro PCMCIA_CIS_INVALID,
24646a9744dSichiro &pcmcia_emtac_a2424i_func0, &pcmcia_emtac_a2424i_func0_cfe0 },
247c4552cabSichiro { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
248c4552cabSichiro PCMCIA_CIS_FUJITSU_FMV_J181,
249c4552cabSichiro &pcmcia_fujitsu_j181_func0, &pcmcia_fujitsu_j181_func0_cfe0 },
2508c2cbf1aSichiro { PCMCIA_VENDOR_NECINFRONTIA, PCMCIA_PRODUCT_NECINFRONTIA_AX420N,
2518c2cbf1aSichiro PCMCIA_CIS_INVALID,
2528c2cbf1aSichiro &pcmcia_necinfrontia_ax420n_func0,
2538c2cbf1aSichiro &pcmcia_necinfrontia_ax420n_func0_cfe0 },
2541a6e9eabSmarc };
2551a6e9eabSmarc
2568534032cSmycroft static const int pcmcia_cis_nquirks =
2571a6e9eabSmarc sizeof(pcmcia_cis_quirks) / sizeof(pcmcia_cis_quirks[0]);
2581a6e9eabSmarc
259d5e42fa3Senami void
pcmcia_check_cis_quirks(struct pcmcia_softc * sc)260454af1c0Sdsl pcmcia_check_cis_quirks(struct pcmcia_softc *sc)
2611a6e9eabSmarc {
2621a6e9eabSmarc int wiped = 0;
2632634ff1bSchristos size_t i, j;
26406de4264Slukem struct pcmcia_function *pf;
26534c8ae80Sjdolecek const struct pcmcia_function *pf_last;
26606de4264Slukem struct pcmcia_config_entry *cfe;
2672634ff1bSchristos struct pcmcia_card *card = &sc->card;
268d5e42fa3Senami const struct pcmcia_cis_quirk *quirk;
2691a6e9eabSmarc
270ae7cea0aSmarc pf = NULL;
2711a6e9eabSmarc pf_last = NULL;
2721a6e9eabSmarc
2738534032cSmycroft for (i = 0; i < pcmcia_cis_nquirks; i++) {
274d5e42fa3Senami quirk = &pcmcia_cis_quirks[i];
2752634ff1bSchristos
276d5e42fa3Senami if (card->manufacturer == quirk->manufacturer &&
277d5e42fa3Senami card->manufacturer != PCMCIA_VENDOR_INVALID &&
278d5e42fa3Senami card->product == quirk->product &&
2792634ff1bSchristos card->product != PCMCIA_PRODUCT_INVALID)
280d5e42fa3Senami goto match;
2812634ff1bSchristos
2822634ff1bSchristos for (j = 0; j < 2; j++)
2835c26271aSenami if (card->cis1_info[j] == NULL ||
2845c26271aSenami quirk->cis1_info[j] == NULL ||
2852634ff1bSchristos strcmp(card->cis1_info[j],
286d5e42fa3Senami quirk->cis1_info[j]) != 0)
287d5e42fa3Senami goto nomatch;
2882634ff1bSchristos
289d5e42fa3Senami match:
2901a6e9eabSmarc if (!wiped) {
2911a6e9eabSmarc if (pcmcia_verbose) {
2922634ff1bSchristos printf("%s: using CIS quirks for ",
29302b7e019Sdrochner device_xname(sc->dev));
2941a6e9eabSmarc for (j = 0; j < 4; j++) {
2952634ff1bSchristos if (card->cis1_info[j] == NULL)
2961a6e9eabSmarc break;
2971a6e9eabSmarc if (j)
2981a6e9eabSmarc printf(", ");
2992634ff1bSchristos printf("%s", card->cis1_info[j]);
3001a6e9eabSmarc }
3011a6e9eabSmarc printf("\n");
3021a6e9eabSmarc }
3032634ff1bSchristos pcmcia_free_pf(&card->pf_head);
3041a6e9eabSmarc wiped = 1;
3051a6e9eabSmarc }
3061a6e9eabSmarc
307d5e42fa3Senami if (pf_last != quirk->pf) {
308d5e42fa3Senami /*
309d5e42fa3Senami * XXX: a driver which still calls pcmcia_card_attach
310d5e42fa3Senami * very early attach stage should be fixed instead.
311d5e42fa3Senami */
312*d47bcd29Schs pf = malloc(sizeof(*pf), M_DEVBUF, M_WAITOK);
313d5e42fa3Senami *pf = *quirk->pf;
3141a6e9eabSmarc SIMPLEQ_INIT(&pf->cfe_head);
3152634ff1bSchristos SIMPLEQ_INSERT_TAIL(&card->pf_head, pf, pf_list);
316d5e42fa3Senami pf_last = quirk->pf;
3171a6e9eabSmarc }
318d5e42fa3Senami
319d5e42fa3Senami /*
320d5e42fa3Senami * XXX: see above.
321d5e42fa3Senami */
322*d47bcd29Schs cfe = malloc(sizeof(*cfe), M_DEVBUF, M_WAITOK);
323d5e42fa3Senami *cfe = *quirk->cfe;
324af27d513Schristos KASSERT(pf != NULL);
325d5e42fa3Senami SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
326d5e42fa3Senami
327d5e42fa3Senami nomatch:;
3281a6e9eabSmarc }
3291a6e9eabSmarc }
330