Home | History | Annotate | Line # | Download | only in pcmcia
pcmcia_cis_quirks.c revision 1.31.4.1
      1  1.31.4.1      yamt /*	$NetBSD: pcmcia_cis_quirks.c,v 1.31.4.1 2009/05/04 08:13:14 yamt Exp $	*/
      2       1.1      marc 
      3       1.1      marc /*
      4       1.1      marc  * Copyright (c) 1998 Marc Horowitz.  All rights reserved.
      5       1.1      marc  *
      6       1.1      marc  * Redistribution and use in source and binary forms, with or without
      7       1.1      marc  * modification, are permitted provided that the following conditions
      8       1.1      marc  * are met:
      9       1.1      marc  * 1. Redistributions of source code must retain the above copyright
     10       1.1      marc  *    notice, this list of conditions and the following disclaimer.
     11       1.1      marc  * 2. Redistributions in binary form must reproduce the above copyright
     12       1.1      marc  *    notice, this list of conditions and the following disclaimer in the
     13       1.1      marc  *    documentation and/or other materials provided with the distribution.
     14       1.1      marc  * 3. All advertising materials mentioning features or use of this software
     15       1.1      marc  *    must display the following acknowledgement:
     16       1.1      marc  *	This product includes software developed by Marc Horowitz.
     17       1.1      marc  * 4. The name of the author may not be used to endorse or promote products
     18       1.1      marc  *    derived from this software without specific prior written permission.
     19       1.1      marc  *
     20       1.1      marc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21       1.1      marc  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22       1.1      marc  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23       1.1      marc  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24       1.1      marc  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25       1.1      marc  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26       1.1      marc  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27       1.1      marc  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28       1.1      marc  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29       1.1      marc  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30       1.1      marc  */
     31      1.13     lukem 
     32      1.13     lukem #include <sys/cdefs.h>
     33  1.31.4.1      yamt __KERNEL_RCSID(0, "$NetBSD: pcmcia_cis_quirks.c,v 1.31.4.1 2009/05/04 08:13:14 yamt Exp $");
     34       1.1      marc 
     35       1.1      marc #include <sys/param.h>
     36       1.1      marc #include <sys/systm.h>
     37       1.1      marc #include <sys/device.h>
     38      1.23     enami #include <sys/kernel.h>
     39       1.1      marc #include <sys/mbuf.h>
     40       1.1      marc 
     41       1.1      marc #include <dev/pcmcia/pcmciadevs.h>
     42       1.1      marc #include <dev/pcmcia/pcmciareg.h>
     43       1.1      marc #include <dev/pcmcia/pcmciachip.h>
     44       1.1      marc #include <dev/pcmcia/pcmciavar.h>
     45       1.1      marc 
     46       1.1      marc /* There are cards out there whose CIS flat-out lies.  This file
     47       1.1      marc    contains struct pcmcia_function chains for those devices. */
     48       1.1      marc 
     49       1.1      marc /* these structures are just static templates which are then copied
     50       1.1      marc    into "live" allocated structures */
     51       1.1      marc 
     52       1.8  jdolecek static const struct pcmcia_function pcmcia_3cxem556_func0 = {
     53      1.29  christos 	.number = 0,				/* function number */
     54      1.29  christos 	.function = PCMCIA_FUNCTION_NETWORK,
     55      1.29  christos 	.last_config_index = 0x07,		/* last cfe number */
     56      1.29  christos 	.ccr_base = 0x800,			/* ccr_base */
     57      1.29  christos 	.ccr_mask = 0x63,			/* ccr_mask */
     58       1.1      marc };
     59       1.1      marc 
     60       1.8  jdolecek static const struct pcmcia_config_entry pcmcia_3cxem556_func0_cfe0 = {
     61      1.29  christos 	.number = 0x07,			/* cfe number */
     62      1.29  christos 	.flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL,
     63      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
     64      1.29  christos 	.num_iospace = 1,		/* num_iospace */
     65      1.29  christos 	.iomask = 4,			/* iomask */
     66      1.29  christos 	.iospace = { { .length = 0x0010, .start = 0 } },	/* iospace */
     67      1.29  christos 	.irqmask = 0xffff,		/* irqmask */
     68       1.1      marc };
     69       1.1      marc 
     70       1.8  jdolecek static const struct pcmcia_function pcmcia_3cxem556_func1 = {
     71      1.29  christos 	.number = 1,			/* function number */
     72      1.29  christos 	.function = PCMCIA_FUNCTION_SERIAL,
     73      1.29  christos 	.last_config_index = 0x27,	/* last cfe number */
     74      1.29  christos 	.ccr_base = 0x900,		/* ccr_base */
     75      1.29  christos 	.ccr_mask = 0x63,		/* ccr_mask */
     76       1.1      marc };
     77       1.1      marc 
     78       1.8  jdolecek static const struct pcmcia_config_entry pcmcia_3cxem556_func1_cfe0 = {
     79      1.29  christos 	.number = 0x27,			/* cfe number */
     80      1.29  christos 	.flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL,
     81      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
     82      1.29  christos 	.num_iospace = 1,		/* num_iospace */
     83      1.29  christos 	.iomask = 3,			/* iomask */
     84      1.29  christos 	.iospace = { { .length = 0x0008, .start = 0 } },	/* iospace */
     85      1.29  christos 	.irqmask = 0xffff,		/* irqmask */
     86       1.1      marc };
     87       1.1      marc 
     88       1.8  jdolecek static const struct pcmcia_function pcmcia_3ccfem556bi_func0 = {
     89      1.29  christos 	.number = 0,			/* function number */
     90      1.29  christos 	.function = PCMCIA_FUNCTION_NETWORK,
     91      1.29  christos 	.last_config_index = 0x07,	/* last cfe number */
     92      1.29  christos 	.ccr_base = 0x1000,		/* ccr_base */
     93      1.29  christos 	.ccr_mask = 0x267,		/* ccr_mask */
     94       1.5   thorpej };
     95       1.5   thorpej 
     96       1.8  jdolecek static const struct pcmcia_config_entry pcmcia_3ccfem556bi_func0_cfe0 = {
     97      1.29  christos 	.number = 0x07,		/* cfe number */
     98      1.29  christos 	.flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL,
     99      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
    100      1.29  christos 	.num_iospace = 1,	/* num_iospace */
    101      1.29  christos 	.iomask = 5,			/* iomask */
    102      1.29  christos 	.iospace = { { .length = 0x0020, .start = 0 } },	/* iospace */
    103       1.5   thorpej };
    104       1.5   thorpej 
    105       1.8  jdolecek static const struct pcmcia_function pcmcia_3ccfem556bi_func1 = {
    106      1.29  christos 	.number = 1,			/* function number */
    107      1.29  christos 	.function = PCMCIA_FUNCTION_SERIAL,
    108      1.29  christos 	.last_config_index = 0x27,	/* last cfe number */
    109      1.29  christos 	.ccr_base = 0x1100,		/* ccr_base */
    110      1.29  christos 	.ccr_mask = 0x277,		/* ccr_mask */
    111       1.5   thorpej };
    112       1.5   thorpej 
    113       1.8  jdolecek static const struct pcmcia_config_entry pcmcia_3ccfem556bi_func1_cfe0 = {
    114      1.29  christos 	.number = 0x27,		/* cfe number */
    115      1.29  christos 	.flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL,
    116      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
    117      1.29  christos 	.num_iospace = 1,	/* num_iospace */
    118      1.29  christos 	.iomask = 3,		/* iomask */
    119      1.29  christos 	.iospace = { { .length = 0x0008, .start = 0 } },	/* iospace */
    120      1.29  christos 	.irqmask = 0xffff,	/* irqmask */
    121       1.5   thorpej };
    122       1.5   thorpej 
    123       1.8  jdolecek static const struct pcmcia_function pcmcia_sveclancard_func0 = {
    124      1.29  christos 	.number = 0,			/* function number */
    125      1.29  christos 	.function = PCMCIA_FUNCTION_NETWORK,
    126      1.29  christos 	.last_config_index = 0x1,	/* last cfe number */
    127      1.29  christos 	.ccr_base = 0x100,		/* ccr_base */
    128      1.29  christos 	.ccr_mask = 0x1,		/* ccr_mask */
    129       1.3      marc };
    130       1.3      marc 
    131       1.8  jdolecek static const struct pcmcia_config_entry pcmcia_sveclancard_func0_cfe0 = {
    132      1.29  christos 	.number = 0x1,		/* cfe number */
    133      1.29  christos 	.flags = PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_RDYBSY_ACTIVE |
    134      1.29  christos 	    PCMCIA_CFE_WP_ACTIVE | PCMCIA_CFE_BVD_ACTIVE | PCMCIA_CFE_IO16,
    135      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
    136      1.29  christos 	.num_iospace = 1,	/* num_iospace */
    137      1.29  christos 	.iomask = 5,		/* iomask */
    138      1.29  christos 	.iospace = { { .length = 0x20, .start = 0x300 } },	/* iospace */
    139      1.29  christos 	.irqmask = 0xdeb8,	/* irqmask */
    140       1.3      marc };
    141       1.3      marc 
    142       1.8  jdolecek static const struct pcmcia_function pcmcia_ndc_nd5100_func0 = {
    143      1.29  christos 	.number = 0,			/* function number */
    144      1.29  christos 	.function = PCMCIA_FUNCTION_NETWORK,
    145      1.29  christos 	.last_config_index = 0x23,	/* last cfe number */
    146      1.29  christos 	.ccr_base = 0x3f8,		/* ccr_base */
    147      1.29  christos 	.ccr_mask = 0x3,		/* ccr_mask */
    148       1.6       scw };
    149       1.6       scw 
    150       1.8  jdolecek static const struct pcmcia_config_entry pcmcia_ndc_nd5100_func0_cfe0 = {
    151      1.29  christos 	.number = 0x20,			/* cfe number */
    152      1.29  christos 	.flags = PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_IO16 |
    153      1.29  christos 	    PCMCIA_CFE_IRQLEVEL,
    154      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
    155      1.29  christos 	.num_iospace = 1,		/* num_iospace */
    156      1.29  christos 	.iomask = 5,			/* iomask */
    157      1.29  christos 	.iospace = { { .length = 0x20, .start = 0x300 } },	/* iospace */
    158      1.29  christos 	.irqmask = 0xdeb8,		/* irqmask */
    159       1.6       scw };
    160       1.6       scw 
    161      1.12    ichiro static const struct pcmcia_function pcmcia_emtac_a2424i_func0 = {
    162      1.29  christos 	.number = 0,			/* function number */
    163      1.29  christos 	.function = PCMCIA_FUNCTION_NETWORK,
    164      1.29  christos 	.last_config_index = 0x21,	/* last cfe number */
    165      1.29  christos 	.ccr_base = 0x3e0,		/* ccr_base */
    166      1.29  christos 	.ccr_mask = 0x1,		/* ccr_mask */
    167      1.12    ichiro };
    168      1.12    ichiro 
    169      1.12    ichiro static const struct pcmcia_config_entry pcmcia_emtac_a2424i_func0_cfe0 = {
    170      1.29  christos 	.number = 0x21,		/* cfe number */
    171      1.29  christos 	.flags = PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL | PCMCIA_CFE_IRQPULSE,
    172      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
    173      1.29  christos 	.num_iospace = 1,	/* num_iospace */
    174      1.29  christos 	.iomask = 6,		/* iomask */
    175      1.29  christos 	.iospace = { { .length = 0x40, .start = 0x100 } },	/* iospace */
    176      1.29  christos 	.irqmask = 0xffff,	/* irqmask */
    177      1.12    ichiro };
    178      1.12    ichiro 
    179      1.17    ichiro static const struct pcmcia_function pcmcia_fujitsu_j181_func0 = {
    180      1.29  christos 	.number = 0,			/* function number */
    181      1.29  christos 	.function = PCMCIA_FUNCTION_NETWORK,
    182      1.29  christos 	.last_config_index = 0x21,	/* last cfe number */
    183      1.29  christos 	.ccr_base = 0xfe0,		/* ccr_base */
    184      1.29  christos 	.ccr_mask = 0xf,		/* ccr_mask */
    185      1.17    ichiro };
    186      1.15    ichiro 
    187      1.17    ichiro static const struct pcmcia_config_entry pcmcia_fujitsu_j181_func0_cfe0 = {
    188      1.29  christos 	.number = 0xc,			/* cfe number */
    189      1.29  christos 	.flags = PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_WP_ACTIVE |
    190      1.29  christos 	    PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL |
    191      1.29  christos 	    PCMCIA_CFE_IRQPULSE,
    192      1.29  christos 	.iftype = PCMCIA_IFTYPE_IO,
    193      1.29  christos 	.num_iospace = 1,		/* num_iospace */
    194      1.29  christos 	.iomask = 10,			/* iomask */
    195      1.29  christos 	.iospace = { { .length = 0x20, .start = 0x140 } },	/* iospace */
    196      1.29  christos 	.irqmask = 0xffff,		/* irqmask */
    197      1.15    ichiro };
    198      1.15    ichiro 
    199      1.30    ichiro static const struct pcmcia_function pcmcia_necinfrontia_ax420n_func0 = {
    200      1.30    ichiro 	.number = 0,			/* function number */
    201      1.30    ichiro 	.function = PCMCIA_FUNCTION_SERIAL,
    202      1.30    ichiro 	.last_config_index = 0x38,	/* last cfe number */
    203      1.30    ichiro 	.ccr_base = 0x200,		/* ccr_base */
    204      1.30    ichiro 	.ccr_mask = 0x1f,		/* ccr_mask */
    205      1.30    ichiro };
    206      1.30    ichiro 
    207      1.30    ichiro static const struct pcmcia_config_entry pcmcia_necinfrontia_ax420n_func0_cfe0 = {
    208      1.30    ichiro 	.number = 0x25,			/* cfe number */
    209      1.30    ichiro 	.flags = PCMCIA_CFE_RDYBSY_ACTIVE | PCMCIA_CFE_IO8 |
    210      1.30    ichiro 		 PCMCIA_CFE_IRQLEVEL | PCMCIA_CFE_POWERDOWN |
    211      1.30    ichiro 		 PCMCIA_CFE_AUDIO,
    212      1.30    ichiro 	.iftype = PCMCIA_IFTYPE_IO,
    213      1.30    ichiro 	.num_iospace = 1,		/* num_iospace */
    214      1.30    ichiro 	.iomask = 10,			/* iomask */
    215      1.30    ichiro 	.iospace = { { .length = 0x8, .start = 0x3f8 } },	/* iospace */
    216      1.30    ichiro 	.irqmask = 0x86bc,		/* irqmask */
    217      1.30    ichiro };
    218      1.30    ichiro 
    219  1.31.4.1      yamt static const struct pcmcia_function pcmcia_sierra_ac850_func0 = {
    220  1.31.4.1      yamt 	.number = 0,			/* function number */
    221  1.31.4.1      yamt 	.function = PCMCIA_FUNCTION_SERIAL,
    222  1.31.4.1      yamt 	.last_config_index = 0x24,	/* last cfe number */
    223  1.31.4.1      yamt 	.ccr_base = 0x700,		/* ccr_base */
    224  1.31.4.1      yamt 	.ccr_mask = 0x73,		/* ccr_mask */
    225  1.31.4.1      yamt };
    226  1.31.4.1      yamt 
    227  1.31.4.1      yamt static const struct pcmcia_config_entry pcmcia_sierra_ac850_cfe0 = {
    228  1.31.4.1      yamt 	.number = 0x22,			/* cfe number */
    229  1.31.4.1      yamt 	.flags = PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL,
    230  1.31.4.1      yamt 	.iftype = PCMCIA_IFTYPE_IO,
    231  1.31.4.1      yamt 	.num_iospace = 1,		/* num_iospace */
    232  1.31.4.1      yamt 	.iomask = 0,			/* iomask */
    233  1.31.4.1      yamt 	.iospace = { { .length = 0x0008, .start = 0x3e8 } },	/* iospace */
    234  1.31.4.1      yamt 	.irqmask = 0x3fbc,		/* irqmask */
    235  1.31.4.1      yamt };
    236  1.31.4.1      yamt 
    237       1.8  jdolecek static const struct pcmcia_cis_quirk pcmcia_cis_quirks[] = {
    238      1.30    ichiro 	{ PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556,
    239      1.30    ichiro 	  PCMCIA_CIS_INVALID,
    240       1.1      marc 	  &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 },
    241      1.30    ichiro 	{ PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556,
    242      1.30    ichiro 	  PCMCIA_CIS_INVALID,
    243       1.4      tron 	  &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 },
    244      1.30    ichiro 	{ PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT,
    245      1.30    ichiro 	  PCMCIA_CIS_INVALID,
    246       1.4      tron 	  &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 },
    247      1.30    ichiro 	{ PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT,
    248      1.30    ichiro 	  PCMCIA_CIS_INVALID,
    249       1.1      marc 	  &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 },
    250       1.5   thorpej 	{ PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
    251       1.5   thorpej 	  PCMCIA_CIS_INVALID,
    252       1.5   thorpej 	  &pcmcia_3ccfem556bi_func0, &pcmcia_3ccfem556bi_func0_cfe0 },
    253       1.5   thorpej 	{ PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
    254       1.5   thorpej 	  PCMCIA_CIS_INVALID,
    255       1.5   thorpej 	  &pcmcia_3ccfem556bi_func1, &pcmcia_3ccfem556bi_func1_cfe0 },
    256      1.30    ichiro 	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
    257      1.30    ichiro 	  PCMCIA_CIS_SVEC_LANCARD,
    258       1.3      marc 	  &pcmcia_sveclancard_func0, &pcmcia_sveclancard_func0_cfe0 },
    259      1.30    ichiro 	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
    260      1.30    ichiro 	  PCMCIA_CIS_NDC_ND5100_E,
    261       1.6       scw 	  &pcmcia_ndc_nd5100_func0, &pcmcia_ndc_nd5100_func0_cfe0 },
    262      1.30    ichiro 	{ PCMCIA_VENDOR_EMTAC, PCMCIA_PRODUCT_EMTAC_WLAN,
    263      1.30    ichiro 	  PCMCIA_CIS_INVALID,
    264      1.12    ichiro 	  &pcmcia_emtac_a2424i_func0, &pcmcia_emtac_a2424i_func0_cfe0 },
    265      1.17    ichiro 	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
    266      1.17    ichiro 	  PCMCIA_CIS_FUJITSU_FMV_J181,
    267      1.17    ichiro 	  &pcmcia_fujitsu_j181_func0, &pcmcia_fujitsu_j181_func0_cfe0 },
    268      1.30    ichiro 	{ PCMCIA_VENDOR_NECINFRONTIA, PCMCIA_PRODUCT_NECINFRONTIA_AX420N,
    269      1.30    ichiro 	  PCMCIA_CIS_INVALID,
    270      1.30    ichiro 	  &pcmcia_necinfrontia_ax420n_func0,
    271      1.30    ichiro 	  &pcmcia_necinfrontia_ax420n_func0_cfe0 },
    272       1.1      marc };
    273      1.25     perry 
    274      1.21   mycroft static const int pcmcia_cis_nquirks =
    275      1.21   mycroft    sizeof(pcmcia_cis_quirks) / sizeof(pcmcia_cis_quirks[0]);
    276       1.1      marc 
    277      1.23     enami void
    278  1.31.4.1      yamt pcmcia_check_cis_quirks(struct pcmcia_softc *sc)
    279       1.1      marc {
    280       1.1      marc 	int wiped = 0;
    281      1.22  christos 	size_t i, j;
    282      1.19     lukem 	struct pcmcia_function *pf;
    283       1.8  jdolecek 	const struct pcmcia_function *pf_last;
    284      1.19     lukem 	struct pcmcia_config_entry *cfe;
    285      1.22  christos 	struct pcmcia_card *card = &sc->card;
    286      1.23     enami 	const struct pcmcia_cis_quirk *quirk;
    287       1.1      marc 
    288       1.2      marc 	pf = NULL;
    289       1.1      marc 	pf_last = NULL;
    290       1.1      marc 
    291      1.22  christos 	for (i = 0; i < pcmcia_cis_nquirks; i++) {
    292      1.23     enami 		quirk = &pcmcia_cis_quirks[i];
    293      1.22  christos 
    294      1.23     enami 		if (card->manufacturer == quirk->manufacturer &&
    295      1.23     enami 		    card->manufacturer != PCMCIA_VENDOR_INVALID &&
    296      1.23     enami 		    card->product == quirk->product &&
    297      1.22  christos 		    card->product != PCMCIA_PRODUCT_INVALID)
    298      1.23     enami 			goto match;
    299      1.22  christos 
    300      1.22  christos 		for (j = 0; j < 2; j++)
    301      1.24     enami 			if (card->cis1_info[j] == NULL ||
    302      1.24     enami 			    quirk->cis1_info[j] == NULL ||
    303      1.24     enami 			    strcmp(card->cis1_info[j],
    304      1.24     enami 			    quirk->cis1_info[j]) != 0)
    305      1.24     enami 				goto nomatch;
    306      1.22  christos 
    307      1.23     enami match:
    308      1.22  christos 		if (!wiped) {
    309      1.22  christos 			if (pcmcia_verbose) {
    310      1.22  christos 				printf("%s: using CIS quirks for ",
    311  1.31.4.1      yamt 				    device_xname(sc->dev));
    312      1.22  christos 				for (j = 0; j < 4; j++) {
    313      1.22  christos 					if (card->cis1_info[j] == NULL)
    314      1.22  christos 						break;
    315      1.22  christos 					if (j)
    316      1.22  christos 						printf(", ");
    317      1.22  christos 					printf("%s", card->cis1_info[j]);
    318       1.1      marc 				}
    319      1.22  christos 				printf("\n");
    320       1.1      marc 			}
    321      1.22  christos 			pcmcia_free_pf(&card->pf_head);
    322      1.22  christos 			wiped = 1;
    323      1.22  christos 		}
    324       1.1      marc 
    325      1.23     enami 		if (pf_last != quirk->pf) {
    326      1.23     enami 			/*
    327      1.23     enami 			 * XXX: a driver which still calls pcmcia_card_attach
    328      1.23     enami 			 * very early attach stage should be fixed instead.
    329      1.23     enami 			 */
    330      1.23     enami 			pf = malloc(sizeof(*pf), M_DEVBUF,
    331      1.23     enami 			    cold ? M_NOWAIT : M_WAITOK);
    332      1.23     enami 			if (pf == NULL)
    333      1.23     enami 				panic("pcmcia_check_cis_quirks: malloc pf");
    334      1.23     enami 			*pf = *quirk->pf;
    335      1.22  christos 			SIMPLEQ_INIT(&pf->cfe_head);
    336      1.23     enami 			SIMPLEQ_INSERT_TAIL(&card->pf_head, pf, pf_list);
    337      1.23     enami 			pf_last = quirk->pf;
    338      1.23     enami 		}
    339       1.1      marc 
    340      1.23     enami 		/*
    341      1.23     enami 		 * XXX: see above.
    342      1.23     enami 		 */
    343      1.23     enami 		cfe = malloc(sizeof(*cfe), M_DEVBUF,
    344      1.23     enami 		    cold ? M_NOWAIT : M_WAITOK);
    345      1.23     enami 		if (cfe == NULL)
    346      1.23     enami 			panic("pcmcia_check_cis_quirks: malloc cfe");
    347      1.23     enami 		*cfe = *quirk->cfe;
    348      1.27  christos 		KASSERT(pf != NULL);
    349      1.23     enami 		SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
    350       1.1      marc 
    351      1.23     enami nomatch:;
    352       1.1      marc 	}
    353       1.1      marc }
    354