diff --git a/sys/dev/pcmcia/files.pcmcia b/sys/dev/pcmcia/files.pcmcia index 8d199d455da1..bc027e0a3c86 100644 --- a/sys/dev/pcmcia/files.pcmcia +++ b/sys/dev/pcmcia/files.pcmcia @@ -1,4 +1,4 @@ -# $NetBSD: files.pcmcia,v 1.12 1998/11/26 15:32:44 pk Exp $ +# $NetBSD: files.pcmcia,v 1.13 1998/12/24 04:51:59 marc Exp $ # # Config.new file and device description for machine-independent PCMCIA code. # Included by ports that need it. @@ -8,11 +8,13 @@ defopt PCMCIAVERBOSE device pcmcia {[function = -1], [irq = -1]} file dev/pcmcia/pcmcia.c pcmcia file dev/pcmcia/pcmcia_cis.c pcmcia +file dev/pcmcia/pcmcia_cis_quirks.c pcmcia # device declaration in sys/conf/files attach pcmcia at pcmciabus -# 3Com 3c589 Ethernet and 3c562 multifunction Ethernet controllers +# 3Com 3c589 Ethernet, 3c562 multifunction Ethernet, and 3CXEM556 +# multifunction Ethernet controllers # device declaration in sys/conf/files attach ep at pcmcia with ep_pcmcia file dev/pcmcia/if_ep_pcmcia.c ep_pcmcia @@ -33,6 +35,7 @@ file dev/pcmcia/com_pcmcia.c com_pcmcia device wl: arp, ether, ifnet attach wl at pcmcia with wl_pcmcia file dev/pcmcia/if_wl_pcmcia.c wl_pcmcia +defopt opt_wl_pcmcia.h WL_TIMER WLP_CC_DEBUG WL_DEBUG MMC_STATUS WL_IFCNTRS WL_TIMING # PCMCIA IDE controller attach wdc at pcmcia with wdc_pcmcia diff --git a/sys/dev/pcmcia/pcmcia.c b/sys/dev/pcmcia/pcmcia.c index 37aea28939b3..252a79d1e4da 100644 --- a/sys/dev/pcmcia/pcmcia.c +++ b/sys/dev/pcmcia/pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: pcmcia.c,v 1.12 1998/12/24 04:50:43 marc Exp $ */ +/* $NetBSD: pcmcia.c,v 1.13 1998/12/24 04:51:59 marc Exp $ */ #define PCMCIADEBUG @@ -153,6 +153,8 @@ pcmcia_card_attach(dev) pcmcia_chip_socket_disable(sc->pct, sc->pch); + pcmcia_check_cis_quirks(sc); + /* * bail now if the card has no functions, or if there was an error in * the cis. diff --git a/sys/dev/pcmcia/pcmcia_cis_quirks.c b/sys/dev/pcmcia/pcmcia_cis_quirks.c new file mode 100644 index 000000000000..222bd5a78981 --- /dev/null +++ b/sys/dev/pcmcia/pcmcia_cis_quirks.c @@ -0,0 +1,166 @@ +/* $NetBSD: pcmcia_cis_quirks.c,v 1.1 1998/12/24 04:51:59 marc Exp $ */ + +#define PCMCIADEBUG + +/* + * Copyright (c) 1998 Marc Horowitz. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Marc Horowitz. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* There are cards out there whose CIS flat-out lies. This file + contains struct pcmcia_function chains for those devices. */ + +/* these structures are just static templates which are then copied + into "live" allocated structures */ + +struct pcmcia_function pcmcia_3cxem556_func0 = { + 0, /* function number */ + PCMCIA_FUNCTION_NETWORK, + 0x07, /* last cfe number */ + 0x800, /* ccr_base */ + 0x63, /* ccr_mask */ +}; + +struct pcmcia_config_entry pcmcia_3cxem556_func0_cfe0 = { + 0x07, /* cfe number */ + PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL, + PCMCIA_IFTYPE_IO, + 1, /* num_iospace */ + 4, /* iomask */ + { { 0x0010, 0 } }, /* iospace */ + 0xffff, /* irqmask */ + 0, /* num_memspace */ + { }, /* memspace */ + 0, /* maxtwins */ +}; + +static struct pcmcia_function pcmcia_3cxem556_func1 = { + 1, /* function number */ + PCMCIA_FUNCTION_SERIAL, + 0x27, /* last cfe number */ + 0x900, /* ccr_base */ + 0x63, /* ccr_mask */ +}; + +static struct pcmcia_config_entry pcmcia_3cxem556_func1_cfe0 = { + 0x27, /* cfe number */ + PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL, + PCMCIA_IFTYPE_IO, + 1, /* num_iospace */ + 3, /* iomask */ + { { 0x0008, 0 } }, /* iospace */ + 0xffff, /* irqmask */ + 0, /* num_memspace */ + { }, /* memspace */ + 0, /* maxtwins */ +}; + +static struct pcmcia_cis_quirk pcmcia_cis_quirks[] = { + { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556, + &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 }, + { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556, + &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 }, +}; + +static int n_pcmcia_cis_quirks = + sizeof(pcmcia_cis_quirks)/sizeof(pcmcia_cis_quirks[0]); + +void pcmcia_check_cis_quirks(sc) + struct pcmcia_softc *sc; +{ + int wiped = 0; + int i, j; + struct pcmcia_function *pf, *pf_next, *pf_last; + struct pcmcia_config_entry *cfe, *cfe_next; + + pf_last = NULL; + + for (i=0; icard.manufacturer == + pcmcia_cis_quirks[i].manufacturer) && + (sc->card.product == + pcmcia_cis_quirks[i].product)) { + if (!wiped) { + if (pcmcia_verbose) { + printf("%s: using CIS quirks for ", sc->dev.dv_xname); + for (j = 0; j < 4; j++) { + if (sc->card.cis1_info[j] == NULL) + break; + if (j) + printf(", "); + printf("%s", sc->card.cis1_info[j]); + } + printf("\n"); + } + + for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL; + pf = pf_next) { + for (cfe = SIMPLEQ_FIRST(&pf->cfe_head); cfe != NULL; + cfe = cfe_next) { + cfe_next = SIMPLEQ_NEXT(cfe, cfe_list); + free(cfe, M_DEVBUF); + } + pf_next = SIMPLEQ_NEXT(pf, pf_list); + free(pf, M_DEVBUF); + } + + SIMPLEQ_INIT(&sc->card.pf_head); + wiped = 1; + } + + if (pf_last == pcmcia_cis_quirks[i].pf) { + cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT); + *cfe = *pcmcia_cis_quirks[i].cfe; + + SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list); + } else { + pf = malloc(sizeof(*pf), M_DEVBUF, M_NOWAIT); + *pf = *pcmcia_cis_quirks[i].pf; + SIMPLEQ_INIT(&pf->cfe_head); + + cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT); + *cfe = *pcmcia_cis_quirks[i].cfe; + + SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list); + SIMPLEQ_INSERT_TAIL(&sc->card.pf_head, pf, pf_list); + + pf_last = pcmcia_cis_quirks[i].pf; + } + } + } +} diff --git a/sys/dev/pcmcia/pcmciavar.h b/sys/dev/pcmcia/pcmciavar.h index dfe49b4842b8..e7ec5690e447 100644 --- a/sys/dev/pcmcia/pcmciavar.h +++ b/sys/dev/pcmcia/pcmciavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: pcmciavar.h,v 1.7 1998/11/17 08:49:13 thorpej Exp $ */ +/* $NetBSD: pcmciavar.h,v 1.8 1998/12/24 04:51:59 marc Exp $ */ /* * Copyright (c) 1997 Marc Horowitz. All rights reserved. @@ -36,6 +36,8 @@ #include +extern int pcmcia_verbose; + /* * Contains information about mapped/allocated i/o spaces. */ @@ -176,6 +178,13 @@ struct pcmcia_softc { bus_size_t iosize; /* size of the i/o space range */ }; +struct pcmcia_cis_quirk { + int32_t manufacturer; + int32_t product; + struct pcmcia_function *pf; + struct pcmcia_config_entry *cfe; +}; + struct pcmcia_attach_args { int32_t manufacturer; int32_t product; @@ -193,6 +202,7 @@ struct pcmcia_tuple { }; void pcmcia_read_cis __P((struct pcmcia_softc *)); +void pcmcia_check_cis_quirks __P((struct pcmcia_softc *)); void pcmcia_print_cis __P((struct pcmcia_softc *)); int pcmcia_scan_cis __P((struct device * dev, int (*) (struct pcmcia_tuple *, void *), void *));