summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>1999-10-26 06:52:31 +0000
committerimp <imp@FreeBSD.org>1999-10-26 06:52:31 +0000
commitc2e7296cf63567584fc5a4b7333448982213c4ac (patch)
tree535bb7fbe2f73f39b40647a29fbf0c12ced759b0 /sys
parentf4e14e481e52797ad7a9e862edfcab473b2644ce (diff)
downloadFreeBSD-src-c2e7296cf63567584fc5a4b7333448982213c4ac.zip
FreeBSD-src-c2e7296cf63567584fc5a4b7333448982213c4ac.tar.gz
Moderately hacked pccard code from newconfig. It is somewhat in
incomplete and likely has problem. The code was originally pcmcia, but I renamed it to pccard and made it compile on FreeBSD -current. I converted SIMPLEQ to STAILQ as well as a few sc->dev.xname -> device_printf changes. This is a green port of fairly mature code. I derived this work from the FreeBSD newconfig project (http://www.jp.freebsd.org/newconfig). Any problems with it are likely introduced by me. Obtained from: newconfig project
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pccard/Makefile.pccarddevs8
-rw-r--r--sys/dev/pccard/devlist2h.awk226
-rw-r--r--sys/dev/pccard/files.pccard71
-rw-r--r--sys/dev/pccard/pccard.c888
-rw-r--r--sys/dev/pccard/pccard_cis.c1229
-rw-r--r--sys/dev/pccard/pccard_cis_quirks.c208
-rw-r--r--sys/dev/pccard/pccardchip.h140
-rw-r--r--sys/dev/pccard/pccarddevs181
-rw-r--r--sys/dev/pccard/pccarddevs.h300
-rw-r--r--sys/dev/pccard/pccarddevs_data.h679
-rw-r--r--sys/dev/pccard/pccardreg.h249
-rw-r--r--sys/dev/pccard/pccardvar.h290
-rw-r--r--sys/tools/pccarddevs2h.awk226
13 files changed, 4695 insertions, 0 deletions
diff --git a/sys/dev/pccard/Makefile.pccarddevs b/sys/dev/pccard/Makefile.pccarddevs
new file mode 100644
index 0000000..bd25c7d
--- /dev/null
+++ b/sys/dev/pccard/Makefile.pccarddevs
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile.pcmciadevs,v 1.1 1998/07/19 17:28:15 christos Exp $
+# $FreeBSD$
+
+AWK= awk
+
+pccarddevs.h pccarddevs_data.h: pccarddevs devlist2h.awk
+ /bin/rm -f pccarddevs.h pccarddevs_data.h
+ ${AWK} -f devlist2h.awk pccarddevs
diff --git a/sys/dev/pccard/devlist2h.awk b/sys/dev/pccard/devlist2h.awk
new file mode 100644
index 0000000..f586397
--- /dev/null
+++ b/sys/dev/pccard/devlist2h.awk
@@ -0,0 +1,226 @@
+#! /usr/bin/awk -f
+# $NetBSD: devlist2h.awk,v 1.3 1998/09/05 14:42:06 christos Exp $
+# $FreeBSD$
+#
+# Copyright (c) 1998 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Christos Zoulas.
+#
+# 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 the NetBSD
+# Foundation, Inc. and its contributors.
+# 4. Neither the name of The NetBSD Foundation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+# Copyright (c) 1995, 1996 Christopher G. Demetriou
+# 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 Christopher G. Demetriou.
+# This product includes software developed by Christos Zoulas
+# 4. The name of the author(s) 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.
+#
+function collectline(f, line) {
+ oparen = 0
+ line = ""
+ while (f <= NF) {
+ if ($f == "#") {
+ line = line "("
+ oparen = 1
+ f++
+ continue
+ }
+ if (oparen) {
+ line = line $f
+ if (f < NF)
+ line = line " "
+ f++
+ continue
+ }
+ line = line $f
+ if (f < NF)
+ line = line " "
+ f++
+ }
+ if (oparen)
+ line = line ")"
+ return line
+}
+BEGIN {
+ nproducts = nvendors = 0
+ dfile="pccarddevs_data.h"
+ hfile="pccarddevs.h"
+}
+NR == 1 {
+ VERSION = $0
+ gsub("\\$", "", VERSION)
+
+ printf("/*\t\$FreeBSD\$\t*/\n\n") > dfile
+ printf("/*\n") > dfile
+ printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
+ > dfile
+ printf(" *\n") > dfile
+ printf(" * generated from:\n") > dfile
+ printf(" *\t%s\n", VERSION) > dfile
+ printf(" */\n") > dfile
+
+ printf("/*\t\$FreeBSD\$\t*/\n\n") > hfile
+ printf("/*\n") > hfile
+ printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
+ > hfile
+ printf(" *\n") > hfile
+ printf(" * generated from:\n") > hfile
+ printf(" *\t%s\n", VERSION) > hfile
+ printf(" */\n") > hfile
+
+ next
+}
+$1 == "vendor" {
+ nvendors++
+
+ vendorindex[$2] = nvendors; # record index for this name, for later.
+ vendors[nvendors, 1] = $2; # name
+ vendors[nvendors, 2] = $3; # id
+ printf("#define\tPCCARD_VENDOR_%s\t%s\t", vendors[nvendors, 1],
+ vendors[nvendors, 2]) > hfile
+ vendors[nvendors, 3] = collectline(4, line)
+ printf("/* %s */\n", vendors[nvendors, 3]) > hfile
+ next
+}
+$1 == "product" {
+ nproducts++
+
+ products[nproducts, 1] = $2; # vendor name
+ products[nproducts, 2] = $3; # product id
+ products[nproducts, 3] = $4; # id
+
+ f = 5;
+
+ if ($4 == "{") {
+ products[nproducts, 3] = -1
+ z = "{ "
+ for (i = 0; i < 4; i++) {
+ if (f <= NF) {
+ gsub("&sp", " ", $f)
+ gsub("&tab", "\t", $f)
+ gsub("&nl", "\n", $f)
+ z = z $f " "
+ f++
+ }
+ else {
+ if (i == 3)
+ z = z "NULL "
+ else
+ z = z "NULL, "
+ }
+ }
+ products[nproducts, 4] = z $f
+ f++
+ }
+ else {
+ products[nproducts, 4] = "{ NULL, NULL, NULL, NULL }"
+ }
+ printf("#define\tPCCARD_CIS_%s_%s\t%s\n",
+ products[nproducts, 1], products[nproducts, 2],
+ products[nproducts, 4]) > hfile
+ printf("#define\tPCCARD_PRODUCT_%s_%s\t%s\n", products[nproducts, 1],
+ products[nproducts, 2], products[nproducts, 3]) > hfile
+
+ products[nproducts, 5] = collectline(f, line)
+
+ printf("#define\tPCCARD_STR_%s_%s\t\"%s\"\n",
+ products[nproducts, 1], products[nproducts, 2],
+ products[nproducts, 5]) > hfile
+
+ next
+}
+{
+ if ($0 == "")
+ blanklines++
+ print $0 > hfile
+ if (blanklines < 2)
+ print $0 > dfile
+}
+END {
+ # print out the match tables
+
+ printf("\n") > dfile
+
+ printf("struct pccard_knowndev pccard_knowndevs[] = {\n") > dfile
+ for (i = 1; i <= nproducts; i++) {
+ printf("\t{\n") > dfile
+ if (products[i, 3] == -1) {
+ printf("\t PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_%s_%s,\n",
+ products[i, 1], products[i, 2]) > dfile
+ } else {
+ printf("\t PCCARD_VENDOR_%s, PCCARD_PRODUCT_%s_%s,\n",
+ products[i, 1], products[i, 1], products[i, 2]) > dfile
+ }
+ printf("\t PCCARD_CIS_%s_%s,\n",
+ products[i, 1], products[i, 2]) > dfile
+ printf("\t ") > dfile
+ printf("0") > dfile
+ printf(",\n") > dfile
+
+ vendi = vendorindex[products[i, 1]];
+ printf("\t \"%s\",\n", vendors[vendi, 3]) > dfile
+ printf("\t \"%s\"\t},\n", products[i, 5]) > dfile
+ printf("\t},\n") > dfile
+ }
+ for (i = 1; i <= nvendors; i++) {
+ printf("\t{\n") > dfile
+ printf("\t PCCARD_VENDOR_%s, 0,\n", vendors[i, 1]) > dfile
+ printf("\t PCCARD_KNOWNDEV_NOPROD,\n") > dfile
+ printf("\t PCCARD_CIS_INVALID,\n") > dfile
+ printf("\t \"%s\",\n", vendors[i, 3]) > dfile
+ printf("\t NULL,\n") > dfile
+ printf("\t},\n") > dfile
+ }
+ printf("\t{ 0, 0, { NULL, NULL, NULL, NULL }, 0, NULL, NULL, }\n") > dfile
+ printf("};\n") > dfile
+}
diff --git a/sys/dev/pccard/files.pccard b/sys/dev/pccard/files.pccard
new file mode 100644
index 0000000..09bf525
--- /dev/null
+++ b/sys/dev/pccard/files.pccard
@@ -0,0 +1,71 @@
+# $NetBSD: files.pcmcia,v 1.14 1999/01/01 19:30:03 christos Exp $
+# $FreeBSD$
+#
+# Config.new file and device description for machine-independent PCMCIA code.
+# Included by ports that need it.
+
+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, 3c562 multifunction Ethernet, and 3CXEM556
+# multifunction Ethernet controllers
+# device declaration in sys/conf/files
+attach ep at pcmcia with ep_pcmcia: elink
+file dev/pcmcia/if_ep_pcmcia.c ep_pcmcia
+
+# National Semiconductor DS8390/WD83C690-based boards
+# (NE[12]000, and clones)
+attach ne at pcmcia with ne_pcmcia: rtl80x9
+file dev/pcmcia/if_ne_pcmcia.c ne_pcmcia
+
+# Adaptec APA-1460 SCSI Host Adapter
+#attach aic at pcmcia with aic_pcmcia
+#file dev/pcmcia/aic_pcmcia.c aic_pcmcia
+
+#attach com at pcmcia with com_pcmcia
+#file dev/pcmcia/com_pcmcia.c com_pcmcia
+
+# Digital RoamAbout / Lucent WaveLAN PCMCIA card
+#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
+#file dev/pcmcia/wdc_pcmcia.c wdc_pcmcia
+
+# SMC91Cxx Ethernet Controllers (i.e. Megahertz X-Jack)
+attach sn at pcmcia with sm_pcmcia
+file dev/pcmcia/if_sm_pcmcia.c sm_pcmcia
+
+# MB8696x Ethernet Controllers (i.e. TDK LAK CD021BX)
+attach fe at pcmcia with mbe_pcmcia
+file dev/pcmcia/if_mbe_pcmcia.c mbe_pcmcia
+
+# PCMCIA Floppy controller
+#attach fdc at pcmcia with fdc_pcmcia
+#file dev/pcmcia/fdc_pcmcia.c fdc_pcmcia
+
+# PCMCIA multi-port serial cards
+#device pcmcom {[slave = -1]}
+#attach pcmcom at pcmcia
+#attach com at pcmcom with com_pcmcom
+#file dev/pcmcia/pcmcom.c pcmcom | com_pcmcom needs-flag
+
+# Xircom Netwave
+#device cnw: arp, ether, ifnet
+#attach cnw at pcmcia
+#file dev/pcmcia/if_cnw.c cnw
+
+# Xircom CreditCard
+device xe: ether, ifnet
+attach xe at pcmcia with xe_pcmcia
+file dev/pcmcia/if_xe.c xe
diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c
new file mode 100644
index 0000000..b12227a
--- /dev/null
+++ b/sys/dev/pccard/pccard.c
@@ -0,0 +1,888 @@
+/* $NetBSD: pcmcia.c,v 1.13 1998/12/24 04:51:59 marc Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (c) 1997 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pccard/pccardreg.h>
+#include <dev/pccard/pccardchip.h>
+#include <dev/pccard/pccardvar.h>
+
+#ifdef PCCARDDEBUG
+int pccard_debug = 0;
+#define DPRINTF(arg) if (pccard_debug) printf arg
+int pccardintr_debug = 0;
+/* this is done this way to avoid doing lots of conditionals
+ at interrupt level. */
+#define PCCARD_CARD_INTR (pccardintr_debug?pccard_card_intrdebug:pccard_card_intr)
+#else
+#define DPRINTF(arg)
+#define PCCARD_CARD_INTR (pccard_card_intr)
+#endif
+
+#ifdef PCCARDVERBOSE
+int pccard_verbose = 1;
+#else
+int pccard_verbose = 0;
+#endif
+
+int pccard_print __P((void *, const char *));
+
+static __inline void pccard_socket_enable __P((pccard_chipset_tag_t,
+ pccard_chipset_handle_t *));
+static __inline void pccard_socket_disable __P((pccard_chipset_tag_t,
+ pccard_chipset_handle_t *));
+
+int pccard_card_intr __P((void *));
+#ifdef PCCARDDEBUG
+int pccard_card_intrdebug __P((void *));
+#endif
+
+int
+pccard_ccr_read(pf, ccr)
+ struct pccard_function *pf;
+ int ccr;
+{
+
+ return (bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
+ pf->pf_ccr_offset + ccr));
+}
+
+void
+pccard_ccr_write(pf, ccr, val)
+ struct pccard_function *pf;
+ int ccr;
+ int val;
+{
+
+ if ((pf->ccr_mask) & (1 << (ccr / 2))) {
+ bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh,
+ pf->pf_ccr_offset + ccr, val);
+ }
+}
+
+static int
+pccard_card_attach(device_t dev)
+{
+ struct pccard_softc *sc = (struct pccard_softc *)
+ device_get_softc(dev);
+ struct pccard_function *pf;
+ struct pccard_attach_args paa;
+ int attached;
+
+ /*
+ * this is here so that when socket_enable calls gettype, trt happens
+ */
+ STAILQ_INIT(&sc->card.pf_head);
+
+ pccard_chip_socket_enable(sc->pct, sc->pch);
+
+ pccard_read_cis(sc);
+
+ pccard_chip_socket_disable(sc->pct, sc->pch);
+
+ pccard_check_cis_quirks(dev);
+
+ /*
+ * bail now if the card has no functions, or if there was an error in
+ * the cis.
+ */
+
+ if (sc->card.error)
+ return (1);
+ if (STAILQ_EMPTY(&sc->card.pf_head))
+ return (1);
+
+ if (pccard_verbose)
+ pccard_print_cis(dev);
+
+ attached = 0;
+
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (STAILQ_EMPTY(&pf->cfe_head))
+ continue;
+
+#ifdef DIAGNOSTIC
+ if (pf->child != NULL) {
+ printf("%s: %s still attached to function %d!\n",
+ sc->dev.dv_xname, pf->child->dv_xname,
+ pf->number);
+ panic("pccard_card_attach");
+ }
+#endif
+ pf->sc = sc;
+ pf->child = NULL;
+ pf->cfe = NULL;
+ pf->ih_fct = NULL;
+ pf->ih_arg = NULL;
+ }
+
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (STAILQ_EMPTY(&pf->cfe_head))
+ continue;
+
+ paa.manufacturer = sc->card.manufacturer;
+ paa.product = sc->card.product;
+ paa.card = &sc->card;
+ paa.pf = pf;
+
+#if XXX
+ if (attach_child()) {
+ attached++;
+
+ DPRINTF(("%s: function %d CCR at %d "
+ "offset %lx: %x %x %x %x, %x %x %x %x, %x\n",
+ sc->dev.dv_xname, pf->number,
+ pf->pf_ccr_window, pf->pf_ccr_offset,
+ pccard_ccr_read(pf, 0x00),
+ pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04),
+ pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A),
+ pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E),
+ pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12)));
+ }
+#endif
+ }
+
+ return (attached ? 0 : 1);
+}
+
+static void
+pccard_card_detach(device_t dev, int flags)
+{
+ struct pccard_softc *sc = (struct pccard_softc *)
+ device_get_softc(dev);
+ struct pccard_function *pf;
+#if XXX
+ int error;
+#endif
+
+ /*
+ * We are running on either the PCCARD socket's event thread
+ * or in user context detaching a device by user request.
+ */
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (STAILQ_FIRST(&pf->cfe_head) == NULL)
+ continue;
+ if (pf->child == NULL)
+ continue;
+ DPRINTF(("%s: detaching %s (function %d)\n",
+ sc->dev.dv_xname, pf->child->dv_xname, pf->number));
+#if XXX
+ if ((error = config_detach(pf->child, flags)) != 0) {
+ printf("%s: error %d detaching %s (function %d)\n",
+ sc->dev.dv_xname, error, pf->child->dv_xname,
+ pf->number);
+ } else
+ pf->child = NULL;
+#endif
+ }
+}
+
+static void
+pccard_card_deactivate(device_t dev)
+{
+ struct pccard_softc *sc = (struct pccard_softc *)
+ device_get_softc(dev);
+ struct pccard_function *pf;
+
+ /*
+ * We're in the chip's card removal interrupt handler.
+ * Deactivate the child driver. The PCCARD socket's
+ * event thread will run later to finish the detach.
+ */
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (STAILQ_FIRST(&pf->cfe_head) == NULL)
+ continue;
+ if (pf->child == NULL)
+ continue;
+ DPRINTF(("%s: deactivating %s (function %d)\n",
+ sc->dev.dv_xname, pf->child->dv_xname, pf->number));
+#if XXX
+ config_deactivate(pf->child);
+#endif
+ }
+}
+
+static int
+pccard_card_gettype(device_t dev)
+{
+ struct pccard_softc *sc = (struct pccard_softc *)
+ device_get_softc(dev);
+ struct pccard_function *pf;
+
+ /*
+ * set the iftype to memory if this card has no functions (not yet
+ * probed), or only one function, and that is not initialized yet or
+ * that is memory.
+ */
+ pf = STAILQ_FIRST(&sc->card.pf_head);
+ if (pf == NULL ||
+ (STAILQ_NEXT(pf, pf_list) == NULL &&
+ (pf->cfe == NULL || pf->cfe->iftype == PCCARD_IFTYPE_MEMORY)))
+ return (PCCARD_IFTYPE_MEMORY);
+ else
+ return (PCCARD_IFTYPE_IO);
+}
+
+/*
+ * Initialize a PCCARD function. May be called as long as the function is
+ * disabled.
+ */
+void
+pccard_function_init(pf, cfe)
+ struct pccard_function *pf;
+ struct pccard_config_entry *cfe;
+{
+ if (pf->pf_flags & PFF_ENABLED)
+ panic("pccard_function_init: function is enabled");
+
+ /* Remember which configuration entry we are using. */
+ pf->cfe = cfe;
+}
+
+static __inline void pccard_socket_enable(pct, pch)
+ pccard_chipset_tag_t pct;
+ pccard_chipset_handle_t *pch;
+{
+ pccard_chip_socket_enable(pct, pch);
+}
+
+static __inline void pccard_socket_disable(pct, pch)
+ pccard_chipset_tag_t pct;
+ pccard_chipset_handle_t *pch;
+{
+ pccard_chip_socket_disable(pct, pch);
+}
+
+/* Enable a PCCARD function */
+int
+pccard_function_enable(pf)
+ struct pccard_function *pf;
+{
+ struct pccard_function *tmp;
+ int reg;
+
+ if (pf->cfe == NULL)
+ panic("pccard_function_enable: function not initialized");
+
+ /*
+ * Increase the reference count on the socket, enabling power, if
+ * necessary.
+ */
+ if (pf->sc->sc_enabled_count++ == 0)
+ pccard_chip_socket_enable(pf->sc->pct, pf->sc->pch);
+ DPRINTF(("%s: ++enabled_count = %d\n", pf->sc->dev.dv_xname,
+ pf->sc->sc_enabled_count));
+
+ if (pf->pf_flags & PFF_ENABLED) {
+ /*
+ * Don't do anything if we're already enabled.
+ */
+ return (0);
+ }
+
+ /*
+ * it's possible for different functions' CCRs to be in the same
+ * underlying page. Check for that.
+ */
+
+ STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) {
+ if ((tmp->pf_flags & PFF_ENABLED) &&
+ (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) &&
+ ((pf->ccr_base + PCCARD_CCR_SIZE) <=
+ (tmp->ccr_base - tmp->pf_ccr_offset +
+ tmp->pf_ccr_realsize))) {
+ pf->pf_ccrt = tmp->pf_ccrt;
+ pf->pf_ccrh = tmp->pf_ccrh;
+ pf->pf_ccr_realsize = tmp->pf_ccr_realsize;
+
+ /*
+ * pf->pf_ccr_offset = (tmp->pf_ccr_offset -
+ * tmp->ccr_base) + pf->ccr_base;
+ */
+ pf->pf_ccr_offset =
+ (tmp->pf_ccr_offset + pf->ccr_base) -
+ tmp->ccr_base;
+ pf->pf_ccr_window = tmp->pf_ccr_window;
+ break;
+ }
+ }
+
+ if (tmp == NULL) {
+ if (pccard_mem_alloc(pf, PCCARD_CCR_SIZE, &pf->pf_pcmh))
+ goto bad;
+
+ if (pccard_mem_map(pf, PCCARD_MEM_ATTR, pf->ccr_base,
+ PCCARD_CCR_SIZE, &pf->pf_pcmh, &pf->pf_ccr_offset,
+ &pf->pf_ccr_window)) {
+ pccard_mem_free(pf, &pf->pf_pcmh);
+ goto bad;
+ }
+ }
+
+ reg = (pf->cfe->number & PCCARD_CCR_OPTION_CFINDEX);
+ reg |= PCCARD_CCR_OPTION_LEVIREQ;
+ if (pccard_mfc(pf->sc)) {
+ reg |= (PCCARD_CCR_OPTION_FUNC_ENABLE |
+ PCCARD_CCR_OPTION_ADDR_DECODE);
+ if (pf->ih_fct)
+ reg |= PCCARD_CCR_OPTION_IREQ_ENABLE;
+
+ }
+ pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
+
+ reg = 0;
+
+ if ((pf->cfe->flags & PCCARD_CFE_IO16) == 0)
+ reg |= PCCARD_CCR_STATUS_IOIS8;
+ if (pf->cfe->flags & PCCARD_CFE_AUDIO)
+ reg |= PCCARD_CCR_STATUS_AUDIO;
+ pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg);
+
+ pccard_ccr_write(pf, PCCARD_CCR_SOCKETCOPY, 0);
+
+ if (pccard_mfc(pf->sc)) {
+ long tmp, iosize;
+
+ tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase;
+ /* round up to nearest (2^n)-1 */
+ for (iosize = 1; iosize < tmp; iosize <<= 1)
+ ;
+ iosize--;
+
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE0,
+ pf->pf_mfc_iobase & 0xff);
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE1,
+ (pf->pf_mfc_iobase >> 8) & 0xff);
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0);
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0);
+
+ pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize);
+ }
+
+#ifdef PCCARDDEBUG
+ if (pccard_debug) {
+ STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) {
+ printf("%s: function %d CCR at %d offset %lx: "
+ "%x %x %x %x, %x %x %x %x, %x\n",
+ tmp->sc->dev.dv_xname, tmp->number,
+ tmp->pf_ccr_window, tmp->pf_ccr_offset,
+ pccard_ccr_read(tmp, 0x00),
+ pccard_ccr_read(tmp, 0x02),
+ pccard_ccr_read(tmp, 0x04),
+ pccard_ccr_read(tmp, 0x06),
+
+ pccard_ccr_read(tmp, 0x0A),
+ pccard_ccr_read(tmp, 0x0C),
+ pccard_ccr_read(tmp, 0x0E),
+ pccard_ccr_read(tmp, 0x10),
+
+ pccard_ccr_read(tmp, 0x12));
+ }
+ }
+#endif
+
+ pf->pf_flags |= PFF_ENABLED;
+ return (0);
+
+ bad:
+ /*
+ * Decrement the reference count, and power down the socket, if
+ * necessary.
+ */
+ if (--pf->sc->sc_enabled_count == 0)
+ pccard_chip_socket_disable(pf->sc->pct, pf->sc->pch);
+ DPRINTF(("%s: --enabled_count = %d\n", pf->sc->dev.dv_xname,
+ pf->sc->sc_enabled_count));
+
+ return (1);
+}
+
+/* Disable PCCARD function. */
+void
+pccard_function_disable(pf)
+ struct pccard_function *pf;
+{
+ struct pccard_function *tmp;
+
+ if (pf->cfe == NULL)
+ panic("pccard_function_enable: function not initialized");
+
+ if ((pf->pf_flags & PFF_ENABLED) == 0) {
+ /*
+ * Don't do anything if we're already disabled.
+ */
+ return;
+ }
+
+ /*
+ * it's possible for different functions' CCRs to be in the same
+ * underlying page. Check for that. Note we mark us as disabled
+ * first to avoid matching ourself.
+ */
+
+ pf->pf_flags &= ~PFF_ENABLED;
+ STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) {
+ if ((tmp->pf_flags & PFF_ENABLED) &&
+ (pf->ccr_base >= (tmp->ccr_base - tmp->pf_ccr_offset)) &&
+ ((pf->ccr_base + PCCARD_CCR_SIZE) <=
+ (tmp->ccr_base - tmp->pf_ccr_offset + tmp->pf_ccr_realsize)))
+ break;
+ }
+
+ /* Not used by anyone else; unmap the CCR. */
+ if (tmp == NULL) {
+ pccard_mem_unmap(pf, pf->pf_ccr_window);
+ pccard_mem_free(pf, &pf->pf_pcmh);
+ }
+
+ /*
+ * Decrement the reference count, and power down the socket, if
+ * necessary.
+ */
+ if (--pf->sc->sc_enabled_count == 0)
+ pccard_chip_socket_disable(pf->sc->pct, pf->sc->pch);
+ DPRINTF(("%s: --enabled_count = %d\n", pf->sc->dev.dv_xname,
+ pf->sc->sc_enabled_count));
+}
+
+int
+pccard_io_map(pf, width, offset, size, pcihp, windowp)
+ struct pccard_function *pf;
+ int width;
+ bus_addr_t offset;
+ bus_size_t size;
+ struct pccard_io_handle *pcihp;
+ int *windowp;
+{
+ int reg;
+
+ if (pccard_chip_io_map(pf->sc->pct, pf->sc->pch,
+ width, offset, size, pcihp, windowp))
+ return (1);
+
+ /*
+ * XXX in the multifunction multi-iospace-per-function case, this
+ * needs to cooperate with io_alloc to make sure that the spaces
+ * don't overlap, and that the ccr's are set correctly
+ */
+
+ if (pccard_mfc(pf->sc)) {
+ long tmp, iosize;
+
+ if (pf->pf_mfc_iomax == 0) {
+ pf->pf_mfc_iobase = pcihp->addr + offset;
+ pf->pf_mfc_iomax = pf->pf_mfc_iobase + size;
+ } else {
+ /* this makes the assumption that nothing overlaps */
+ if (pf->pf_mfc_iobase > pcihp->addr + offset)
+ pf->pf_mfc_iobase = pcihp->addr + offset;
+ if (pf->pf_mfc_iomax < pcihp->addr + offset + size)
+ pf->pf_mfc_iomax = pcihp->addr + offset + size;
+ }
+
+ tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase;
+ /* round up to nearest (2^n)-1 */
+ for (iosize = 1; iosize >= tmp; iosize <<= 1)
+ ;
+ iosize--;
+
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE0,
+ pf->pf_mfc_iobase & 0xff);
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE1,
+ (pf->pf_mfc_iobase >> 8) & 0xff);
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0);
+ pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0);
+
+ pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize);
+
+ reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION);
+ reg |= PCCARD_CCR_OPTION_ADDR_DECODE;
+ pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
+ }
+ return (0);
+}
+
+void
+pccard_io_unmap(pf, window)
+ struct pccard_function *pf;
+ int window;
+{
+
+ pccard_chip_io_unmap(pf->sc->pct, pf->sc->pch, window);
+
+ /* XXX Anything for multi-function cards? */
+}
+
+void *
+pccard_intr_establish(pf, ipl, ih_fct, ih_arg)
+ struct pccard_function *pf;
+ int ipl;
+ int (*ih_fct) __P((void *));
+ void *ih_arg;
+{
+ void *ret;
+
+ /* behave differently if this is a multifunction card */
+
+ if (pccard_mfc(pf->sc)) {
+ int s, ihcnt, hiipl, reg;
+ struct pccard_function *pf2;
+
+ /*
+ * mask all the ipl's which are already used by this card,
+ * and find the highest ipl number (lowest priority)
+ */
+
+ ihcnt = 0;
+ s = 0; /* this is only here to keep the compiler
+ happy */
+ hiipl = 0; /* this is only here to keep the compiler
+ happy */
+
+ STAILQ_FOREACH(pf2, &pf->sc->card.pf_head, pf_list) {
+ if (pf2->ih_fct) {
+ DPRINTF(("%s: function %d has ih_fct %p\n",
+ pf->sc->dev.dv_xname, pf2->number,
+ pf2->ih_fct));
+
+ if (ihcnt == 0) {
+ hiipl = pf2->ih_ipl;
+ } else {
+ if (pf2->ih_ipl > hiipl)
+ hiipl = pf2->ih_ipl;
+ }
+
+ ihcnt++;
+ }
+ }
+
+ /*
+ * establish the real interrupt, changing the ipl if
+ * necessary
+ */
+
+ if (ihcnt == 0) {
+#ifdef DIAGNOSTIC
+ if (pf->sc->ih != NULL)
+ panic("card has intr handler, but no function does");
+#endif
+ s = splhigh();
+
+ /* set up the handler for the new function */
+
+ pf->ih_fct = ih_fct;
+ pf->ih_arg = ih_arg;
+ pf->ih_ipl = ipl;
+
+ pf->sc->ih = pccard_chip_intr_establish(pf->sc->pct,
+ pf->sc->pch, pf, ipl, PCCARD_CARD_INTR, pf->sc);
+ splx(s);
+ } else if (ipl > hiipl) {
+#ifdef DIAGNOSTIC
+ if (pf->sc->ih == NULL)
+ panic("functions have ih, but the card does not");
+#endif
+
+ /* XXX need #ifdef for splserial on x86 */
+ s = splhigh();
+
+ pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
+ pf->sc->ih);
+
+ /* set up the handler for the new function */
+ pf->ih_fct = ih_fct;
+ pf->ih_arg = ih_arg;
+ pf->ih_ipl = ipl;
+
+ pf->sc->ih = pccard_chip_intr_establish(pf->sc->pct,
+ pf->sc->pch, pf, ipl, PCCARD_CARD_INTR, pf->sc);
+
+ splx(s);
+ } else {
+ s = splhigh();
+
+ /* set up the handler for the new function */
+
+ pf->ih_fct = ih_fct;
+ pf->ih_arg = ih_arg;
+ pf->ih_ipl = ipl;
+
+ splx(s);
+ }
+
+ ret = pf->sc->ih;
+
+ if (ret != NULL) {
+ reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION);
+ reg |= PCCARD_CCR_OPTION_IREQ_ENABLE;
+ pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
+
+ reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
+ reg |= PCCARD_CCR_STATUS_INTRACK;
+ pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg);
+ }
+ } else {
+ ret = pccard_chip_intr_establish(pf->sc->pct, pf->sc->pch,
+ pf, ipl, ih_fct, ih_arg);
+ }
+
+ return (ret);
+}
+
+void
+pccard_intr_disestablish(pf, ih)
+ struct pccard_function *pf;
+ void *ih;
+{
+ /* behave differently if this is a multifunction card */
+
+ if (pccard_mfc(pf->sc)) {
+ int s, ihcnt, hiipl;
+ struct pccard_function *pf2;
+
+ /*
+ * mask all the ipl's which are already used by this card,
+ * and find the highest ipl number (lowest priority). Skip
+ * the current function.
+ */
+
+ ihcnt = 0;
+ s = 0; /* this is only here to keep the compipler
+ happy */
+ hiipl = 0; /* this is only here to keep the compipler
+ happy */
+
+ STAILQ_FOREACH(pf2, &pf->sc->card.pf_head, pf_list) {
+ if (pf2 == pf)
+ continue;
+
+ if (pf2->ih_fct) {
+ if (ihcnt == 0) {
+ hiipl = pf2->ih_ipl;
+ } else {
+ if (pf2->ih_ipl > hiipl)
+ hiipl = pf2->ih_ipl;
+ }
+ ihcnt++;
+ }
+ }
+
+ /*
+ * if the ih being removed is lower priority than the lowest
+ * priority remaining interrupt, up the priority.
+ */
+
+ /* ihcnt is the number of interrupt handlers *not* including
+ the one about to be removed. */
+
+ if (ihcnt == 0) {
+ int reg;
+
+#ifdef DIAGNOSTIC
+ if (pf->sc->ih == NULL)
+ panic("disestablishing last function, but card has no ih");
+#endif
+ pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
+ pf->sc->ih);
+
+ reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION);
+ reg &= ~PCCARD_CCR_OPTION_IREQ_ENABLE;
+ pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
+
+ pf->ih_fct = NULL;
+ pf->ih_arg = NULL;
+
+ pf->sc->ih = NULL;
+ } else if (pf->ih_ipl > hiipl) {
+#ifdef DIAGNOSTIC
+ if (pf->sc->ih == NULL)
+ panic("changing ih ipl, but card has no ih");
+#endif
+ /* XXX need #ifdef for splserial on x86 */
+ s = splhigh();
+
+ pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
+ pf->sc->ih);
+ pf->sc->ih = pccard_chip_intr_establish(pf->sc->pct,
+ pf->sc->pch, pf, hiipl, PCCARD_CARD_INTR, pf->sc);
+
+ /* null out the handler for this function */
+
+ pf->ih_fct = NULL;
+ pf->ih_arg = NULL;
+
+ splx(s);
+ } else {
+ s = splhigh();
+
+ pf->ih_fct = NULL;
+ pf->ih_arg = NULL;
+
+ splx(s);
+ }
+ } else {
+ pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch, ih);
+ }
+}
+
+int
+pccard_card_intr(arg)
+ void *arg;
+{
+ struct pccard_softc *sc = arg;
+ struct pccard_function *pf;
+ int reg, ret, ret2;
+
+ ret = 0;
+
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (pf->ih_fct != NULL &&
+ (pf->ccr_mask & (1 << (PCCARD_CCR_STATUS / 2)))) {
+ reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
+ if (reg & PCCARD_CCR_STATUS_INTR) {
+ ret2 = (*pf->ih_fct)(pf->ih_arg);
+ if (ret2 != 0 && ret == 0)
+ ret = ret2;
+ reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
+ pccard_ccr_write(pf, PCCARD_CCR_STATUS,
+ reg & ~PCCARD_CCR_STATUS_INTR);
+ }
+ }
+ }
+
+ return (ret);
+}
+
+#ifdef PCCARDDEBUG
+int
+pccard_card_intrdebug(arg)
+ void *arg;
+{
+ struct pccard_softc *sc = arg;
+ struct pccard_function *pf;
+ int reg, ret, ret2;
+
+ ret = 0;
+
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ printf("%s: intr flags=%x fct=%d cor=%02x csr=%02x pin=%02x",
+ sc->dev.dv_xname, pf->pf_flags, pf->number,
+ pccard_ccr_read(pf, PCCARD_CCR_OPTION),
+ pccard_ccr_read(pf, PCCARD_CCR_STATUS),
+ pccard_ccr_read(pf, PCCARD_CCR_PIN));
+ if (pf->ih_fct != NULL &&
+ (pf->ccr_mask & (1 << (PCCARD_CCR_STATUS / 2)))) {
+ reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
+ if (reg & PCCARD_CCR_STATUS_INTR) {
+ ret2 = (*pf->ih_fct)(pf->ih_arg);
+ if (ret2 != 0 && ret == 0)
+ ret = ret2;
+ reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
+ printf("; csr %02x->%02x",
+ reg, reg & ~PCCARD_CCR_STATUS_INTR);
+ pccard_ccr_write(pf, PCCARD_CCR_STATUS,
+ reg & ~PCCARD_CCR_STATUS_INTR);
+ }
+ }
+ printf("\n");
+ }
+
+ return (ret);
+}
+#endif
+
+static int
+pccard_add_children(device_t dev, int busno)
+{
+ device_add_child(dev, NULL, -1, NULL);
+ return 0;
+}
+
+static int
+pccard_probe(device_t dev)
+{
+ device_set_desc(dev, "PC Card bus -- newconfig version");
+ return pccard_add_children(dev, device_get_unit(dev));
+}
+
+static device_method_t pccard_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pccard_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* Bus interface */
+#if 0
+ DEVMETHOD(bus_print_child, pccard_print_child),
+#endif
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+#if 0
+ DEVMETHOD(bus_alloc_resource, pccard_alloc_resource),
+ DEVMETHOD(bus_release_resource, pccard_release_resource),
+#endif
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+#if 0
+ DEVMETHOD(bus_set_resource, pccard_set_resource),
+ DEVMETHOD(bus_get_resource, pccard_get_resource),
+ DEVMETHOD(bus_delete_resource, pccard_delete_resource),
+#endif
+
+ { 0, 0 }
+};
+
+static driver_t pccard_driver = {
+ "pccard",
+ pccard_methods,
+ 1, /* no softc */
+};
+
+devclass_t pccard_devclass;
+
+DRIVER_MODULE(pccard, pcicx, pccard_driver, pccard_devclass, 0, 0);
+DRIVER_MODULE(pccard, pc98pcic, pccard_driver, pccard_devclass, 0, 0);
+DRIVER_MODULE(pccard, pccbb, pccard_driver, pccard_devclass, 0, 0);
diff --git a/sys/dev/pccard/pccard_cis.c b/sys/dev/pccard/pccard_cis.c
new file mode 100644
index 0000000..682ed58
--- /dev/null
+++ b/sys/dev/pccard/pccard_cis.c
@@ -0,0 +1,1229 @@
+/* $NetBSD: pcmcia_cis.c,v 1.10 1998/12/29 09:03:15 marc Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (c) 1997 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pccard/pccardreg.h>
+#include <dev/pccard/pccardchip.h>
+#include <dev/pccard/pccardvar.h>
+
+#ifdef PCCARDCISDEBUG
+int pccardcis_debug = 0;
+#define DPRINTF(arg) if (pccardcis_debug) printf arg
+#else
+#define DPRINTF(arg)
+#endif
+
+#define PCCARD_CIS_SIZE 1024
+
+struct cis_state {
+ int count;
+ int gotmfc;
+ struct pccard_config_entry temp_cfe;
+ struct pccard_config_entry *default_cfe;
+ struct pccard_card *card;
+ struct pccard_function *pf;
+};
+
+int pccard_parse_cis_tuple __P((struct pccard_tuple *, void *));
+
+void
+pccard_read_cis(sc)
+ struct pccard_softc *sc;
+{
+ struct cis_state state;
+
+ state.count = 0;
+ state.gotmfc = 0;
+
+ state.card = &sc->card;
+
+ state.card->error = 0;
+ state.card->cis1_major = -1;
+ state.card->cis1_minor = -1;
+ state.card->cis1_info[0] = NULL;
+ state.card->cis1_info[1] = NULL;
+ state.card->cis1_info[2] = NULL;
+ state.card->cis1_info[3] = NULL;
+ state.card->manufacturer = PCCARD_VENDOR_INVALID;
+ state.card->product = PCCARD_PRODUCT_INVALID;
+ STAILQ_INIT(&state.card->pf_head);
+
+ state.pf = NULL;
+
+ if (pccard_scan_cis((struct device *)sc, pccard_parse_cis_tuple,
+ &state) == -1)
+ state.card->error++;
+}
+
+int
+pccard_scan_cis(dev, fct, arg)
+ struct device *dev;
+ int (*fct) __P((struct pccard_tuple *, void *));
+ void *arg;
+{
+ struct pccard_softc *sc = (struct pccard_softc *) dev;
+ pccard_chipset_tag_t pct;
+ pccard_chipset_handle_t pch;
+ int window;
+ struct pccard_mem_handle pcmh;
+ struct pccard_tuple tuple;
+ int longlink_present;
+ int longlink_common;
+ u_long longlink_addr;
+ int mfc_count;
+ int mfc_index;
+ struct {
+ int common;
+ u_long addr;
+ } mfc[256 / 5];
+ int ret;
+
+ ret = 0;
+
+ pct = sc->pct;
+ pch = sc->pch;
+
+ /* allocate some memory */
+
+ if (pccard_chip_mem_alloc(pct, pch, PCCARD_CIS_SIZE, &pcmh)) {
+#ifdef DIAGNOSTIC
+ printf("%s: can't alloc memory to read attributes\n",
+ sc->dev.dv_xname);
+#endif
+ return -1;
+ }
+ tuple.memt = pcmh.memt;
+ tuple.memh = pcmh.memh;
+
+ /* initialize state for the primary tuple chain */
+ if (pccard_chip_mem_map(pct, pch, PCCARD_MEM_ATTR, 0,
+ PCCARD_CIS_SIZE, &pcmh, &tuple.ptr, &window)) {
+ pccard_chip_mem_free(pct, pch, &pcmh);
+#ifdef DIAGNOSTIC
+ printf("%s: can't map memory to read attributes\n",
+ sc->dev.dv_xname);
+#endif
+ return -1;
+ }
+#ifndef __FreeBSD__
+ DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
+#endif
+ tuple.mult = 2;
+
+ longlink_present = 1;
+ longlink_common = 1;
+ longlink_addr = 0;
+
+ mfc_count = 0;
+ mfc_index = 0;
+
+ DPRINTF(("%s: CIS tuple chain:\n", sc->dev.dv_xname));
+
+ while (1) {
+ while (1) {
+ /* get the tuple code */
+
+ tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
+
+ /* two special-case tuples */
+
+ if (tuple.code == PCCARD_CISTPL_NULL) {
+ DPRINTF(("CISTPL_NONE\n 00\n"));
+ tuple.ptr++;
+ continue;
+ } else if (tuple.code == PCCARD_CISTPL_END) {
+ DPRINTF(("CISTPL_END\n ff\n"));
+ /* Call the function for the END tuple, since
+ the CIS semantics depend on it */
+ if ((*fct) (&tuple, arg)) {
+ pccard_chip_mem_unmap(pct, pch,
+ window);
+ ret = 1;
+ goto done;
+ }
+ tuple.ptr++;
+ break;
+ }
+ /* now all the normal tuples */
+
+ tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
+ switch (tuple.code) {
+ case PCCARD_CISTPL_LONGLINK_A:
+ case PCCARD_CISTPL_LONGLINK_C:
+ if (tuple.length < 4) {
+ DPRINTF(("CISTPL_LONGLINK_%s too "
+ "short %d\n",
+ longlink_common ? "C" : "A",
+ tuple.length));
+ break;
+ }
+ longlink_present = 1;
+ longlink_common = (tuple.code ==
+ PCCARD_CISTPL_LONGLINK_C) ? 1 : 0;
+ longlink_addr = pccard_tuple_read_4(&tuple, 0);
+ DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
+ longlink_common ? "C" : "A",
+ longlink_addr));
+ break;
+ case PCCARD_CISTPL_NO_LINK:
+ longlink_present = 0;
+ DPRINTF(("CISTPL_NO_LINK\n"));
+ break;
+ case PCCARD_CISTPL_CHECKSUM:
+ if (tuple.length < 5) {
+ DPRINTF(("CISTPL_CHECKSUM too "
+ "short %d\n", tuple.length));
+ break;
+ } {
+ int16_t offset;
+ u_long addr, length;
+ u_int cksum, sum;
+ int i;
+
+ *((u_int16_t *) & offset) =
+ pccard_tuple_read_2(&tuple, 0);
+ length = pccard_tuple_read_2(&tuple, 2);
+ cksum = pccard_tuple_read_1(&tuple, 4);
+
+ addr = tuple.ptr + offset;
+
+ DPRINTF(("CISTPL_CHECKSUM addr=%lx "
+ "len=%lx cksum=%x",
+ addr, length, cksum));
+
+ /*
+ * XXX do more work to deal with
+ * distant regions
+ */
+ if ((addr >= PCCARD_CIS_SIZE) ||
+ ((addr + length) < 0) ||
+ ((addr + length) >=
+ PCCARD_CIS_SIZE)) {
+ DPRINTF((" skipped, "
+ "too distant\n"));
+ break;
+ }
+ sum = 0;
+ for (i = 0; i < length; i++)
+ sum +=
+ bus_space_read_1(tuple.memt,
+ tuple.memh,
+ addr + tuple.mult * i);
+ if (cksum != (sum & 0xff)) {
+ DPRINTF((" failed sum=%x\n",
+ sum));
+#if XXX
+ printf("%s: CIS checksum "
+ "failed\n",
+ sc->dev.dv_xname);
+#endif
+#if 0
+ /*
+ * XXX Some working cards have
+ * XXX bad checksums!!
+ */
+ ret = -1;
+#endif
+ } else {
+ DPRINTF((" ok\n"));
+ }
+ }
+ break;
+ case PCCARD_CISTPL_LONGLINK_MFC:
+ if (tuple.length < 1) {
+ DPRINTF(("CISTPL_LONGLINK_MFC too "
+ "short %d\n", tuple.length));
+ break;
+ }
+ /*
+ * this is kind of ad hoc, as I don't have
+ * any real documentation
+ */
+ {
+ int i;
+
+ mfc_count =
+ pccard_tuple_read_1(&tuple, 0);
+ DPRINTF(("CISTPL_LONGLINK_MFC %d",
+ mfc_count));
+ for (i = 0; i < mfc_count; i++) {
+ mfc[i].common =
+ (pccard_tuple_read_1(&tuple,
+ 1 + 5 * i) ==
+ PCCARD_MFC_MEM_COMMON) ?
+ 1 : 0;
+ mfc[i].addr =
+ pccard_tuple_read_4(&tuple,
+ 1 + 5 * i + 1);
+ DPRINTF((" %s:%lx",
+ mfc[i].common ? "common" :
+ "attr", mfc[i].addr));
+ }
+ DPRINTF(("\n"));
+ }
+ /*
+ * for LONGLINK_MFC, fall through to the
+ * function. This tuple has structural and
+ * semantic content.
+ */
+ default:
+ {
+ if ((*fct) (&tuple, arg)) {
+ pccard_chip_mem_unmap(pct,
+ pch, window);
+ ret = 1;
+ goto done;
+ }
+ }
+ break;
+ } /* switch */
+#ifdef PCCARDCISDEBUG
+ /* print the tuple */
+ {
+ int i;
+
+ DPRINTF((" %02x %02x", tuple.code,
+ tuple.length));
+
+ for (i = 0; i < tuple.length; i++) {
+ DPRINTF((" %02x",
+ pccard_tuple_read_1(&tuple, i)));
+ if ((i % 16) == 13)
+ DPRINTF(("\n"));
+ }
+ if ((i % 16) != 14)
+ DPRINTF(("\n"));
+ }
+#endif
+ /* skip to the next tuple */
+ tuple.ptr += 2 + tuple.length;
+ }
+
+ /*
+ * the chain is done. Clean up and move onto the next one,
+ * if any. The loop is here in the case that there is an MFC
+ * card with no longlink (which defaults to existing, == 0).
+ * In general, this means that if one pointer fails, it will
+ * try the next one, instead of just bailing.
+ */
+
+ while (1) {
+ pccard_chip_mem_unmap(pct, pch, window);
+
+ if (longlink_present) {
+ /*
+ * if the longlink is to attribute memory,
+ * then it is unindexed. That is, if the
+ * link value is 0x100, then the actual
+ * memory address is 0x200. This means that
+ * we need to multiply by 2 before calling
+ * mem_map, and then divide the resulting ptr
+ * by 2 after.
+ */
+
+ if (!longlink_common)
+ longlink_addr *= 2;
+
+ pccard_chip_mem_map(pct, pch, longlink_common ?
+ PCCARD_MEM_COMMON : PCCARD_MEM_ATTR,
+ longlink_addr, PCCARD_CIS_SIZE,
+ &pcmh, &tuple.ptr, &window);
+
+ if (!longlink_common)
+ tuple.ptr /= 2;
+#ifndef __FreeBSD__
+ DPRINTF(("cis mem map %x\n",
+ (unsigned int) tuple.memh));
+#endif
+ tuple.mult = longlink_common ? 1 : 2;
+ longlink_present = 0;
+ longlink_common = 1;
+ longlink_addr = 0;
+ } else if (mfc_count && (mfc_index < mfc_count)) {
+ if (!mfc[mfc_index].common)
+ mfc[mfc_index].addr *= 2;
+
+ pccard_chip_mem_map(pct, pch,
+ mfc[mfc_index].common ?
+ PCCARD_MEM_COMMON : PCCARD_MEM_ATTR,
+ mfc[mfc_index].addr, PCCARD_CIS_SIZE,
+ &pcmh, &tuple.ptr, &window);
+
+ if (!mfc[mfc_index].common)
+ tuple.ptr /= 2;
+#ifndef __FreeBSD__
+ DPRINTF(("cis mem map %x\n",
+ (unsigned int) tuple.memh));
+#endif
+ /* set parse state, and point at the next one */
+
+ tuple.mult = mfc[mfc_index].common ? 1 : 2;
+
+ mfc_index++;
+ } else {
+ goto done;
+ }
+
+ /* make sure that the link is valid */
+ tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
+ if (tuple.code != PCCARD_CISTPL_LINKTARGET) {
+ DPRINTF(("CISTPL_LINKTARGET expected, "
+ "code %02x observed\n", tuple.code));
+ continue;
+ }
+ tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
+ if (tuple.length < 3) {
+ DPRINTF(("CISTPL_LINKTARGET too short %d\n",
+ tuple.length));
+ continue;
+ }
+ if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
+ (pccard_tuple_read_1(&tuple, 1) != 'I') ||
+ (pccard_tuple_read_1(&tuple, 2) != 'S')) {
+ DPRINTF(("CISTPL_LINKTARGET magic "
+ "%02x%02x%02x incorrect\n",
+ pccard_tuple_read_1(&tuple, 0),
+ pccard_tuple_read_1(&tuple, 1),
+ pccard_tuple_read_1(&tuple, 2)));
+ continue;
+ }
+ tuple.ptr += 2 + tuple.length;
+
+ break;
+ }
+ }
+
+ pccard_chip_mem_unmap(pct, pch, window);
+
+done:
+ /* Last, free the allocated memory block */
+ pccard_chip_mem_free(pct, pch, &pcmh);
+
+ return (ret);
+}
+
+/* XXX this is incredibly verbose. Not sure what trt is */
+
+void
+pccard_print_cis(device_t dev)
+{
+ struct pccard_softc *sc = (struct pccard_softc *) device_get_softc(dev);
+ struct pccard_card *card = &sc->card;
+ struct pccard_function *pf;
+ struct pccard_config_entry *cfe;
+ int i;
+
+ device_printf(dev, "CIS version ");
+ if (card->cis1_major == 4) {
+ if (card->cis1_minor == 0)
+ printf("PCCARD 1.0\n");
+ else if (card->cis1_minor == 1)
+ printf("PCCARD 2.0 or 2.1\n");
+ } else if (card->cis1_major >= 5)
+ printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
+ else
+ printf("unknown (major=%d, minor=%d)\n",
+ card->cis1_major, card->cis1_minor);
+
+ device_printf(dev, "CIS info: ");
+ for (i = 0; i < 4; i++) {
+ if (card->cis1_info[i] == NULL)
+ break;
+ if (i)
+ printf(", ");
+ printf("%s", card->cis1_info[i]);
+ }
+ printf("\n");
+
+ device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
+ card->manufacturer, card->product);
+
+ STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
+ device_printf(dev, "function %d: ", pf->number);
+
+ switch (pf->function) {
+ case PCCARD_FUNCTION_UNSPEC:
+ printf("unspecified");
+ break;
+ case PCCARD_FUNCTION_MULTIFUNCTION:
+ printf("multi-function");
+ break;
+ case PCCARD_FUNCTION_MEMORY:
+ printf("memory");
+ break;
+ case PCCARD_FUNCTION_SERIAL:
+ printf("serial port");
+ break;
+ case PCCARD_FUNCTION_PARALLEL:
+ printf("parallel port");
+ break;
+ case PCCARD_FUNCTION_DISK:
+ printf("fixed disk");
+ break;
+ case PCCARD_FUNCTION_VIDEO:
+ printf("video adapter");
+ break;
+ case PCCARD_FUNCTION_NETWORK:
+ printf("network adapter");
+ break;
+ case PCCARD_FUNCTION_AIMS:
+ printf("auto incrementing mass storage");
+ break;
+ case PCCARD_FUNCTION_SCSI:
+ printf("SCSI bridge");
+ break;
+ case PCCARD_FUNCTION_SECURITY:
+ printf("Security services");
+ break;
+ case PCCARD_FUNCTION_INSTRUMENT:
+ printf("Instrument");
+ break;
+ default:
+ printf("unknown (%d)", pf->function);
+ break;
+ }
+
+ printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask);
+
+ STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
+ device_printf(dev, "function %d, config table entry "
+ "%d: ", pf->number, cfe->number);
+
+ switch (cfe->iftype) {
+ case PCCARD_IFTYPE_MEMORY:
+ printf("memory card");
+ break;
+ case PCCARD_IFTYPE_IO:
+ printf("I/O card");
+ break;
+ default:
+ printf("card type unknown");
+ break;
+ }
+
+ printf("; irq mask %x", cfe->irqmask);
+
+ if (cfe->num_iospace) {
+ printf("; iomask %lx, iospace", cfe->iomask);
+
+ for (i = 0; i < cfe->num_iospace; i++)
+ printf(" %lx%s%lx",
+ cfe->iospace[i].start,
+ cfe->iospace[i].length ? "-" : "",
+ cfe->iospace[i].start +
+ cfe->iospace[i].length - 1);
+ }
+ if (cfe->num_memspace) {
+ printf("; memspace");
+
+ for (i = 0; i < cfe->num_memspace; i++)
+ printf(" %lx%s%lx%s%lx",
+ cfe->memspace[i].cardaddr,
+ cfe->memspace[i].length ? "-" : "",
+ cfe->memspace[i].cardaddr +
+ cfe->memspace[i].length - 1,
+ cfe->memspace[i].hostaddr ?
+ "@" : "",
+ cfe->memspace[i].hostaddr);
+ }
+ if (cfe->maxtwins)
+ printf("; maxtwins %d", cfe->maxtwins);
+
+ printf(";");
+
+ if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
+ printf(" mwait_required");
+ if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
+ printf(" rdybsy_active");
+ if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
+ printf(" wp_active");
+ if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
+ printf(" bvd_active");
+ if (cfe->flags & PCCARD_CFE_IO8)
+ printf(" io8");
+ if (cfe->flags & PCCARD_CFE_IO16)
+ printf(" io16");
+ if (cfe->flags & PCCARD_CFE_IRQSHARE)
+ printf(" irqshare");
+ if (cfe->flags & PCCARD_CFE_IRQPULSE)
+ printf(" irqpulse");
+ if (cfe->flags & PCCARD_CFE_IRQLEVEL)
+ printf(" irqlevel");
+ if (cfe->flags & PCCARD_CFE_POWERDOWN)
+ printf(" powerdown");
+ if (cfe->flags & PCCARD_CFE_READONLY)
+ printf(" readonly");
+ if (cfe->flags & PCCARD_CFE_AUDIO)
+ printf(" audio");
+
+ printf("\n");
+ }
+ }
+
+ if (card->error)
+ device_printf(dev, "%d errors found while parsing CIS\n",
+ card->error);
+}
+
+int
+pccard_parse_cis_tuple(tuple, arg)
+ struct pccard_tuple *tuple;
+ void *arg;
+{
+ /* most of these are educated guesses */
+ static struct pccard_config_entry init_cfe = {
+ -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
+ PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
+ };
+
+ struct cis_state *state = arg;
+
+ switch (tuple->code) {
+ case PCCARD_CISTPL_END:
+ /* if we've seen a LONGLINK_MFC, and this is the first
+ * END after it, reset the function list.
+ *
+ * XXX This might also be the right place to start a
+ * new function, but that assumes that a function
+ * definition never crosses any longlink, and I'm not
+ * sure about that. This is probably safe for MFC
+ * cards, but what we have now isn't broken, so I'd
+ * rather not change it.
+ */
+ if (state->gotmfc == 1) {
+ struct pccard_function *pf, *pfnext;
+
+ for (pf = STAILQ_FIRST(&state->card->pf_head);
+ pf != NULL; pf = pfnext) {
+ pfnext = STAILQ_NEXT(pf, pf_list);
+ free(pf, M_DEVBUF);
+ }
+
+ STAILQ_INIT(&state->card->pf_head);
+
+ state->count = 0;
+ state->gotmfc = 2;
+ state->pf = NULL;
+ }
+ break;
+ case PCCARD_CISTPL_LONGLINK_MFC:
+ /*
+ * this tuple's structure was dealt with in scan_cis. here,
+ * record the fact that the MFC tuple was seen, so that
+ * functions declared before the MFC link can be cleaned
+ * up.
+ */
+ state->gotmfc = 1;
+ break;
+#ifdef PCCARDCISDEBUG
+ case PCCARD_CISTPL_DEVICE:
+ case PCCARD_CISTPL_DEVICE_A:
+ {
+ u_int reg, dtype, dspeed;
+
+ reg = pccard_tuple_read_1(tuple, 0);
+ dtype = reg & PCCARD_DTYPE_MASK;
+ dspeed = reg & PCCARD_DSPEED_MASK;
+
+ DPRINTF(("CISTPL_DEVICE%s type=",
+ (tuple->code == PCCARD_CISTPL_DEVICE) ? "" : "_A"));
+ switch (dtype) {
+ case PCCARD_DTYPE_NULL:
+ DPRINTF(("null"));
+ break;
+ case PCCARD_DTYPE_ROM:
+ DPRINTF(("rom"));
+ break;
+ case PCCARD_DTYPE_OTPROM:
+ DPRINTF(("otprom"));
+ break;
+ case PCCARD_DTYPE_EPROM:
+ DPRINTF(("eprom"));
+ break;
+ case PCCARD_DTYPE_EEPROM:
+ DPRINTF(("eeprom"));
+ break;
+ case PCCARD_DTYPE_FLASH:
+ DPRINTF(("flash"));
+ break;
+ case PCCARD_DTYPE_SRAM:
+ DPRINTF(("sram"));
+ break;
+ case PCCARD_DTYPE_DRAM:
+ DPRINTF(("dram"));
+ break;
+ case PCCARD_DTYPE_FUNCSPEC:
+ DPRINTF(("funcspec"));
+ break;
+ case PCCARD_DTYPE_EXTEND:
+ DPRINTF(("extend"));
+ break;
+ default:
+ DPRINTF(("reserved"));
+ break;
+ }
+ DPRINTF((" speed="));
+ switch (dspeed) {
+ case PCCARD_DSPEED_NULL:
+ DPRINTF(("null"));
+ break;
+ case PCCARD_DSPEED_250NS:
+ DPRINTF(("250ns"));
+ break;
+ case PCCARD_DSPEED_200NS:
+ DPRINTF(("200ns"));
+ break;
+ case PCCARD_DSPEED_150NS:
+ DPRINTF(("150ns"));
+ break;
+ case PCCARD_DSPEED_100NS:
+ DPRINTF(("100ns"));
+ break;
+ case PCCARD_DSPEED_EXT:
+ DPRINTF(("ext"));
+ break;
+ default:
+ DPRINTF(("reserved"));
+ break;
+ }
+ }
+ DPRINTF(("\n"));
+ break;
+#endif
+ case PCCARD_CISTPL_VERS_1:
+ if (tuple->length < 6) {
+ DPRINTF(("CISTPL_VERS_1 too short %d\n",
+ tuple->length));
+ break;
+ } {
+ int start, i, ch, count;
+
+ state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
+ state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
+
+ for (count = 0, start = 0, i = 0;
+ (count < 4) && ((i + 4) < 256); i++) {
+ ch = pccard_tuple_read_1(tuple, 2 + i);
+ if (ch == 0xff)
+ break;
+ state->card->cis1_info_buf[i] = ch;
+ if (ch == 0) {
+ state->card->cis1_info[count] =
+ state->card->cis1_info_buf + start;
+ start = i + 1;
+ count++;
+ }
+ }
+ DPRINTF(("CISTPL_VERS_1\n"));
+ }
+ break;
+ case PCCARD_CISTPL_MANFID:
+ if (tuple->length < 4) {
+ DPRINTF(("CISTPL_MANFID too short %d\n",
+ tuple->length));
+ break;
+ }
+ state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
+ state->card->product = pccard_tuple_read_2(tuple, 2);
+ DPRINTF(("CISTPL_MANFID\n"));
+ break;
+ case PCCARD_CISTPL_FUNCID:
+ if (tuple->length < 1) {
+ DPRINTF(("CISTPL_FUNCID too short %d\n",
+ tuple->length));
+ break;
+ }
+ if ((state->pf == NULL) || (state->gotmfc == 2)) {
+ state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
+ M_NOWAIT);
+ bzero(state->pf, sizeof(*state->pf));
+ state->pf->number = state->count++;
+ state->pf->last_config_index = -1;
+ STAILQ_INIT(&state->pf->cfe_head);
+
+ STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
+ pf_list);
+ }
+ state->pf->function = pccard_tuple_read_1(tuple, 0);
+
+ DPRINTF(("CISTPL_FUNCID\n"));
+ break;
+ case PCCARD_CISTPL_CONFIG:
+ if (tuple->length < 3) {
+ DPRINTF(("CISTPL_CONFIG too short %d\n",
+ tuple->length));
+ break;
+ } {
+ u_int reg, rasz, rmsz, rfsz;
+ int i;
+
+ reg = pccard_tuple_read_1(tuple, 0);
+ rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
+ PCCARD_TPCC_RASZ_SHIFT);
+ rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
+ PCCARD_TPCC_RMSZ_SHIFT);
+ rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
+ PCCARD_TPCC_RFSZ_SHIFT);
+
+ if (tuple->length < (rasz + rmsz + rfsz)) {
+ DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
+ "short %d\n", rasz, rmsz, rfsz,
+ tuple->length));
+ break;
+ }
+ if (state->pf == NULL) {
+ state->pf = malloc(sizeof(*state->pf),
+ M_DEVBUF, M_NOWAIT);
+ bzero(state->pf, sizeof(*state->pf));
+ state->pf->number = state->count++;
+ state->pf->last_config_index = -1;
+ STAILQ_INIT(&state->pf->cfe_head);
+
+ STAILQ_INSERT_TAIL(&state->card->pf_head,
+ state->pf, pf_list);
+
+ state->pf->function = PCCARD_FUNCTION_UNSPEC;
+ }
+ state->pf->last_config_index =
+ pccard_tuple_read_1(tuple, 1);
+
+ state->pf->ccr_base = 0;
+ for (i = 0; i < rasz; i++)
+ state->pf->ccr_base |=
+ ((pccard_tuple_read_1(tuple, 2 + i)) <<
+ (i * 8));
+
+ state->pf->ccr_mask = 0;
+ for (i = 0; i < rmsz; i++)
+ state->pf->ccr_mask |=
+ ((pccard_tuple_read_1(tuple,
+ 2 + rasz + i)) << (i * 8));
+
+ /* skip the reserved area and subtuples */
+
+ /* reset the default cfe for each cfe list */
+ state->temp_cfe = init_cfe;
+ state->default_cfe = &state->temp_cfe;
+ }
+ DPRINTF(("CISTPL_CONFIG\n"));
+ break;
+ case PCCARD_CISTPL_CFTABLE_ENTRY:
+ {
+ int idx, i, j;
+ u_int reg, reg2;
+ u_int intface, def, num;
+ u_int power, timing, iospace, irq, memspace, misc;
+ struct pccard_config_entry *cfe;
+
+ idx = 0;
+
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+ intface = reg & PCCARD_TPCE_INDX_INTFACE;
+ def = reg & PCCARD_TPCE_INDX_DEFAULT;
+ num = reg & PCCARD_TPCE_INDX_NUM_MASK;
+
+ /*
+ * this is a little messy. Some cards have only a
+ * cfentry with the default bit set. So, as we go
+ * through the list, we add new indexes to the queue,
+ * and keep a pointer to the last one with the
+ * default bit set. if we see a record with the same
+ * index, as the default, we stash the default and
+ * replace the queue entry. otherwise, we just add
+ * new entries to the queue, pointing the default ptr
+ * at them if the default bit is set. if we get to
+ * the end with the default pointer pointing at a
+ * record which hasn't had a matching index, that's
+ * ok; it just becomes a cfentry like any other.
+ */
+
+ /*
+ * if the index in the cis differs from the default
+ * cis, create new entry in the queue and start it
+ * with the current default
+ */
+ if (num != state->default_cfe->number) {
+ cfe = (struct pccard_config_entry *)
+ malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+
+ *cfe = *state->default_cfe;
+
+ STAILQ_INSERT_TAIL(&state->pf->cfe_head,
+ cfe, cfe_list);
+
+ cfe->number = num;
+
+ /*
+ * if the default bit is set in the cis, then
+ * point the new default at whatever is being
+ * filled in
+ */
+ if (def)
+ state->default_cfe = cfe;
+ } else {
+ /*
+ * the cis index matches the default index,
+ * fill in the default cfentry. It is
+ * assumed that the cfdefault index is in the
+ * queue. For it to be otherwise, the cis
+ * index would have to be -1 (initial
+ * condition) which is not possible, or there
+ * would have to be a preceding cis entry
+ * which had the same cis index and had the
+ * default bit unset. Neither condition
+ * should happen. If it does, this cfentry
+ * is lost (written into temp space), which
+ * is an acceptable failure mode.
+ */
+
+ cfe = state->default_cfe;
+
+ /*
+ * if the cis entry does not have the default
+ * bit set, copy the default out of the way
+ * first.
+ */
+ if (!def) {
+ state->temp_cfe = *state->default_cfe;
+ state->default_cfe = &state->temp_cfe;
+ }
+ }
+
+ if (intface) {
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+ if (reg & PCCARD_TPCE_IF_MWAIT)
+ cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
+ if (reg & PCCARD_TPCE_IF_RDYBSY)
+ cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
+ if (reg & PCCARD_TPCE_IF_WP)
+ cfe->flags |= PCCARD_CFE_WP_ACTIVE;
+ if (reg & PCCARD_TPCE_IF_BVD)
+ cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
+ cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
+ }
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ power = reg & PCCARD_TPCE_FS_POWER_MASK;
+ timing = reg & PCCARD_TPCE_FS_TIMING;
+ iospace = reg & PCCARD_TPCE_FS_IOSPACE;
+ irq = reg & PCCARD_TPCE_FS_IRQ;
+ memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
+ misc = reg & PCCARD_TPCE_FS_MISC;
+
+ if (power) {
+ /* skip over power, don't save */
+ /* for each parameter selection byte */
+ for (i = 0; i < power; i++) {
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+ /* for each bit */
+ for (j = 0; j < 7; j++) {
+ /* if the bit is set */
+ if ((reg >> j) & 0x01) {
+ /* skip over bytes */
+ do {
+ reg2 = pccard_tuple_read_1(tuple, idx);
+ idx++;
+ /*
+ * until
+ * non-extensi
+ * on byte
+ */
+ } while (reg2 & 0x80);
+ }
+ }
+ }
+ }
+ if (timing) {
+ /* skip over timing, don't save */
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
+ PCCARD_TPCE_TD_RESERVED_MASK)
+ idx++;
+ if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
+ PCCARD_TPCE_TD_RDYBSY_MASK)
+ idx++;
+ if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
+ PCCARD_TPCE_TD_WAIT_MASK)
+ idx++;
+ }
+ if (iospace) {
+ if (tuple->length <= idx) {
+ DPRINTF(("ran out of space before TCPE_IO\n"));
+ goto abort_cfe;
+ }
+
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
+ cfe->flags |= PCCARD_CFE_IO8;
+ if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
+ cfe->flags |= PCCARD_CFE_IO16;
+ cfe->iomask =
+ reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
+
+ if (reg & PCCARD_TPCE_IO_HASRANGE) {
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ cfe->num_iospace = 1 + (reg &
+ PCCARD_TPCE_IO_RANGE_COUNT);
+
+ if (cfe->num_iospace >
+ (sizeof(cfe->iospace) /
+ sizeof(cfe->iospace[0]))) {
+ DPRINTF(("too many io "
+ "spaces %d",
+ cfe->num_iospace));
+ state->card->error++;
+ break;
+ }
+ for (i = 0; i < cfe->num_iospace; i++) {
+ switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
+ case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
+ cfe->iospace[i].start =
+ pccard_tuple_read_1(tuple, idx);
+ idx++;
+ break;
+ case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
+ cfe->iospace[i].start =
+ pccard_tuple_read_2(tuple, idx);
+ idx += 2;
+ break;
+ case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
+ cfe->iospace[i].start =
+ pccard_tuple_read_4(tuple, idx);
+ idx += 4;
+ break;
+ }
+ switch (reg &
+ PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
+ case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
+ cfe->iospace[i].length =
+ pccard_tuple_read_1(tuple, idx);
+ idx++;
+ break;
+ case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
+ cfe->iospace[i].length =
+ pccard_tuple_read_2(tuple, idx);
+ idx += 2;
+ break;
+ case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
+ cfe->iospace[i].length =
+ pccard_tuple_read_4(tuple, idx);
+ idx += 4;
+ break;
+ }
+ cfe->iospace[i].length++;
+ }
+ } else {
+ cfe->num_iospace = 1;
+ cfe->iospace[0].start = 0;
+ cfe->iospace[0].length =
+ (1 << cfe->iomask);
+ }
+ }
+ if (irq) {
+ if (tuple->length <= idx) {
+ DPRINTF(("ran out of space before TCPE_IR\n"));
+ goto abort_cfe;
+ }
+
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ if (reg & PCCARD_TPCE_IR_SHARE)
+ cfe->flags |= PCCARD_CFE_IRQSHARE;
+ if (reg & PCCARD_TPCE_IR_PULSE)
+ cfe->flags |= PCCARD_CFE_IRQPULSE;
+ if (reg & PCCARD_TPCE_IR_LEVEL)
+ cfe->flags |= PCCARD_CFE_IRQLEVEL;
+
+ if (reg & PCCARD_TPCE_IR_HASMASK) {
+ /*
+ * it's legal to ignore the
+ * special-interrupt bits, so I will
+ */
+
+ cfe->irqmask =
+ pccard_tuple_read_2(tuple, idx);
+ idx += 2;
+ } else {
+ cfe->irqmask =
+ (1 << (reg & PCCARD_TPCE_IR_IRQ));
+ }
+ }
+ if (memspace) {
+ if (tuple->length <= idx) {
+ DPRINTF(("ran out of space before TCPE_MS\n"));
+ goto abort_cfe;
+ }
+
+ if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) {
+ cfe->num_memspace = 0;
+ } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
+ cfe->num_memspace = 1;
+ cfe->memspace[0].length = 256 *
+ pccard_tuple_read_2(tuple, idx);
+ idx += 2;
+ cfe->memspace[0].cardaddr = 0;
+ cfe->memspace[0].hostaddr = 0;
+ } else if (memspace ==
+ PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
+ cfe->num_memspace = 1;
+ cfe->memspace[0].length = 256 *
+ pccard_tuple_read_2(tuple, idx);
+ idx += 2;
+ cfe->memspace[0].cardaddr = 256 *
+ pccard_tuple_read_2(tuple, idx);
+ idx += 2;
+ cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
+ } else {
+ int lengthsize;
+ int cardaddrsize;
+ int hostaddrsize;
+
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ cfe->num_memspace = reg &
+ PCCARD_TPCE_MS_COUNT;
+
+ if (cfe->num_memspace >
+ (sizeof(cfe->memspace) /
+ sizeof(cfe->memspace[0]))) {
+ DPRINTF(("too many mem "
+ "spaces %d",
+ cfe->num_memspace));
+ state->card->error++;
+ break;
+ }
+ lengthsize =
+ ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
+ PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
+ cardaddrsize =
+ ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
+ PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
+ hostaddrsize =
+ (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
+
+ if (lengthsize == 0) {
+ DPRINTF(("cfe memspace "
+ "lengthsize == 0"));
+ state->card->error++;
+ }
+ for (i = 0; i < cfe->num_memspace; i++) {
+ if (lengthsize) {
+ cfe->memspace[i].length =
+ 256 * pccard_tuple_read_n(tuple, lengthsize,
+ idx);
+ idx += lengthsize;
+ } else {
+ cfe->memspace[i].length = 0;
+ }
+ if (cfe->memspace[i].length == 0) {
+ DPRINTF(("cfe->memspace[%d].length == 0",
+ i));
+ state->card->error++;
+ }
+ if (cardaddrsize) {
+ cfe->memspace[i].cardaddr =
+ 256 * pccard_tuple_read_n(tuple, cardaddrsize,
+ idx);
+ idx += cardaddrsize;
+ } else {
+ cfe->memspace[i].cardaddr = 0;
+ }
+ if (hostaddrsize) {
+ cfe->memspace[i].hostaddr =
+ 256 * pccard_tuple_read_n(tuple, hostaddrsize,
+ idx);
+ idx += hostaddrsize;
+ } else {
+ cfe->memspace[i].hostaddr = 0;
+ }
+ }
+ }
+ }
+ if (misc) {
+ if (tuple->length <= idx) {
+ DPRINTF(("ran out of space before TCPE_MI\n"));
+ goto abort_cfe;
+ }
+
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+
+ if (reg & PCCARD_TPCE_MI_PWRDOWN)
+ cfe->flags = PCCARD_CFE_POWERDOWN;
+ if (reg & PCCARD_TPCE_MI_READONLY)
+ cfe->flags = PCCARD_CFE_READONLY;
+ if (reg & PCCARD_TPCE_MI_AUDIO)
+ cfe->flags = PCCARD_CFE_AUDIO;
+ cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
+
+ while (reg & PCCARD_TPCE_MI_EXT) {
+ reg = pccard_tuple_read_1(tuple, idx);
+ idx++;
+ }
+ }
+ /* skip all the subtuples */
+ }
+
+ abort_cfe:
+ DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
+ break;
+ default:
+ DPRINTF(("unhandled CISTPL %x\n", tuple->code));
+ break;
+ }
+
+ return (0);
+}
diff --git a/sys/dev/pccard/pccard_cis_quirks.c b/sys/dev/pccard/pccard_cis_quirks.c
new file mode 100644
index 0000000..448ca40
--- /dev/null
+++ b/sys/dev/pccard/pccard_cis_quirks.c
@@ -0,0 +1,208 @@
+/* $NetBSD: pcmcia_cis_quirks.c,v 1.3 1998/12/29 09:00:28 marc Exp $ */
+/* $FreeBSD$ */
+
+#define PCCARDDEBUG
+
+/*
+ * 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pccard/pccarddevs.h>
+#include <dev/pccard/pccardreg.h>
+#include <dev/pccard/pccardchip.h>
+#include <dev/pccard/pccardvar.h>
+
+/* There are cards out there whose CIS flat-out lies. This file
+ contains struct pccard_function chains for those devices. */
+
+/* these structures are just static templates which are then copied
+ into "live" allocated structures */
+
+struct pccard_function pccard_3cxem556_func0 = {
+ 0, /* function number */
+ PCCARD_FUNCTION_NETWORK,
+ 0x07, /* last cfe number */
+ 0x800, /* ccr_base */
+ 0x63, /* ccr_mask */
+};
+
+struct pccard_config_entry pccard_3cxem556_func0_cfe0 = {
+ 0x07, /* cfe number */
+ PCCARD_CFE_IO8 | PCCARD_CFE_IO16 | PCCARD_CFE_IRQLEVEL,
+ PCCARD_IFTYPE_IO,
+ 1, /* num_iospace */
+ 4, /* iomask */
+ { { 0x0010, 0 } }, /* iospace */
+ 0xffff, /* irqmask */
+ 0, /* num_memspace */
+ { }, /* memspace */
+ 0, /* maxtwins */
+};
+
+static struct pccard_function pccard_3cxem556_func1 = {
+ 1, /* function number */
+ PCCARD_FUNCTION_SERIAL,
+ 0x27, /* last cfe number */
+ 0x900, /* ccr_base */
+ 0x63, /* ccr_mask */
+};
+
+static struct pccard_config_entry pccard_3cxem556_func1_cfe0 = {
+ 0x27, /* cfe number */
+ PCCARD_CFE_IO8 | PCCARD_CFE_IRQLEVEL,
+ PCCARD_IFTYPE_IO,
+ 1, /* num_iospace */
+ 3, /* iomask */
+ { { 0x0008, 0 } }, /* iospace */
+ 0xffff, /* irqmask */
+ 0, /* num_memspace */
+ { }, /* memspace */
+ 0, /* maxtwins */
+};
+
+static struct pccard_function pccard_sveclancard_func0 = {
+ 0, /* function number */
+ PCCARD_FUNCTION_NETWORK,
+ 0x1, /* last cfe number */
+ 0x100, /* ccr_base */
+ 0x1, /* ccr_mask */
+};
+
+static struct pccard_config_entry pccard_sveclancard_func0_cfe0 = {
+ 0x1, /* cfe number */
+ PCCARD_CFE_MWAIT_REQUIRED | PCCARD_CFE_RDYBSY_ACTIVE |
+ PCCARD_CFE_WP_ACTIVE | PCCARD_CFE_BVD_ACTIVE | PCCARD_CFE_IO16,
+ PCCARD_IFTYPE_IO,
+ 1, /* num_iospace */
+ 5, /* iomask */
+ { { 0x20, 0x300 } }, /* iospace */
+ 0xdeb8, /* irqmask */
+ 0, /* num_memspace */
+ { }, /* memspace */
+ 0, /* maxtwins */
+};
+
+static struct pccard_cis_quirk pccard_cis_quirks[] = {
+ { PCCARD_VENDOR_3COM, PCCARD_PRODUCT_3COM_3CXEM556, PCCARD_CIS_INVALID,
+ &pccard_3cxem556_func0, &pccard_3cxem556_func0_cfe0 },
+ { PCCARD_VENDOR_3COM, PCCARD_PRODUCT_3COM_3CXEM556, PCCARD_CIS_INVALID,
+ &pccard_3cxem556_func1, &pccard_3cxem556_func1_cfe0 },
+ { PCCARD_VENDOR_INVALID, PCCARD_PRODUCT_INVALID, PCCARD_CIS_SVEC_LANCARD,
+ &pccard_sveclancard_func0, &pccard_sveclancard_func0_cfe0 },
+};
+
+static int n_pccard_cis_quirks =
+ sizeof(pccard_cis_quirks)/sizeof(pccard_cis_quirks[0]);
+
+void pccard_check_cis_quirks(device_t dev)
+{
+ struct pccard_softc *sc = (struct pccard_softc *)
+ device_get_softc(dev);
+ int wiped = 0;
+ int i, j;
+ struct pccard_function *pf, *pf_next, *pf_last;
+ struct pccard_config_entry *cfe, *cfe_next;
+
+ pf = NULL;
+ pf_last = NULL;
+
+ for (i=0; i<n_pccard_cis_quirks; i++) {
+ if ((sc->card.manufacturer == pccard_cis_quirks[i].manufacturer) &&
+ (sc->card.product == pccard_cis_quirks[i].product) &&
+ (((sc->card.manufacturer != PCCARD_VENDOR_INVALID) &&
+ (sc->card.product != PCCARD_PRODUCT_INVALID)) ||
+ ((sc->card.manufacturer == PCCARD_VENDOR_INVALID) &&
+ (sc->card.product == PCCARD_PRODUCT_INVALID) &&
+ sc->card.cis1_info[0] &&
+ (strcmp(sc->card.cis1_info[0],
+ pccard_cis_quirks[i].cis1_info[0]) == 0) &&
+ sc->card.cis1_info[1] &&
+ (strcmp(sc->card.cis1_info[1],
+ pccard_cis_quirks[i].cis1_info[1]) == 0)))) {
+ if (!wiped) {
+ if (pccard_verbose) {
+ device_printf(dev, "using CIS quirks for ");
+ 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 = STAILQ_FIRST(&sc->card.pf_head); pf != NULL;
+ pf = pf_next) {
+ for (cfe = STAILQ_FIRST(&pf->cfe_head); cfe != NULL;
+ cfe = cfe_next) {
+ cfe_next = STAILQ_NEXT(cfe, cfe_list);
+ free(cfe, M_DEVBUF);
+ }
+ pf_next = STAILQ_NEXT(pf, pf_list);
+ free(pf, M_DEVBUF);
+ }
+
+ STAILQ_INIT(&sc->card.pf_head);
+ wiped = 1;
+ }
+
+ if (pf_last == pccard_cis_quirks[i].pf) {
+ cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+ *cfe = *pccard_cis_quirks[i].cfe;
+
+ STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
+ } else {
+ pf = malloc(sizeof(*pf), M_DEVBUF, M_NOWAIT);
+ *pf = *pccard_cis_quirks[i].pf;
+ STAILQ_INIT(&pf->cfe_head);
+
+ cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+ *cfe = *pccard_cis_quirks[i].cfe;
+
+ STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
+ STAILQ_INSERT_TAIL(&sc->card.pf_head, pf, pf_list);
+
+ pf_last = pccard_cis_quirks[i].pf;
+ }
+ }
+ }
+}
diff --git a/sys/dev/pccard/pccardchip.h b/sys/dev/pccard/pccardchip.h
new file mode 100644
index 0000000..3b99dc8
--- /dev/null
+++ b/sys/dev/pccard/pccardchip.h
@@ -0,0 +1,140 @@
+/* $NetBSD: pcmciachip.h,v 1.3 1998/11/17 08:49:12 thorpej Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (c) 1997 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.
+ */
+
+#ifndef _PCCARD_PCCARDCHIP_H_
+#define _PCCARD_PCCARDCHIP_H_
+
+#include <machine/bus.h>
+
+struct pccard_function;
+struct pccard_mem_handle;
+struct pccard_io_handle;
+
+/* interfaces for pccard to call the chipset */
+
+typedef struct pccard_chip_functions *pccard_chipset_tag_t;
+typedef void *pccard_chipset_handle_t;
+typedef int pccard_mem_handle_t;
+
+#define PCCARD_MEM_ATTR 1
+#define PCCARD_MEM_COMMON 2
+
+#define PCCARD_WIDTH_AUTO 0
+#define PCCARD_WIDTH_IO8 1
+#define PCCARD_WIDTH_IO16 2
+
+struct pccard_chip_functions {
+ /* memory space allocation */
+ int (*mem_alloc) __P((pccard_chipset_handle_t, bus_size_t,
+ struct pccard_mem_handle *));
+ void (*mem_free) __P((pccard_chipset_handle_t,
+ struct pccard_mem_handle *));
+
+ /* memory space window mapping */
+ int (*mem_map) __P((pccard_chipset_handle_t, int, bus_addr_t,
+ bus_size_t, struct pccard_mem_handle *,
+ bus_addr_t *, int *));
+ void (*mem_unmap) __P((pccard_chipset_handle_t, int));
+
+ /* I/O space allocation */
+ int (*io_alloc) __P((pccard_chipset_handle_t, bus_addr_t,
+ bus_size_t, bus_size_t, struct pccard_io_handle *));
+ void (*io_free) __P((pccard_chipset_handle_t,
+ struct pccard_io_handle *));
+
+ /* I/O space window mapping */
+ int (*io_map) __P((pccard_chipset_handle_t, int, bus_addr_t,
+ bus_size_t, struct pccard_io_handle *, int *));
+ void (*io_unmap) __P((pccard_chipset_handle_t, int));
+
+ /* interrupt glue */
+ void *(*intr_establish) __P((pccard_chipset_handle_t,
+ struct pccard_function *, int, int (*)(void *), void *));
+ void (*intr_disestablish) __P((pccard_chipset_handle_t, void *));
+
+ /* card enable/disable */
+ void (*socket_enable) __P((pccard_chipset_handle_t));
+ void (*socket_disable) __P((pccard_chipset_handle_t));
+};
+
+/* Memory space functions. */
+#define pccard_chip_mem_alloc(tag, handle, size, pcmhp) \
+ ((*(tag)->mem_alloc)((handle), (size), (pcmhp)))
+
+#define pccard_chip_mem_free(tag, handle, pcmhp) \
+ ((*(tag)->mem_free)((handle), (pcmhp)))
+
+#define pccard_chip_mem_map(tag, handle, kind, card_addr, size, pcmhp, \
+ offsetp, windowp) \
+ ((*(tag)->mem_map)((handle), (kind), (card_addr), (size), (pcmhp), \
+ (offsetp), (windowp)))
+
+#define pccard_chip_mem_unmap(tag, handle, window) \
+ ((*(tag)->mem_unmap)((handle), (window)))
+
+/* I/O space functions. */
+#define pccard_chip_io_alloc(tag, handle, start, size, align, pcihp) \
+ ((*(tag)->io_alloc)((handle), (start), (size), (align), (pcihp)))
+
+#define pccard_chip_io_free(tag, handle, pcihp) \
+ ((*(tag)->io_free)((handle), (pcihp)))
+
+#define pccard_chip_io_map(tag, handle, width, card_addr, size, pcihp, \
+ windowp) \
+ ((*(tag)->io_map)((handle), (width), (card_addr), (size), (pcihp), \
+ (windowp)))
+
+#define pccard_chip_io_unmap(tag, handle, window) \
+ ((*(tag)->io_unmap)((handle), (window)))
+
+/* Interrupt functions. */
+#define pccard_chip_intr_establish(tag, handle, pf, ipl, fct, arg) \
+ ((*(tag)->intr_establish)((handle), (pf), (ipl), (fct), (arg)))
+
+#define pccard_chip_intr_disestablish(tag, handle, ih) \
+ ((*(tag)->intr_disestablish)((handle), (ih)))
+
+/* Socket functions. */
+#define pccard_chip_socket_enable(tag, handle) \
+ ((*(tag)->socket_enable)((handle)))
+#define pccard_chip_socket_disable(tag, handle) \
+ ((*(tag)->socket_disable)((handle)))
+
+struct pccardbus_attach_args {
+ char *paa_busname;
+ pccard_chipset_tag_t pct;
+ pccard_chipset_handle_t pch;
+ bus_addr_t iobase; /* start i/o space allocation here */
+ bus_size_t iosize; /* size of the i/o space range */
+};
+
+#endif /* _PCCARD_PCCARDCHIP_H_ */
diff --git a/sys/dev/pccard/pccarddevs b/sys/dev/pccard/pccarddevs
new file mode 100644
index 0000000..443d37e
--- /dev/null
+++ b/sys/dev/pccard/pccarddevs
@@ -0,0 +1,181 @@
+$NetBSD: pcmciadevs,v 1.33 1999/02/19 21:49:43 abs Exp $
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/*
+ * List of known PCMCIA vendors
+ */
+
+vendor FUJITSU 0x0004 Fujitsu Corporation
+vendor SANDISK 0x0045 Sandisk Corporation
+vendor NEWMEDIA 0x0057 NewMedia Corporation
+vendor INTEL 0x0089 Intel Corporation
+vendor IBM 0x00a4 IBM Corporation
+vendor MOTOROLA 0x0109 Motorola Corporation
+vendor 3COM 0x0101 3Com Corporation
+vendor MEGAHERTZ 0x0102 Megahertz Corporation
+vendor SOCKET 0x0104 Socket Communications
+vendor TDK 0x0105 TDK Corporation
+vendor SMC 0x0108 Standard Microsystems Corporation
+vendor USROBOTICS 0x0115 US Robotics Corporation
+vendor MEGAHERTZ2 0x0128 Megahertz Corporation
+vendor ADAPTEC 0x012f Adaptec Corporation
+vendor COMPAQ1 0x0138 Compaq Corporation (1)
+vendor LINKSYS 0x0149 Linksys Corporation
+vendor SIMPLETECH 0x014d Simple Technology
+vendor COMPAQ2 0x0183 Compaq Corporation (2)
+vendor DAYNA 0x0194 Dayna Corporation
+vendor IODATA 0x01bf I-O DATA
+vendor COMPEX 0x8a01 Compex Corporation
+vendor COREGA 0xc00f Corega K.K.
+vendor HAGIWARASYSCOM 0xc012 Hagiwara SYS-COM
+vendor RATOC 0xc015 RATOC System Inc.
+
+/*
+ * List of known products. Grouped by vendor.
+ */
+/* Adaptec Products */
+product ADAPTEC APA1460_1 0x0001 Adaptec APA-1460/A SCSI Host Adapter
+product ADAPTEC APA1460_2 0x0002 Adaptec APA-1460/B SCSI Host Adapter
+
+/* 3COM Products */
+product 3COM 3C562 0x0562 3Com 3c562 33.6 Modem/10Mbps Ethernet
+product 3COM 3C589 0x0589 3Com 3c589 10Mbps Ethernet
+product 3COM 3C574 0x0574 3Com 3c574-TX 10/100Mbps Ethernet
+product 3COM 3CXEM556 0x0035 3Com/Megahertz 3CXEM556 Ethernet/Modem
+
+/* Compex Products */
+product COMPEX LINKPORT_ENET_B 0x0100 Compex Linkport ENET-B Ethernet
+
+/* Dayna Products */
+product DAYNA COMMUNICARD_E_1 0x002d Dayna CommuniCard E
+product DAYNA COMMUNICARD_E_2 0x002f Dayna CommuniCard E
+
+/* DIGITAL Products */
+product DIGITAL MOBILE_MEDIA_CDROM 0x0d00 Digital Mobile Media CD-ROM
+
+/* Fujutsu Products */
+product FUJITSU SCSI600 0x0401 Fujitsu SCSI 600 Interface
+
+/* Motorola Products */
+product MOTOROLA POWER144 0x0105 Motorola Power 14.4 Modem
+product MOTOROLA PM100C 0x0302 Motorola Personal Messenger 100C CDPD Modem
+
+/* IBM Products */
+product IBM INFOMOVER 0x0002 National Semiconductor InfoMover
+product IBM HOME_AND_AWAY 0x002e IBM Home and Away Modem
+product IBM WIRELESS_LAN_ENTRY 0x0032 Wireless LAN Entry
+product IBM PORTABLE_CDROM_DRIVE 0x002d PCMCIA Portable CD-ROM Drive
+
+/* I-O DATA */
+product IODATA PCLAT 0x2216 I-O DATA PCLA/T
+
+/* Linksys corporation */
+product LINKSYS ECARD_1 0x0265 Linksys EthernetCard or D-Link DE-650
+product LINKSYS COMBO_ECARD 0xc1ab Linksys Combo EthernetCard
+product LINKSYS TRUST_COMBO_ECARD 0x021b Trust (Linksys) Combo EthernetCard
+
+/* Megahertz Products */
+product MEGAHERTZ XJ4288 0x0023 Megahertz XJ4288 Modem
+product MEGAHERTZ XJ5560 0x0034 Megahertz X-JACK 56kbps Modem
+product MEGAHERTZ2 XJACK 0x0103 Megahertz X-JACK Ethernet
+product MEGAHERTZ XJEM3336 0x0006 Megahertz X-JACK Ethernet Modem
+
+/* US Robotics Products */
+product USROBOTICS WORLDPORT144 0x3330 US Robotics WorldPort 14.4 Modem
+
+/* Sandisk Products */
+product SANDISK SDCFB 0x0401 Sandisk CompactFlash Card
+
+/* Simple Technology Products */
+product SIMPLETECH COMMUNICATOR288 0x0100 Simple Technology 28.8 Communicator
+
+/* Socket Communications Products */
+product SOCKET PAGECARD 0x0003 Socket Communications PageCard
+product SOCKET DUAL_RS232 0x0006 Socket Communications Dual RS232
+
+/* TDK Products */
+product TDK LAK_CD021BX 0x0200 TDK LAK-CD021BX Ethernet
+product TDK DFL9610 0x0d0a TDK DFL9610 Ethernet & Digital Cellular
+
+/* TDK Vendor ID also used by Xircom! */
+product TDK XIR_CE_10 0x0108 Xircom CreditCard Ethernet
+product TDK XIR_CEM_10 0x110a Xircom CreditCard Ethernet + Modem
+product TDK XIR_CEM_28 0x110b Xircom CreditCard Ethernet + Modem 28.8
+product TDK XIR_PS_CE2_10 0x010b Xircom CreditCard CE2 Ethernet
+product TDK XIR_CE3_100 0x010a Xircom CreditCard Ethernet 10/100
+product TDK XIR_CNW 0x0802 Xircom CreditCard Netwave
+
+/* NewMedia Products */
+product NEWMEDIA BASICS 0x0019 NewMedia BASICS Ethernet
+
+/* Standard Microsystems Corporation Products */
+product SMC 8016 0x0105 SMC 8016 EtherCard
+
+/* RATOC System Inc. Products */
+product RATOC REX_R280 0x1 RATOC REX-R280
+
+/* Cards we know only by their cis */
+vendor PREMAX -1 Premax
+vendor PLANET -1 Planet
+vendor DLINK -1 D-Link
+vendor RPTI -1 RPTI
+vendor ACCTON -1 ACCTON
+vendor YEDATA -1 Y-E DATA
+vendor DIGITAL -1 Digital Equipment Corporation
+vendor TEAC -1 TEAC
+vendor SVEC -1 SVEC/Hawking Technology
+vendor NAKAGAWAMETAL -1 NAKAGAWA METAL
+
+product MEGAHERTZ XJ2288 { "MEGAHERTZ", "MODEM&spXJ2288", NULL, NULL } Megahertz XJ2288 Modem
+product PREMAX PE200 { "PMX&sp&sp&sp", "PE-200", NULL, NULL } PreMax PE-200
+product PLANET SMARTCOM2000 { "PCMCIA", "UE2212", NULL, NULL } Planet SmartCOM 2000
+product DLINK DE650 { "D-Link", "DE-650", NULL, NULL } D-Link DE-650
+product DLINK DE660 { "D-Link", "DE-660", NULL, NULL } D-Link DE-660
+product RPTI EP401 { "RPTI", "EP401&spEthernet&spNE2000&spCompatible", NULL, NULL } RPTI EP401
+product ACCTON EN2212 { "ACCTON", "EN2212", NULL, NULL } Accton EN2212
+product YEDATA EXTERNAL_FDD { "Y-E&spDATA", "External&spFDD", NULL, NULL } Y-E DATA External FDD
+product DIGITAL DEPCMXX { "DIGITAL", "DEPCM-XX", NULL, NULL } DEC DEPCM-BA
+product TEAC IDECARDII { NULL, "NinjaATA-", NULL, NULL } TEAC IDE Card/II
+product LINKSYS ECARD_2 { "LINKSYS", "E-CARD", NULL, NULL } Linksys E-Card
+product COREGA PCC_2 { "corega&spK.K.", "corega&spEther&spPCC-T", NULL, NULL } Corega
+product SVEC COMBOCARD { "Ethernet", "Adapter", NULL, NULL } SVEC/Hawking Tech. Combo Card
+product SVEC LANCARD { "SVEC", "FD605&spPCMCIA&spEtherNet&spCard", "V1-1", NULL } SVEC PCMCIA Lan Card
+
+product NAKAGAWAMETAL LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL } NAKAGAWA METAL LNT-10TN NE2000 Compatible Card
+
diff --git a/sys/dev/pccard/pccarddevs.h b/sys/dev/pccard/pccarddevs.h
new file mode 100644
index 0000000..dcbbba5
--- /dev/null
+++ b/sys/dev/pccard/pccarddevs.h
@@ -0,0 +1,300 @@
+/* $FreeBSD$ */
+
+/*
+ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
+ *
+ * generated from:
+ * NetBSD: pcmciadevs,v 1.33 1999/02/19 21:49:43 abs Exp
+ */
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/*
+ * List of known PCMCIA vendors
+ */
+
+#define PCCARD_VENDOR_FUJITSU 0x0004 /* Fujitsu Corporation */
+#define PCCARD_VENDOR_SANDISK 0x0045 /* Sandisk Corporation */
+#define PCCARD_VENDOR_NEWMEDIA 0x0057 /* NewMedia Corporation */
+#define PCCARD_VENDOR_INTEL 0x0089 /* Intel Corporation */
+#define PCCARD_VENDOR_IBM 0x00a4 /* IBM Corporation */
+#define PCCARD_VENDOR_MOTOROLA 0x0109 /* Motorola Corporation */
+#define PCCARD_VENDOR_3COM 0x0101 /* 3Com Corporation */
+#define PCCARD_VENDOR_MEGAHERTZ 0x0102 /* Megahertz Corporation */
+#define PCCARD_VENDOR_SOCKET 0x0104 /* Socket Communications */
+#define PCCARD_VENDOR_TDK 0x0105 /* TDK Corporation */
+#define PCCARD_VENDOR_SMC 0x0108 /* Standard Microsystems Corporation */
+#define PCCARD_VENDOR_USROBOTICS 0x0115 /* US Robotics Corporation */
+#define PCCARD_VENDOR_MEGAHERTZ2 0x0128 /* Megahertz Corporation */
+#define PCCARD_VENDOR_ADAPTEC 0x012f /* Adaptec Corporation */
+#define PCCARD_VENDOR_COMPAQ1 0x0138 /* Compaq Corporation (1) */
+#define PCCARD_VENDOR_LINKSYS 0x0149 /* Linksys Corporation */
+#define PCCARD_VENDOR_SIMPLETECH 0x014d /* Simple Technology */
+#define PCCARD_VENDOR_COMPAQ2 0x0183 /* Compaq Corporation (2) */
+#define PCCARD_VENDOR_DAYNA 0x0194 /* Dayna Corporation */
+#define PCCARD_VENDOR_IODATA 0x01bf /* I-O DATA */
+#define PCCARD_VENDOR_COMPEX 0x8a01 /* Compex Corporation */
+#define PCCARD_VENDOR_COREGA 0xc00f /* Corega K.K. */
+#define PCCARD_VENDOR_HAGIWARASYSCOM 0xc012 /* Hagiwara SYS-COM */
+#define PCCARD_VENDOR_RATOC 0xc015 /* RATOC System Inc. */
+
+/*
+ * List of known products. Grouped by vendor.
+ */
+/* Adaptec Products */
+#define PCCARD_CIS_ADAPTEC_APA1460_1 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_ADAPTEC_APA1460_1 0x0001
+#define PCCARD_STR_ADAPTEC_APA1460_1 "Adaptec APA-1460/A SCSI Host Adapter"
+#define PCCARD_CIS_ADAPTEC_APA1460_2 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_ADAPTEC_APA1460_2 0x0002
+#define PCCARD_STR_ADAPTEC_APA1460_2 "Adaptec APA-1460/B SCSI Host Adapter"
+
+/* 3COM Products */
+#define PCCARD_CIS_3COM_3C562 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_3COM_3C562 0x0562
+#define PCCARD_STR_3COM_3C562 "3Com 3c562 33.6 Modem/10Mbps Ethernet"
+#define PCCARD_CIS_3COM_3C589 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_3COM_3C589 0x0589
+#define PCCARD_STR_3COM_3C589 "3Com 3c589 10Mbps Ethernet"
+#define PCCARD_CIS_3COM_3C574 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_3COM_3C574 0x0574
+#define PCCARD_STR_3COM_3C574 "3Com 3c574-TX 10/100Mbps Ethernet"
+#define PCCARD_CIS_3COM_3CXEM556 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_3COM_3CXEM556 0x0035
+#define PCCARD_STR_3COM_3CXEM556 "3Com/Megahertz 3CXEM556 Ethernet/Modem"
+
+/* Compex Products */
+#define PCCARD_CIS_COMPEX_LINKPORT_ENET_B { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_COMPEX_LINKPORT_ENET_B 0x0100
+#define PCCARD_STR_COMPEX_LINKPORT_ENET_B "Compex Linkport ENET-B Ethernet"
+
+/* Dayna Products */
+#define PCCARD_CIS_DAYNA_COMMUNICARD_E_1 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_DAYNA_COMMUNICARD_E_1 0x002d
+#define PCCARD_STR_DAYNA_COMMUNICARD_E_1 "Dayna CommuniCard E"
+#define PCCARD_CIS_DAYNA_COMMUNICARD_E_2 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_DAYNA_COMMUNICARD_E_2 0x002f
+#define PCCARD_STR_DAYNA_COMMUNICARD_E_2 "Dayna CommuniCard E"
+
+/* DIGITAL Products */
+#define PCCARD_CIS_DIGITAL_MOBILE_MEDIA_CDROM { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_DIGITAL_MOBILE_MEDIA_CDROM 0x0d00
+#define PCCARD_STR_DIGITAL_MOBILE_MEDIA_CDROM "Digital Mobile Media CD-ROM"
+
+/* Fujutsu Products */
+#define PCCARD_CIS_FUJITSU_SCSI600 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_FUJITSU_SCSI600 0x0401
+#define PCCARD_STR_FUJITSU_SCSI600 "Fujitsu SCSI 600 Interface"
+
+/* Motorola Products */
+#define PCCARD_CIS_MOTOROLA_POWER144 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_MOTOROLA_POWER144 0x0105
+#define PCCARD_STR_MOTOROLA_POWER144 "Motorola Power 14.4 Modem"
+#define PCCARD_CIS_MOTOROLA_PM100C { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_MOTOROLA_PM100C 0x0302
+#define PCCARD_STR_MOTOROLA_PM100C "Motorola Personal Messenger 100C CDPD Modem"
+
+/* IBM Products */
+#define PCCARD_CIS_IBM_INFOMOVER { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_IBM_INFOMOVER 0x0002
+#define PCCARD_STR_IBM_INFOMOVER "National Semiconductor InfoMover"
+#define PCCARD_CIS_IBM_HOME_AND_AWAY { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_IBM_HOME_AND_AWAY 0x002e
+#define PCCARD_STR_IBM_HOME_AND_AWAY "IBM Home and Away Modem"
+#define PCCARD_CIS_IBM_WIRELESS_LAN_ENTRY { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_IBM_WIRELESS_LAN_ENTRY 0x0032
+#define PCCARD_STR_IBM_WIRELESS_LAN_ENTRY "Wireless LAN Entry"
+#define PCCARD_CIS_IBM_PORTABLE_CDROM_DRIVE { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_IBM_PORTABLE_CDROM_DRIVE 0x002d
+#define PCCARD_STR_IBM_PORTABLE_CDROM_DRIVE "PCMCIA Portable CD-ROM Drive"
+
+/* I-O DATA */
+#define PCCARD_CIS_IODATA_PCLAT { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_IODATA_PCLAT 0x2216
+#define PCCARD_STR_IODATA_PCLAT "I-O DATA PCLA/T"
+
+/* Linksys corporation */
+#define PCCARD_CIS_LINKSYS_ECARD_1 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_LINKSYS_ECARD_1 0x0265
+#define PCCARD_STR_LINKSYS_ECARD_1 "Linksys EthernetCard or D-Link DE-650"
+#define PCCARD_CIS_LINKSYS_COMBO_ECARD { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_LINKSYS_COMBO_ECARD 0xc1ab
+#define PCCARD_STR_LINKSYS_COMBO_ECARD "Linksys Combo EthernetCard"
+#define PCCARD_CIS_LINKSYS_TRUST_COMBO_ECARD { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_LINKSYS_TRUST_COMBO_ECARD 0x021b
+#define PCCARD_STR_LINKSYS_TRUST_COMBO_ECARD "Trust (Linksys) Combo EthernetCard"
+
+/* Megahertz Products */
+#define PCCARD_CIS_MEGAHERTZ_XJ4288 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_MEGAHERTZ_XJ4288 0x0023
+#define PCCARD_STR_MEGAHERTZ_XJ4288 "Megahertz XJ4288 Modem"
+#define PCCARD_CIS_MEGAHERTZ_XJ5560 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_MEGAHERTZ_XJ5560 0x0034
+#define PCCARD_STR_MEGAHERTZ_XJ5560 "Megahertz X-JACK 56kbps Modem"
+#define PCCARD_CIS_MEGAHERTZ2_XJACK { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_MEGAHERTZ2_XJACK 0x0103
+#define PCCARD_STR_MEGAHERTZ2_XJACK "Megahertz X-JACK Ethernet"
+#define PCCARD_CIS_MEGAHERTZ_XJEM3336 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_MEGAHERTZ_XJEM3336 0x0006
+#define PCCARD_STR_MEGAHERTZ_XJEM3336 "Megahertz X-JACK Ethernet Modem"
+
+/* US Robotics Products */
+#define PCCARD_CIS_USROBOTICS_WORLDPORT144 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_USROBOTICS_WORLDPORT144 0x3330
+#define PCCARD_STR_USROBOTICS_WORLDPORT144 "US Robotics WorldPort 14.4 Modem"
+
+/* Sandisk Products */
+#define PCCARD_CIS_SANDISK_SDCFB { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_SANDISK_SDCFB 0x0401
+#define PCCARD_STR_SANDISK_SDCFB "Sandisk CompactFlash Card"
+
+/* Simple Technology Products */
+#define PCCARD_CIS_SIMPLETECH_COMMUNICATOR288 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_SIMPLETECH_COMMUNICATOR288 0x0100
+#define PCCARD_STR_SIMPLETECH_COMMUNICATOR288 "Simple Technology 28.8 Communicator"
+
+/* Socket Communications Products */
+#define PCCARD_CIS_SOCKET_PAGECARD { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_SOCKET_PAGECARD 0x0003
+#define PCCARD_STR_SOCKET_PAGECARD "Socket Communications PageCard"
+#define PCCARD_CIS_SOCKET_DUAL_RS232 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_SOCKET_DUAL_RS232 0x0006
+#define PCCARD_STR_SOCKET_DUAL_RS232 "Socket Communications Dual RS232"
+
+/* TDK Products */
+#define PCCARD_CIS_TDK_LAK_CD021BX { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_LAK_CD021BX 0x0200
+#define PCCARD_STR_TDK_LAK_CD021BX "TDK LAK-CD021BX Ethernet"
+#define PCCARD_CIS_TDK_DFL9610 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_DFL9610 0x0d0a
+#define PCCARD_STR_TDK_DFL9610 "TDK DFL9610 Ethernet & Digital Cellular"
+
+/* TDK Vendor ID also used by Xircom! */
+#define PCCARD_CIS_TDK_XIR_CE_10 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_XIR_CE_10 0x0108
+#define PCCARD_STR_TDK_XIR_CE_10 "Xircom CreditCard Ethernet"
+#define PCCARD_CIS_TDK_XIR_CEM_10 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_XIR_CEM_10 0x110a
+#define PCCARD_STR_TDK_XIR_CEM_10 "Xircom CreditCard Ethernet + Modem"
+#define PCCARD_CIS_TDK_XIR_CEM_28 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_XIR_CEM_28 0x110b
+#define PCCARD_STR_TDK_XIR_CEM_28 "Xircom CreditCard Ethernet + Modem 28.8"
+#define PCCARD_CIS_TDK_XIR_PS_CE2_10 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_XIR_PS_CE2_10 0x010b
+#define PCCARD_STR_TDK_XIR_PS_CE2_10 "Xircom CreditCard CE2 Ethernet"
+#define PCCARD_CIS_TDK_XIR_CE3_100 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_XIR_CE3_100 0x010a
+#define PCCARD_STR_TDK_XIR_CE3_100 "Xircom CreditCard Ethernet 10/100"
+#define PCCARD_CIS_TDK_XIR_CNW { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_TDK_XIR_CNW 0x0802
+#define PCCARD_STR_TDK_XIR_CNW "Xircom CreditCard Netwave"
+
+/* NewMedia Products */
+#define PCCARD_CIS_NEWMEDIA_BASICS { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_NEWMEDIA_BASICS 0x0019
+#define PCCARD_STR_NEWMEDIA_BASICS "NewMedia BASICS Ethernet"
+
+/* Standard Microsystems Corporation Products */
+#define PCCARD_CIS_SMC_8016 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_SMC_8016 0x0105
+#define PCCARD_STR_SMC_8016 "SMC 8016 EtherCard"
+
+/* RATOC System Inc. Products */
+#define PCCARD_CIS_RATOC_REX_R280 { NULL, NULL, NULL, NULL }
+#define PCCARD_PRODUCT_RATOC_REX_R280 0x1
+#define PCCARD_STR_RATOC_REX_R280 "RATOC REX-R280"
+
+/* Cards we know only by their cis */
+#define PCCARD_VENDOR_PREMAX -1 /* Premax */
+#define PCCARD_VENDOR_PLANET -1 /* Planet */
+#define PCCARD_VENDOR_DLINK -1 /* D-Link */
+#define PCCARD_VENDOR_RPTI -1 /* RPTI */
+#define PCCARD_VENDOR_ACCTON -1 /* ACCTON */
+#define PCCARD_VENDOR_YEDATA -1 /* Y-E DATA */
+#define PCCARD_VENDOR_DIGITAL -1 /* Digital Equipment Corporation */
+#define PCCARD_VENDOR_TEAC -1 /* TEAC */
+#define PCCARD_VENDOR_SVEC -1 /* SVEC/Hawking Technology */
+#define PCCARD_VENDOR_NAKAGAWAMETAL -1 /* NAKAGAWA METAL */
+
+#define PCCARD_CIS_MEGAHERTZ_XJ2288 { "MEGAHERTZ", "MODEM XJ2288", NULL, NULL }
+#define PCCARD_PRODUCT_MEGAHERTZ_XJ2288 -1
+#define PCCARD_STR_MEGAHERTZ_XJ2288 "Megahertz XJ2288 Modem"
+#define PCCARD_CIS_PREMAX_PE200 { "PMX ", "PE-200", NULL, NULL }
+#define PCCARD_PRODUCT_PREMAX_PE200 -1
+#define PCCARD_STR_PREMAX_PE200 "PreMax PE-200"
+#define PCCARD_CIS_PLANET_SMARTCOM2000 { "PCMCIA", "UE2212", NULL, NULL }
+#define PCCARD_PRODUCT_PLANET_SMARTCOM2000 -1
+#define PCCARD_STR_PLANET_SMARTCOM2000 "Planet SmartCOM 2000"
+#define PCCARD_CIS_DLINK_DE650 { "D-Link", "DE-650", NULL, NULL }
+#define PCCARD_PRODUCT_DLINK_DE650 -1
+#define PCCARD_STR_DLINK_DE650 "D-Link DE-650"
+#define PCCARD_CIS_DLINK_DE660 { "D-Link", "DE-660", NULL, NULL }
+#define PCCARD_PRODUCT_DLINK_DE660 -1
+#define PCCARD_STR_DLINK_DE660 "D-Link DE-660"
+#define PCCARD_CIS_RPTI_EP401 { "RPTI", "EP401 Ethernet NE2000 Compatible", NULL, NULL }
+#define PCCARD_PRODUCT_RPTI_EP401 -1
+#define PCCARD_STR_RPTI_EP401 "RPTI EP401"
+#define PCCARD_CIS_ACCTON_EN2212 { "ACCTON", "EN2212", NULL, NULL }
+#define PCCARD_PRODUCT_ACCTON_EN2212 -1
+#define PCCARD_STR_ACCTON_EN2212 "Accton EN2212"
+#define PCCARD_CIS_YEDATA_EXTERNAL_FDD { "Y-E DATA", "External FDD", NULL, NULL }
+#define PCCARD_PRODUCT_YEDATA_EXTERNAL_FDD -1
+#define PCCARD_STR_YEDATA_EXTERNAL_FDD "Y-E DATA External FDD"
+#define PCCARD_CIS_DIGITAL_DEPCMXX { "DIGITAL", "DEPCM-XX", NULL, NULL }
+#define PCCARD_PRODUCT_DIGITAL_DEPCMXX -1
+#define PCCARD_STR_DIGITAL_DEPCMXX "DEC DEPCM-BA"
+#define PCCARD_CIS_TEAC_IDECARDII { NULL, "NinjaATA-", NULL, NULL }
+#define PCCARD_PRODUCT_TEAC_IDECARDII -1
+#define PCCARD_STR_TEAC_IDECARDII "TEAC IDE Card/II"
+#define PCCARD_CIS_LINKSYS_ECARD_2 { "LINKSYS", "E-CARD", NULL, NULL }
+#define PCCARD_PRODUCT_LINKSYS_ECARD_2 -1
+#define PCCARD_STR_LINKSYS_ECARD_2 "Linksys E-Card"
+#define PCCARD_CIS_COREGA_PCC_2 { "corega K.K.", "corega Ether PCC-T", NULL, NULL }
+#define PCCARD_PRODUCT_COREGA_PCC_2 -1
+#define PCCARD_STR_COREGA_PCC_2 "Corega"
+#define PCCARD_CIS_SVEC_COMBOCARD { "Ethernet", "Adapter", NULL, NULL }
+#define PCCARD_PRODUCT_SVEC_COMBOCARD -1
+#define PCCARD_STR_SVEC_COMBOCARD "SVEC/Hawking Tech. Combo Card"
+#define PCCARD_CIS_SVEC_LANCARD { "SVEC", "FD605 PCMCIA EtherNet Card", "V1-1", NULL }
+#define PCCARD_PRODUCT_SVEC_LANCARD -1
+#define PCCARD_STR_SVEC_LANCARD "SVEC PCMCIA Lan Card"
+
+#define PCCARD_CIS_NAKAGAWAMETAL_LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL }
+#define PCCARD_PRODUCT_NAKAGAWAMETAL_LNT10TN -1
+#define PCCARD_STR_NAKAGAWAMETAL_LNT10TN "NAKAGAWA METAL LNT-10TN NE2000 Compatible Card"
+
diff --git a/sys/dev/pccard/pccarddevs_data.h b/sys/dev/pccard/pccarddevs_data.h
new file mode 100644
index 0000000..a05cb21
--- /dev/null
+++ b/sys/dev/pccard/pccarddevs_data.h
@@ -0,0 +1,679 @@
+/* $FreeBSD$ */
+
+/*
+ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
+ *
+ * generated from:
+ * NetBSD: pcmciadevs,v 1.33 1999/02/19 21:49:43 abs Exp
+ */
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+struct pccard_knowndev pccard_knowndevs[] = {
+ {
+ PCCARD_VENDOR_ADAPTEC, PCCARD_PRODUCT_ADAPTEC_APA1460_1,
+ PCCARD_CIS_ADAPTEC_APA1460_1,
+ 0,
+ "Adaptec Corporation",
+ "Adaptec APA-1460/A SCSI Host Adapter" },
+ },
+ {
+ PCCARD_VENDOR_ADAPTEC, PCCARD_PRODUCT_ADAPTEC_APA1460_2,
+ PCCARD_CIS_ADAPTEC_APA1460_2,
+ 0,
+ "Adaptec Corporation",
+ "Adaptec APA-1460/B SCSI Host Adapter" },
+ },
+ {
+ PCCARD_VENDOR_3COM, PCCARD_PRODUCT_3COM_3C562,
+ PCCARD_CIS_3COM_3C562,
+ 0,
+ "3Com Corporation",
+ "3Com 3c562 33.6 Modem/10Mbps Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_3COM, PCCARD_PRODUCT_3COM_3C589,
+ PCCARD_CIS_3COM_3C589,
+ 0,
+ "3Com Corporation",
+ "3Com 3c589 10Mbps Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_3COM, PCCARD_PRODUCT_3COM_3C574,
+ PCCARD_CIS_3COM_3C574,
+ 0,
+ "3Com Corporation",
+ "3Com 3c574-TX 10/100Mbps Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_3COM, PCCARD_PRODUCT_3COM_3CXEM556,
+ PCCARD_CIS_3COM_3CXEM556,
+ 0,
+ "3Com Corporation",
+ "3Com/Megahertz 3CXEM556 Ethernet/Modem" },
+ },
+ {
+ PCCARD_VENDOR_COMPEX, PCCARD_PRODUCT_COMPEX_LINKPORT_ENET_B,
+ PCCARD_CIS_COMPEX_LINKPORT_ENET_B,
+ 0,
+ "Compex Corporation",
+ "Compex Linkport ENET-B Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_DAYNA, PCCARD_PRODUCT_DAYNA_COMMUNICARD_E_1,
+ PCCARD_CIS_DAYNA_COMMUNICARD_E_1,
+ 0,
+ "Dayna Corporation",
+ "Dayna CommuniCard E" },
+ },
+ {
+ PCCARD_VENDOR_DAYNA, PCCARD_PRODUCT_DAYNA_COMMUNICARD_E_2,
+ PCCARD_CIS_DAYNA_COMMUNICARD_E_2,
+ 0,
+ "Dayna Corporation",
+ "Dayna CommuniCard E" },
+ },
+ {
+ PCCARD_VENDOR_DIGITAL, PCCARD_PRODUCT_DIGITAL_MOBILE_MEDIA_CDROM,
+ PCCARD_CIS_DIGITAL_MOBILE_MEDIA_CDROM,
+ 0,
+ "Digital Equipment Corporation",
+ "Digital Mobile Media CD-ROM" },
+ },
+ {
+ PCCARD_VENDOR_FUJITSU, PCCARD_PRODUCT_FUJITSU_SCSI600,
+ PCCARD_CIS_FUJITSU_SCSI600,
+ 0,
+ "Fujitsu Corporation",
+ "Fujitsu SCSI 600 Interface" },
+ },
+ {
+ PCCARD_VENDOR_MOTOROLA, PCCARD_PRODUCT_MOTOROLA_POWER144,
+ PCCARD_CIS_MOTOROLA_POWER144,
+ 0,
+ "Motorola Corporation",
+ "Motorola Power 14.4 Modem" },
+ },
+ {
+ PCCARD_VENDOR_MOTOROLA, PCCARD_PRODUCT_MOTOROLA_PM100C,
+ PCCARD_CIS_MOTOROLA_PM100C,
+ 0,
+ "Motorola Corporation",
+ "Motorola Personal Messenger 100C CDPD Modem" },
+ },
+ {
+ PCCARD_VENDOR_IBM, PCCARD_PRODUCT_IBM_INFOMOVER,
+ PCCARD_CIS_IBM_INFOMOVER,
+ 0,
+ "IBM Corporation",
+ "National Semiconductor InfoMover" },
+ },
+ {
+ PCCARD_VENDOR_IBM, PCCARD_PRODUCT_IBM_HOME_AND_AWAY,
+ PCCARD_CIS_IBM_HOME_AND_AWAY,
+ 0,
+ "IBM Corporation",
+ "IBM Home and Away Modem" },
+ },
+ {
+ PCCARD_VENDOR_IBM, PCCARD_PRODUCT_IBM_WIRELESS_LAN_ENTRY,
+ PCCARD_CIS_IBM_WIRELESS_LAN_ENTRY,
+ 0,
+ "IBM Corporation",
+ "Wireless LAN Entry" },
+ },
+ {
+ PCCARD_VENDOR_IBM, PCCARD_PRODUCT_IBM_PORTABLE_CDROM_DRIVE,
+ PCCARD_CIS_IBM_PORTABLE_CDROM_DRIVE,
+ 0,
+ "IBM Corporation",
+ "PCMCIA Portable CD-ROM Drive" },
+ },
+ {
+ PCCARD_VENDOR_IODATA, PCCARD_PRODUCT_IODATA_PCLAT,
+ PCCARD_CIS_IODATA_PCLAT,
+ 0,
+ "I-O DATA",
+ "I-O DATA PCLA/T" },
+ },
+ {
+ PCCARD_VENDOR_LINKSYS, PCCARD_PRODUCT_LINKSYS_ECARD_1,
+ PCCARD_CIS_LINKSYS_ECARD_1,
+ 0,
+ "Linksys Corporation",
+ "Linksys EthernetCard or D-Link DE-650" },
+ },
+ {
+ PCCARD_VENDOR_LINKSYS, PCCARD_PRODUCT_LINKSYS_COMBO_ECARD,
+ PCCARD_CIS_LINKSYS_COMBO_ECARD,
+ 0,
+ "Linksys Corporation",
+ "Linksys Combo EthernetCard" },
+ },
+ {
+ PCCARD_VENDOR_LINKSYS, PCCARD_PRODUCT_LINKSYS_TRUST_COMBO_ECARD,
+ PCCARD_CIS_LINKSYS_TRUST_COMBO_ECARD,
+ 0,
+ "Linksys Corporation",
+ "Trust (Linksys) Combo EthernetCard" },
+ },
+ {
+ PCCARD_VENDOR_MEGAHERTZ, PCCARD_PRODUCT_MEGAHERTZ_XJ4288,
+ PCCARD_CIS_MEGAHERTZ_XJ4288,
+ 0,
+ "Megahertz Corporation",
+ "Megahertz XJ4288 Modem" },
+ },
+ {
+ PCCARD_VENDOR_MEGAHERTZ, PCCARD_PRODUCT_MEGAHERTZ_XJ5560,
+ PCCARD_CIS_MEGAHERTZ_XJ5560,
+ 0,
+ "Megahertz Corporation",
+ "Megahertz X-JACK 56kbps Modem" },
+ },
+ {
+ PCCARD_VENDOR_MEGAHERTZ2, PCCARD_PRODUCT_MEGAHERTZ2_XJACK,
+ PCCARD_CIS_MEGAHERTZ2_XJACK,
+ 0,
+ "Megahertz Corporation",
+ "Megahertz X-JACK Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_MEGAHERTZ, PCCARD_PRODUCT_MEGAHERTZ_XJEM3336,
+ PCCARD_CIS_MEGAHERTZ_XJEM3336,
+ 0,
+ "Megahertz Corporation",
+ "Megahertz X-JACK Ethernet Modem" },
+ },
+ {
+ PCCARD_VENDOR_USROBOTICS, PCCARD_PRODUCT_USROBOTICS_WORLDPORT144,
+ PCCARD_CIS_USROBOTICS_WORLDPORT144,
+ 0,
+ "US Robotics Corporation",
+ "US Robotics WorldPort 14.4 Modem" },
+ },
+ {
+ PCCARD_VENDOR_SANDISK, PCCARD_PRODUCT_SANDISK_SDCFB,
+ PCCARD_CIS_SANDISK_SDCFB,
+ 0,
+ "Sandisk Corporation",
+ "Sandisk CompactFlash Card" },
+ },
+ {
+ PCCARD_VENDOR_SIMPLETECH, PCCARD_PRODUCT_SIMPLETECH_COMMUNICATOR288,
+ PCCARD_CIS_SIMPLETECH_COMMUNICATOR288,
+ 0,
+ "Simple Technology",
+ "Simple Technology 28.8 Communicator" },
+ },
+ {
+ PCCARD_VENDOR_SOCKET, PCCARD_PRODUCT_SOCKET_PAGECARD,
+ PCCARD_CIS_SOCKET_PAGECARD,
+ 0,
+ "Socket Communications",
+ "Socket Communications PageCard" },
+ },
+ {
+ PCCARD_VENDOR_SOCKET, PCCARD_PRODUCT_SOCKET_DUAL_RS232,
+ PCCARD_CIS_SOCKET_DUAL_RS232,
+ 0,
+ "Socket Communications",
+ "Socket Communications Dual RS232" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_LAK_CD021BX,
+ PCCARD_CIS_TDK_LAK_CD021BX,
+ 0,
+ "TDK Corporation",
+ "TDK LAK-CD021BX Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_DFL9610,
+ PCCARD_CIS_TDK_DFL9610,
+ 0,
+ "TDK Corporation",
+ "TDK DFL9610 Ethernet & Digital Cellular" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_XIR_CE_10,
+ PCCARD_CIS_TDK_XIR_CE_10,
+ 0,
+ "TDK Corporation",
+ "Xircom CreditCard Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_XIR_CEM_10,
+ PCCARD_CIS_TDK_XIR_CEM_10,
+ 0,
+ "TDK Corporation",
+ "Xircom CreditCard Ethernet + Modem" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_XIR_CEM_28,
+ PCCARD_CIS_TDK_XIR_CEM_28,
+ 0,
+ "TDK Corporation",
+ "Xircom CreditCard Ethernet + Modem 28.8" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_XIR_PS_CE2_10,
+ PCCARD_CIS_TDK_XIR_PS_CE2_10,
+ 0,
+ "TDK Corporation",
+ "Xircom CreditCard CE2 Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_XIR_CE3_100,
+ PCCARD_CIS_TDK_XIR_CE3_100,
+ 0,
+ "TDK Corporation",
+ "Xircom CreditCard Ethernet 10/100" },
+ },
+ {
+ PCCARD_VENDOR_TDK, PCCARD_PRODUCT_TDK_XIR_CNW,
+ PCCARD_CIS_TDK_XIR_CNW,
+ 0,
+ "TDK Corporation",
+ "Xircom CreditCard Netwave" },
+ },
+ {
+ PCCARD_VENDOR_NEWMEDIA, PCCARD_PRODUCT_NEWMEDIA_BASICS,
+ PCCARD_CIS_NEWMEDIA_BASICS,
+ 0,
+ "NewMedia Corporation",
+ "NewMedia BASICS Ethernet" },
+ },
+ {
+ PCCARD_VENDOR_SMC, PCCARD_PRODUCT_SMC_8016,
+ PCCARD_CIS_SMC_8016,
+ 0,
+ "Standard Microsystems Corporation",
+ "SMC 8016 EtherCard" },
+ },
+ {
+ PCCARD_VENDOR_RATOC, PCCARD_PRODUCT_RATOC_REX_R280,
+ PCCARD_CIS_RATOC_REX_R280,
+ 0,
+ "RATOC System Inc.",
+ "RATOC REX-R280" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_MEGAHERTZ_XJ2288,
+ PCCARD_CIS_MEGAHERTZ_XJ2288,
+ 0,
+ "Megahertz Corporation",
+ "Megahertz XJ2288 Modem" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_PREMAX_PE200,
+ PCCARD_CIS_PREMAX_PE200,
+ 0,
+ "Premax",
+ "PreMax PE-200" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_PLANET_SMARTCOM2000,
+ PCCARD_CIS_PLANET_SMARTCOM2000,
+ 0,
+ "Planet",
+ "Planet SmartCOM 2000" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_DLINK_DE650,
+ PCCARD_CIS_DLINK_DE650,
+ 0,
+ "D-Link",
+ "D-Link DE-650" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_DLINK_DE660,
+ PCCARD_CIS_DLINK_DE660,
+ 0,
+ "D-Link",
+ "D-Link DE-660" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_RPTI_EP401,
+ PCCARD_CIS_RPTI_EP401,
+ 0,
+ "RPTI",
+ "RPTI EP401" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_ACCTON_EN2212,
+ PCCARD_CIS_ACCTON_EN2212,
+ 0,
+ "ACCTON",
+ "Accton EN2212" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_YEDATA_EXTERNAL_FDD,
+ PCCARD_CIS_YEDATA_EXTERNAL_FDD,
+ 0,
+ "Y-E DATA",
+ "Y-E DATA External FDD" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_DIGITAL_DEPCMXX,
+ PCCARD_CIS_DIGITAL_DEPCMXX,
+ 0,
+ "Digital Equipment Corporation",
+ "DEC DEPCM-BA" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_TEAC_IDECARDII,
+ PCCARD_CIS_TEAC_IDECARDII,
+ 0,
+ "TEAC",
+ "TEAC IDE Card/II" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_LINKSYS_ECARD_2,
+ PCCARD_CIS_LINKSYS_ECARD_2,
+ 0,
+ "Linksys Corporation",
+ "Linksys E-Card" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_COREGA_PCC_2,
+ PCCARD_CIS_COREGA_PCC_2,
+ 0,
+ "Corega K.K.",
+ "Corega" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_SVEC_COMBOCARD,
+ PCCARD_CIS_SVEC_COMBOCARD,
+ 0,
+ "SVEC/Hawking Technology",
+ "SVEC/Hawking Tech. Combo Card" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_SVEC_LANCARD,
+ PCCARD_CIS_SVEC_LANCARD,
+ 0,
+ "SVEC/Hawking Technology",
+ "SVEC PCMCIA Lan Card" },
+ },
+ {
+ PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_NAKAGAWAMETAL_LNT10TN,
+ PCCARD_CIS_NAKAGAWAMETAL_LNT10TN,
+ 0,
+ "NAKAGAWA METAL",
+ "NAKAGAWA METAL LNT-10TN NE2000 Compatible Card" },
+ },
+ {
+ PCCARD_VENDOR_FUJITSU, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Fujitsu Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_SANDISK, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Sandisk Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_NEWMEDIA, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "NewMedia Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_INTEL, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Intel Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_IBM, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "IBM Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_MOTOROLA, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Motorola Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_3COM, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "3Com Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_MEGAHERTZ, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Megahertz Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_SOCKET, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Socket Communications",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_TDK, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "TDK Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_SMC, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Standard Microsystems Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_USROBOTICS, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "US Robotics Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_MEGAHERTZ2, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Megahertz Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_ADAPTEC, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Adaptec Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_COMPAQ1, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Compaq Corporation (1)",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_LINKSYS, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Linksys Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_SIMPLETECH, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Simple Technology",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_COMPAQ2, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Compaq Corporation (2)",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_DAYNA, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Dayna Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_IODATA, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "I-O DATA",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_COMPEX, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Compex Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_COREGA, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Corega K.K.",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_HAGIWARASYSCOM, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Hagiwara SYS-COM",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_RATOC, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "RATOC System Inc.",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_PREMAX, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Premax",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_PLANET, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Planet",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_DLINK, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "D-Link",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_RPTI, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "RPTI",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_ACCTON, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "ACCTON",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_YEDATA, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Y-E DATA",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_DIGITAL, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "Digital Equipment Corporation",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_TEAC, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "TEAC",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_SVEC, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "SVEC/Hawking Technology",
+ NULL,
+ },
+ {
+ PCCARD_VENDOR_NAKAGAWAMETAL, 0,
+ PCCARD_KNOWNDEV_NOPROD,
+ PCCARD_CIS_INVALID,
+ "NAKAGAWA METAL",
+ NULL,
+ },
+ { 0, 0, { NULL, NULL, NULL, NULL }, 0, NULL, NULL, }
+};
diff --git a/sys/dev/pccard/pccardreg.h b/sys/dev/pccard/pccardreg.h
new file mode 100644
index 0000000..a82417a
--- /dev/null
+++ b/sys/dev/pccard/pccardreg.h
@@ -0,0 +1,249 @@
+/* $NetBSD: pcmciareg.h,v 1.7 1998/10/29 09:45:52 enami Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (c) 1997 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.
+ */
+
+/* most of this is from the PCCARD PC Card Standard, Release 2.1 */
+
+/* Note: the weird indenting here is to make the constants more
+ readable. Please don't normalize it. --marc */
+
+/*
+ * CIS Tuples */
+
+/* Layer 1 Basic Compatibility Tuples */
+#define PCCARD_CISTPL_NULL 0x00
+#define PCCARD_CISTPL_DEVICE 0x01
+#define PCCARD_DTYPE_MASK 0xF0
+#define PCCARD_DTYPE_NULL 0x00
+#define PCCARD_DTYPE_ROM 0x10
+#define PCCARD_DTYPE_OTPROM 0x20
+#define PCCARD_DTYPE_EPROM 0x30
+#define PCCARD_DTYPE_EEPROM 0x40
+#define PCCARD_DTYPE_FLASH 0x50
+#define PCCARD_DTYPE_SRAM 0x60
+#define PCCARD_DTYPE_DRAM 0x70
+#define PCCARD_DTYPE_FUNCSPEC 0xD0
+#define PCCARD_DTYPE_EXTEND 0xE0
+#define PCCARD_DSPEED_MASK 0x07
+#define PCCARD_DSPEED_NULL 0x00
+#define PCCARD_DSPEED_250NS 0x01
+#define PCCARD_DSPEED_200NS 0x02
+#define PCCARD_DSPEED_150NS 0x03
+#define PCCARD_DSPEED_100NS 0x04
+#define PCCARD_DSPEED_EXT 0x07
+
+/*
+ * the 2.1 docs have 0x02-0x07 as reserved, but the linux drivers list the
+ * follwing tuple code values. I have at least one card (3com 3c562
+ * lan+modem) which has a code 0x06 tuple, so I'm going to assume that these
+ * are for real
+ */
+
+#define PCCARD_CISTPL_LONGLINK_CB 0x02
+#define PCCARD_CISTPL_INDIRECT 0x03
+#define PCCARD_CISTPL_CONFIG_CB 0x04
+#define PCCARD_CISTPL_CFTABLE_ENTRY_CB 0x05
+#define PCCARD_CISTPL_LONGLINK_MFC 0x06
+#define PCCARD_MFC_MEM_ATTR 0x00
+#define PCCARD_MFC_MEM_COMMON 0x01
+#define PCCARD_CISTPL_BAR 0x07
+#define PCCARD_CISTPL_PWR_MGMNT 0x08
+
+#define PCCARD_CISTPL_CHECKSUM 0x10
+#define PCCARD_CISTPL_LONGLINK_A 0x11
+#define PCCARD_CISTPL_LONGLINK_C 0x12
+#define PCCARD_CISTPL_LINKTARGET 0x13
+#define PCCARD_CISTPL_NO_LINK 0x14
+#define PCCARD_CISTPL_VERS_1 0x15
+#define PCCARD_CISTPL_ALTSTR 0x16
+#define PCCARD_CISTPL_DEVICE_A 0x17
+#define PCCARD_CISTPL_JEDEC_C 0x18
+#define PCCARD_CISTPL_JEDEC_A 0x19
+#define PCCARD_CISTPL_CONFIG 0x1A
+#define PCCARD_TPCC_RASZ_MASK 0x03
+#define PCCARD_TPCC_RASZ_SHIFT 0
+#define PCCARD_TPCC_RMSZ_MASK 0x3C
+#define PCCARD_TPCC_RMSZ_SHIFT 2
+#define PCCARD_TPCC_RFSZ_MASK 0xC0
+#define PCCARD_TPCC_RFSZ_SHIFT 6
+#define PCCARD_CISTPL_CFTABLE_ENTRY 0x1B
+#define PCCARD_TPCE_INDX_INTFACE 0x80
+#define PCCARD_TPCE_INDX_DEFAULT 0x40
+#define PCCARD_TPCE_INDX_NUM_MASK 0x3F
+#define PCCARD_TPCE_IF_MWAIT 0x80
+#define PCCARD_TPCE_IF_RDYBSY 0x40
+#define PCCARD_TPCE_IF_WP 0x20
+#define PCCARD_TPCE_IF_BVD 0x10
+#define PCCARD_TPCE_IF_IFTYPE 0x0F
+#define PCCARD_IFTYPE_MEMORY 0
+#define PCCARD_IFTYPE_IO 1
+#define PCCARD_TPCE_FS_MISC 0x80
+#define PCCARD_TPCE_FS_MEMSPACE_MASK 0x60
+#define PCCARD_TPCE_FS_MEMSPACE_NONE 0x00
+#define PCCARD_TPCE_FS_MEMSPACE_LENGTH 0x20
+#define PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR 0x40
+#define PCCARD_TPCE_FS_MEMSPACE_TABLE 0x60
+#define PCCARD_TPCE_FS_IRQ 0x10
+#define PCCARD_TPCE_FS_IOSPACE 0x08
+#define PCCARD_TPCE_FS_TIMING 0x04
+#define PCCARD_TPCE_FS_POWER_MASK 0x03
+#define PCCARD_TPCE_FS_POWER_NONE 0x00
+#define PCCARD_TPCE_FS_POWER_VCC 0x01
+#define PCCARD_TPCE_FS_POWER_VCCVPP1 0x02
+#define PCCARD_TPCE_FS_POWER_VCCVPP1VPP2 0x03
+#define PCCARD_TPCE_TD_RESERVED_MASK 0xE0
+#define PCCARD_TPCE_TD_RDYBSY_MASK 0x1C
+#define PCCARD_TPCE_TD_WAIT_MASK 0x03
+#define PCCARD_TPCE_IO_HASRANGE 0x80
+#define PCCARD_TPCE_IO_BUSWIDTH_16BIT 0x40
+#define PCCARD_TPCE_IO_BUSWIDTH_8BIT 0x20
+#define PCCARD_TPCE_IO_IOADDRLINES_MASK 0x1F
+#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK 0xC0
+#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_NONE 0x00
+#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE 0x40
+#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO 0x80
+#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR 0xC0
+#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK 0x30
+#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_NONE 0x00
+#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE 0x10
+#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO 0x20
+#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR 0x30
+#define PCCARD_TPCE_IO_RANGE_COUNT 0x0F
+#define PCCARD_TPCE_IR_SHARE 0x80
+#define PCCARD_TPCE_IR_PULSE 0x40
+#define PCCARD_TPCE_IR_LEVEL 0x20
+#define PCCARD_TPCE_IR_HASMASK 0x10
+#define PCCARD_TPCE_IR_IRQ 0x0F
+#define PCCARD_TPCE_MS_HOSTADDR 0x80
+#define PCCARD_TPCE_MS_CARDADDR_SIZE_MASK 0x60
+#define PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT 5
+#define PCCARD_TPCE_MS_LENGTH_SIZE_MASK 0x18
+#define PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT 3
+#define PCCARD_TPCE_MS_COUNT 0x07
+#define PCCARD_TPCE_MI_EXT 0x80
+#define PCCARD_TPCE_MI_RESERVED 0x40
+#define PCCARD_TPCE_MI_PWRDOWN 0x20
+#define PCCARD_TPCE_MI_READONLY 0x10
+#define PCCARD_TPCE_MI_AUDIO 0x08
+#define PCCARD_TPCE_MI_MAXTWINS 0x07
+#define PCCARD_CISTPL_DEVICE_OC 0x1C
+#define PCCARD_CISTPL_DEVICE_OA 0x1D
+#define PCCARD_CISTPL_DEVICE_GEO 0x1E
+#define PCCARD_CISTPL_DEVICE_GEO_A 0x1F
+#define PCCARD_CISTPL_MANFID 0x20
+#define PCCARD_CISTPL_FUNCID 0x21
+#define PCCARD_FUNCTION_UNSPEC -1
+#define PCCARD_FUNCTION_MULTIFUNCTION 0
+#define PCCARD_FUNCTION_MEMORY 1
+#define PCCARD_FUNCTION_SERIAL 2
+#define PCCARD_FUNCTION_PARALLEL 3
+#define PCCARD_FUNCTION_DISK 4
+#define PCCARD_FUNCTION_VIDEO 5
+#define PCCARD_FUNCTION_NETWORK 6
+#define PCCARD_FUNCTION_AIMS 7
+#define PCCARD_FUNCTION_SCSI 8
+#define PCCARD_FUNCTION_SECURITY 9
+#define PCCARD_FUNCTION_INSTRUMENT 10
+#define PCCARD_CISTPL_FUNCE 0x22
+#define PCCARD_TPLFE_TYPE_LAN_TECH 0x01
+#define PCCARD_TPLFE_TYPE_LAN_SPEED 0x02
+#define PCCARD_TPLFE_TYPE_LAN_MEDIA 0x03
+#define PCCARD_TPLFE_TYPE_LAN_NID 0x04
+#define PCCARD_TPLFE_TYPE_LAN_CONN 0x05
+#define PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE 0x01
+#define PCCARD_TPLFE_DDI_PCCARD_ATA 0x01
+#define PCCARD_CISTPL_END 0xFF
+
+/* Layer 2 Data Recording Format Tuples */
+
+#define PCCARD_CISTPL_SWIL 0x23
+/* #define PCCARD_CISTPL_RESERVED 0x24-0x3F */
+#define PCCARD_CISTPL_VERS_2 0x40
+#define PCCARD_CISTPL_FORMAT 0x41
+#define PCCARD_CISTPL_GEOMETRY 0x42
+#define PCCARD_CISTPL_BYTEORDER 0x43
+#define PCCARD_CISTPL_DATE 0x44
+#define PCCARD_CISTPL_BATTERY 0x45
+#define PCCARD_CISTPL_FORAMT_A 0x47
+
+/* Layer 3 Data Organization Tuples */
+
+#define PCCARD_CISTPL_ORG 0x46
+/* #define PCCARD_CISTPL_RESERVED 0x47-0x7F */
+
+/* Layer 4 System-Specific Standard Tuples */
+
+/* #define PCCARD_CISTPL_RESERVED 0x80-0x8F */
+#define PCCARD_CISTPL_SPCL 0x90
+/* #define PCCARD_CISTPL_RESERVED 0x90-0xFE */
+
+/*
+ * Card Configuration Registers
+ */
+
+#define PCCARD_CCR_OPTION 0x00
+#define PCCARD_CCR_OPTION_SRESET 0x80
+#define PCCARD_CCR_OPTION_LEVIREQ 0x40
+#define PCCARD_CCR_OPTION_CFINDEX 0x3F
+#define PCCARD_CCR_OPTION_IREQ_ENABLE 0x04
+#define PCCARD_CCR_OPTION_ADDR_DECODE 0x02
+#define PCCARD_CCR_OPTION_FUNC_ENABLE 0x01
+#define PCCARD_CCR_STATUS 0x02
+#define PCCARD_CCR_STATUS_PINCHANGED 0x80
+#define PCCARD_CCR_STATUS_SIGCHG 0x40
+#define PCCARD_CCR_STATUS_IOIS8 0x20
+#define PCCARD_CCR_STATUS_RESERVED1 0x10
+#define PCCARD_CCR_STATUS_AUDIO 0x08
+#define PCCARD_CCR_STATUS_PWRDWN 0x04
+#define PCCARD_CCR_STATUS_INTR 0x02
+#define PCCARD_CCR_STATUS_INTRACK 0x01
+#define PCCARD_CCR_PIN 0x04
+#define PCCARD_CCR_PIN_CBVD1 0x80
+#define PCCARD_CCR_PIN_CBVD2 0x40
+#define PCCARD_CCR_PIN_CRDYBSY 0x20
+#define PCCARD_CCR_PIN_CWPROT 0x10
+#define PCCARD_CCR_PIN_RBVD1 0x08
+#define PCCARD_CCR_PIN_RBVD2 0x04
+#define PCCARD_CCR_PIN_RRDYBSY 0x02
+#define PCCARD_CCR_PIN_RWPROT 0x01
+#define PCCARD_CCR_SOCKETCOPY 0x06
+#define PCCARD_CCR_SOCKETCOPY_RESERVED 0x80
+#define PCCARD_CCR_SOCKETCOPY_COPY_MASK 0x70
+#define PCCARD_CCR_SOCKETCOPY_COPY_SHIFT 4
+#define PCCARD_CCR_SOCKETCOPY_SOCKET_MASK 0x0F
+#define PCCARD_CCR_EXTSTATUS 0x08
+#define PCCARD_CCR_IOBASE0 0x0A
+#define PCCARD_CCR_IOBASE1 0x0C
+#define PCCARD_CCR_IOBASE2 0x0E
+#define PCCARD_CCR_IOBASE3 0x10
+#define PCCARD_CCR_IOSIZE 0x12
+
+#define PCCARD_CCR_SIZE 0x14
diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h
new file mode 100644
index 0000000..365fc79
--- /dev/null
+++ b/sys/dev/pccard/pccardvar.h
@@ -0,0 +1,290 @@
+/* $NetBSD: pcmciavar.h,v 1.9 1998/12/29 09:00:28 marc Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Copyright (c) 1997 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 <sys/types.h>
+#include <sys/queue.h>
+
+#include <machine/bus.h>
+
+#include <dev/pccard/pccardchip.h>
+
+extern int pccard_verbose;
+
+/*
+ * Contains information about mapped/allocated i/o spaces.
+ */
+struct pccard_io_handle {
+ bus_space_tag_t iot; /* bus space tag (from chipset) */
+ bus_space_handle_t ioh; /* mapped space handle */
+ bus_addr_t addr; /* resulting address in bus space */
+ bus_size_t size; /* size of i/o space */
+ int flags; /* misc. information */
+};
+
+#define PCCARD_IO_ALLOCATED 0x01 /* i/o space was allocated */
+
+/*
+ * Contains information about allocated memory space.
+ */
+struct pccard_mem_handle {
+ bus_space_tag_t memt; /* bus space tag (from chipset) */
+ bus_space_handle_t memh; /* mapped space handle */
+ bus_addr_t addr; /* resulting address in bus space */
+ bus_size_t size; /* size of mem space */
+ pccard_mem_handle_t mhandle; /* opaque memory handle */
+ bus_size_t realsize; /* how much we really allocated */
+};
+
+/* pccard itself */
+
+#define PCCARD_CFE_MWAIT_REQUIRED 0x0001
+#define PCCARD_CFE_RDYBSY_ACTIVE 0x0002
+#define PCCARD_CFE_WP_ACTIVE 0x0004
+#define PCCARD_CFE_BVD_ACTIVE 0x0008
+#define PCCARD_CFE_IO8 0x0010
+#define PCCARD_CFE_IO16 0x0020
+#define PCCARD_CFE_IRQSHARE 0x0040
+#define PCCARD_CFE_IRQPULSE 0x0080
+#define PCCARD_CFE_IRQLEVEL 0x0100
+#define PCCARD_CFE_POWERDOWN 0x0200
+#define PCCARD_CFE_READONLY 0x0400
+#define PCCARD_CFE_AUDIO 0x0800
+
+struct pccard_config_entry {
+ int number;
+ u_int32_t flags;
+ int iftype;
+ int num_iospace;
+
+ /*
+ * The card will only decode this mask in any case, so we can
+ * do dynamic allocation with this in mind, in case the suggestions
+ * below are no good.
+ */
+ u_long iomask;
+ struct {
+ u_long length;
+ u_long start;
+ } iospace[4]; /* XXX this could be as high as 16 */
+ u_int16_t irqmask;
+ int num_memspace;
+ struct {
+ u_long length;
+ u_long cardaddr;
+ u_long hostaddr;
+ } memspace[2]; /* XXX this could be as high as 8 */
+ int maxtwins;
+ STAILQ_ENTRY(pccard_config_entry) cfe_list;
+};
+
+struct pccard_function {
+ /* read off the card */
+ int number;
+ int function;
+ int last_config_index;
+ u_long ccr_base;
+ u_long ccr_mask;
+ STAILQ_HEAD(, pccard_config_entry) cfe_head;
+ STAILQ_ENTRY(pccard_function) pf_list;
+ /* run-time state */
+ struct pccard_softc *sc;
+ struct device *child;
+ struct pccard_config_entry *cfe;
+ struct pccard_mem_handle pf_pcmh;
+#define pf_ccrt pf_pcmh.memt
+#define pf_ccrh pf_pcmh.memh
+#define pf_ccr_mhandle pf_pcmh.mhandle
+#define pf_ccr_realsize pf_pcmh.realsize
+ bus_addr_t pf_ccr_offset;
+ int pf_ccr_window;
+ long pf_mfc_iobase;
+ long pf_mfc_iomax;
+ int (*ih_fct) __P((void *));
+ void *ih_arg;
+ int ih_ipl;
+ int pf_flags;
+};
+
+/* pf_flags */
+#define PFF_ENABLED 0x0001 /* function is enabled */
+
+struct pccard_card {
+ int cis1_major;
+ int cis1_minor;
+ /* XXX waste of space? */
+ char cis1_info_buf[256];
+ char *cis1_info[4];
+ /*
+ * Use int32_t for manufacturer and product so that they can
+ * hold the id value found in card CIS and special value that
+ * indicates no id was found.
+ */
+ int32_t manufacturer;
+#define PCCARD_VENDOR_INVALID -1
+ int32_t product;
+#define PCCARD_PRODUCT_INVALID -1
+ u_int16_t error;
+#define PCCARD_CIS_INVALID { NULL, NULL, NULL, NULL }
+ STAILQ_HEAD(, pccard_function) pf_head;
+};
+
+struct pccardbus_if {
+ int (*if_card_attach) __P((struct device*));
+ void (*if_card_detach) __P((struct device*, int));
+ void (*if_card_deactivate) __P((struct device*));
+ int (*if_card_gettype) __P((struct device*));
+};
+
+struct pccard_softc {
+
+ /* this stuff is for the socket */
+ pccard_chipset_tag_t pct;
+ pccard_chipset_handle_t pch;
+
+ /* this stuff is for the card */
+ struct pccard_card card;
+ void *ih;
+ int sc_enabled_count; /* how many functions are
+ enabled */
+
+ /*
+ * These are passed down from the PCCARD chip, and exist only
+ * so that cards with Very Special address allocation needs
+ * know what range they should be dealing with.
+ */
+ bus_addr_t iobase; /* start i/o space allocation here */
+ bus_size_t iosize; /* size of the i/o space range */
+ /* pccardbus (upper) interface functions */
+ struct pccardbus_if sc_if;
+};
+
+void
+pccardbus_if_setup __P((struct pccard_softc*));
+
+struct pccard_cis_quirk {
+ int32_t manufacturer;
+ int32_t product;
+ char *cis1_info[4];
+ struct pccard_function *pf;
+ struct pccard_config_entry *cfe;
+};
+
+struct pccard_attach_args {
+ int32_t manufacturer;
+ int32_t product;
+ struct pccard_card *card;
+ struct pccard_function *pf;
+};
+
+struct pccard_tuple {
+ unsigned int code;
+ unsigned int length;
+ u_long mult;
+ bus_addr_t ptr;
+ bus_space_tag_t memt;
+ bus_space_handle_t memh;
+};
+
+void pccard_read_cis __P((struct pccard_softc *));
+void pccard_check_cis_quirks(device_t);
+void pccard_print_cis(device_t);
+int pccard_scan_cis __P((struct device * dev,
+ int (*) (struct pccard_tuple *, void *), void *));
+
+#define pccard_cis_read_1(tuple, idx0) \
+ (bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0)))
+
+#define pccard_tuple_read_1(tuple, idx1) \
+ (pccard_cis_read_1((tuple), ((tuple)->ptr+(2+(idx1)))))
+
+#define pccard_tuple_read_2(tuple, idx2) \
+ (pccard_tuple_read_1((tuple), (idx2)) | \
+ (pccard_tuple_read_1((tuple), (idx2)+1)<<8))
+
+#define pccard_tuple_read_3(tuple, idx3) \
+ (pccard_tuple_read_1((tuple), (idx3)) | \
+ (pccard_tuple_read_1((tuple), (idx3)+1)<<8) | \
+ (pccard_tuple_read_1((tuple), (idx3)+2)<<16))
+
+#define pccard_tuple_read_4(tuple, idx4) \
+ (pccard_tuple_read_1((tuple), (idx4)) | \
+ (pccard_tuple_read_1((tuple), (idx4)+1)<<8) | \
+ (pccard_tuple_read_1((tuple), (idx4)+2)<<16) | \
+ (pccard_tuple_read_1((tuple), (idx4)+3)<<24))
+
+#define pccard_tuple_read_n(tuple, n, idxn) \
+ (((n)==1)?pccard_tuple_read_1((tuple), (idxn)) : \
+ (((n)==2)?pccard_tuple_read_2((tuple), (idxn)) : \
+ (((n)==3)?pccard_tuple_read_3((tuple), (idxn)) : \
+ /* n == 4 */ pccard_tuple_read_4((tuple), (idxn)))))
+
+#define PCCARD_SPACE_MEMORY 1
+#define PCCARD_SPACE_IO 2
+
+int pccard_ccr_read __P((struct pccard_function *, int));
+void pccard_ccr_write __P((struct pccard_function *, int, int));
+
+#define pccard_mfc(sc) (STAILQ_FIRST(&(sc)->card.pf_head) && \
+ STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list))
+
+void pccard_function_init __P((struct pccard_function *,
+ struct pccard_config_entry *));
+int pccard_function_enable __P((struct pccard_function *));
+void pccard_function_disable __P((struct pccard_function *));
+
+#define pccard_io_alloc(pf, start, size, align, pciop) \
+ (pccard_chip_io_alloc((pf)->sc->pct, pf->sc->pch, (start), \
+ (size), (align), (pciop)))
+
+#define pccard_io_free(pf, pciohp) \
+ (pccard_chip_io_free((pf)->sc->pct, (pf)->sc->pch, (pciohp)))
+
+int pccard_io_map __P((struct pccard_function *, int, bus_addr_t,
+ bus_size_t, struct pccard_io_handle *, int *));
+void pccard_io_unmap __P((struct pccard_function *, int));
+
+#define pccard_mem_alloc(pf, size, pcmhp) \
+ (pccard_chip_mem_alloc((pf)->sc->pct, (pf)->sc->pch, (size), (pcmhp)))
+
+#define pccard_mem_free(pf, pcmhp) \
+ (pccard_chip_mem_free((pf)->sc->pct, (pf)->sc->pch, (pcmhp)))
+
+#define pccard_mem_map(pf, kind, card_addr, size, pcmhp, offsetp, windowp) \
+ (pccard_chip_mem_map((pf)->sc->pct, (pf)->sc->pch, (kind), \
+ (card_addr), (size), (pcmhp), (offsetp), (windowp)))
+
+#define pccard_mem_unmap(pf, window) \
+ (pccard_chip_mem_unmap((pf)->sc->pct, (pf)->sc->pch, (window)))
+
+void *pccard_intr_establish __P((struct pccard_function *, int,
+ int (*) (void *), void *));
+void pccard_intr_disestablish __P((struct pccard_function *, void *));
diff --git a/sys/tools/pccarddevs2h.awk b/sys/tools/pccarddevs2h.awk
new file mode 100644
index 0000000..f586397
--- /dev/null
+++ b/sys/tools/pccarddevs2h.awk
@@ -0,0 +1,226 @@
+#! /usr/bin/awk -f
+# $NetBSD: devlist2h.awk,v 1.3 1998/09/05 14:42:06 christos Exp $
+# $FreeBSD$
+#
+# Copyright (c) 1998 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Christos Zoulas.
+#
+# 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 the NetBSD
+# Foundation, Inc. and its contributors.
+# 4. Neither the name of The NetBSD Foundation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+# Copyright (c) 1995, 1996 Christopher G. Demetriou
+# 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 Christopher G. Demetriou.
+# This product includes software developed by Christos Zoulas
+# 4. The name of the author(s) 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.
+#
+function collectline(f, line) {
+ oparen = 0
+ line = ""
+ while (f <= NF) {
+ if ($f == "#") {
+ line = line "("
+ oparen = 1
+ f++
+ continue
+ }
+ if (oparen) {
+ line = line $f
+ if (f < NF)
+ line = line " "
+ f++
+ continue
+ }
+ line = line $f
+ if (f < NF)
+ line = line " "
+ f++
+ }
+ if (oparen)
+ line = line ")"
+ return line
+}
+BEGIN {
+ nproducts = nvendors = 0
+ dfile="pccarddevs_data.h"
+ hfile="pccarddevs.h"
+}
+NR == 1 {
+ VERSION = $0
+ gsub("\\$", "", VERSION)
+
+ printf("/*\t\$FreeBSD\$\t*/\n\n") > dfile
+ printf("/*\n") > dfile
+ printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
+ > dfile
+ printf(" *\n") > dfile
+ printf(" * generated from:\n") > dfile
+ printf(" *\t%s\n", VERSION) > dfile
+ printf(" */\n") > dfile
+
+ printf("/*\t\$FreeBSD\$\t*/\n\n") > hfile
+ printf("/*\n") > hfile
+ printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
+ > hfile
+ printf(" *\n") > hfile
+ printf(" * generated from:\n") > hfile
+ printf(" *\t%s\n", VERSION) > hfile
+ printf(" */\n") > hfile
+
+ next
+}
+$1 == "vendor" {
+ nvendors++
+
+ vendorindex[$2] = nvendors; # record index for this name, for later.
+ vendors[nvendors, 1] = $2; # name
+ vendors[nvendors, 2] = $3; # id
+ printf("#define\tPCCARD_VENDOR_%s\t%s\t", vendors[nvendors, 1],
+ vendors[nvendors, 2]) > hfile
+ vendors[nvendors, 3] = collectline(4, line)
+ printf("/* %s */\n", vendors[nvendors, 3]) > hfile
+ next
+}
+$1 == "product" {
+ nproducts++
+
+ products[nproducts, 1] = $2; # vendor name
+ products[nproducts, 2] = $3; # product id
+ products[nproducts, 3] = $4; # id
+
+ f = 5;
+
+ if ($4 == "{") {
+ products[nproducts, 3] = -1
+ z = "{ "
+ for (i = 0; i < 4; i++) {
+ if (f <= NF) {
+ gsub("&sp", " ", $f)
+ gsub("&tab", "\t", $f)
+ gsub("&nl", "\n", $f)
+ z = z $f " "
+ f++
+ }
+ else {
+ if (i == 3)
+ z = z "NULL "
+ else
+ z = z "NULL, "
+ }
+ }
+ products[nproducts, 4] = z $f
+ f++
+ }
+ else {
+ products[nproducts, 4] = "{ NULL, NULL, NULL, NULL }"
+ }
+ printf("#define\tPCCARD_CIS_%s_%s\t%s\n",
+ products[nproducts, 1], products[nproducts, 2],
+ products[nproducts, 4]) > hfile
+ printf("#define\tPCCARD_PRODUCT_%s_%s\t%s\n", products[nproducts, 1],
+ products[nproducts, 2], products[nproducts, 3]) > hfile
+
+ products[nproducts, 5] = collectline(f, line)
+
+ printf("#define\tPCCARD_STR_%s_%s\t\"%s\"\n",
+ products[nproducts, 1], products[nproducts, 2],
+ products[nproducts, 5]) > hfile
+
+ next
+}
+{
+ if ($0 == "")
+ blanklines++
+ print $0 > hfile
+ if (blanklines < 2)
+ print $0 > dfile
+}
+END {
+ # print out the match tables
+
+ printf("\n") > dfile
+
+ printf("struct pccard_knowndev pccard_knowndevs[] = {\n") > dfile
+ for (i = 1; i <= nproducts; i++) {
+ printf("\t{\n") > dfile
+ if (products[i, 3] == -1) {
+ printf("\t PCCARD_VENDOR_UNKNOWN, PCCARD_PRODUCT_%s_%s,\n",
+ products[i, 1], products[i, 2]) > dfile
+ } else {
+ printf("\t PCCARD_VENDOR_%s, PCCARD_PRODUCT_%s_%s,\n",
+ products[i, 1], products[i, 1], products[i, 2]) > dfile
+ }
+ printf("\t PCCARD_CIS_%s_%s,\n",
+ products[i, 1], products[i, 2]) > dfile
+ printf("\t ") > dfile
+ printf("0") > dfile
+ printf(",\n") > dfile
+
+ vendi = vendorindex[products[i, 1]];
+ printf("\t \"%s\",\n", vendors[vendi, 3]) > dfile
+ printf("\t \"%s\"\t},\n", products[i, 5]) > dfile
+ printf("\t},\n") > dfile
+ }
+ for (i = 1; i <= nvendors; i++) {
+ printf("\t{\n") > dfile
+ printf("\t PCCARD_VENDOR_%s, 0,\n", vendors[i, 1]) > dfile
+ printf("\t PCCARD_KNOWNDEV_NOPROD,\n") > dfile
+ printf("\t PCCARD_CIS_INVALID,\n") > dfile
+ printf("\t \"%s\",\n", vendors[i, 3]) > dfile
+ printf("\t NULL,\n") > dfile
+ printf("\t},\n") > dfile
+ }
+ printf("\t{ 0, 0, { NULL, NULL, NULL, NULL }, 0, NULL, NULL, }\n") > dfile
+ printf("};\n") > dfile
+}
OpenPOWER on IntegriCloud