xref: /netbsd-src/sys/dev/pcmcia/pcmcia_cis_quirks.c (revision d47bcd296c8b39243dd81e9cc75ea86330d4eeaf)
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