summaryrefslogtreecommitdiffstats
path: root/sys/dev/pccard
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pccard')
-rw-r--r--sys/dev/pccard/Makefile.pccarddevs8
-rw-r--r--sys/dev/pccard/card_if.m194
-rw-r--r--sys/dev/pccard/devlist2h.awk178
-rw-r--r--sys/dev/pccard/files.pccard71
-rw-r--r--sys/dev/pccard/pccard.c1356
-rw-r--r--sys/dev/pccard/pccard_cis.c1293
-rw-r--r--sys/dev/pccard/pccard_cis.h203
-rw-r--r--sys/dev/pccard/pccard_cis_quirks.c288
-rw-r--r--sys/dev/pccard/pccarddevs611
-rw-r--r--sys/dev/pccard/pccarddevs.h1150
-rw-r--r--sys/dev/pccard/pccardreg.h74
-rw-r--r--sys/dev/pccard/pccardvar.h380
-rw-r--r--sys/dev/pccard/power_if.m46
13 files changed, 5852 insertions, 0 deletions
diff --git a/sys/dev/pccard/Makefile.pccarddevs b/sys/dev/pccard/Makefile.pccarddevs
new file mode 100644
index 0000000..592c2c5
--- /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 devlist2h.awk
+ /bin/rm -f pccarddevs.h
+ ${AWK} -f devlist2h.awk pccarddevs
diff --git a/sys/dev/pccard/card_if.m b/sys/dev/pccard/card_if.m
new file mode 100644
index 0000000..c843e32
--- /dev/null
+++ b/sys/dev/pccard/card_if.m
@@ -0,0 +1,194 @@
+#
+# Copyright (c) 1999 M. Warner Losh.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+#
+# $FreeBSD$
+#
+
+#include <sys/bus.h>
+#include <dev/pccard/pccardvar.h>
+
+INTERFACE card;
+
+# WARNING: THIS FILE IS USED BY BOTH OLDCARD AND NEWCARD. MAKE SURE
+# YOU TEST BOTH KERNELS IF CHANGING THIS FILE.
+
+#
+# Companion interface for pccard. We need to set attributes for memory
+# and i/o port mappings (as well as other types of attributes) that have
+# a well defined meaning inside the pccard/cardbus system. The bus
+# methods are inadequate for this because this must be done at the time the
+# resources are set for the device, which predates their activation. Also,
+# the driver activating the resources doesn't necessarily know or need to know
+# these attributes.
+#
+METHOD int set_res_flags {
+ device_t dev;
+ device_t child;
+ int restype;
+ int rid;
+ u_long value;
+};
+
+METHOD int get_res_flags {
+ device_t dev;
+ device_t child;
+ int restype;
+ int rid;
+ u_long *value;
+};
+
+#
+# Sets the memory offset of the pccard bridge's window into attribute
+# or common memory space.
+#
+METHOD int set_memory_offset {
+ device_t dev;
+ device_t child;
+ int rid;
+ u_int32_t cardaddr;
+ u_int32_t *deltap;
+}
+
+METHOD int get_memory_offset {
+ device_t dev;
+ device_t child;
+ int rid;
+ u_int32_t *offset;
+}
+
+#
+# pccard bridges call this method to initate the attachment of a card
+#
+METHOD int attach_card {
+ device_t dev;
+}
+
+#
+# pccard bridges call this to detach a card.
+#
+METHOD int detach_card {
+ device_t dev;
+}
+
+#
+# Returns the function number for this device.
+#
+METHOD int get_function {
+ device_t dev;
+ device_t child;
+ int *func;
+}
+
+#
+# Activates (and powers up if necessary) the card's nth function
+# since each function gets its own device, there is no need to
+# to specify a function number
+#
+METHOD int activate_function {
+ device_t dev;
+ device_t child;
+}
+
+METHOD int deactivate_function {
+ device_t dev;
+ device_t child;
+}
+
+#
+# Compatibility methods for OLDCARD drivers. We use these routines to make
+# it possible to call the OLDCARD driver's probe routine in the context that
+# it expects. For OLDCARD these are implemented as pass throughs to the
+# device_{probe,attach} routines. For NEWCARD they are implemented such
+# such that probe becomes strictly a matching routine and attach does both
+# the old probe and old attach.
+#
+# compat devices should use the following:
+#
+# /* Device interface */
+# DEVMETHOD(device_probe), pccard_compat_probe),
+# DEVMETHOD(device_attach), pccard_compat_attach),
+# /* Card interface */
+# DEVMETHOD(card_compat_match, foo_match), /* newly written */
+# DEVMETHOD(card_compat_probe, foo_probe), /* old probe */
+# DEVMETHOD(card_compat_attach, foo_attach), /* old attach */
+#
+# This will allow a single driver binary image to be used for both
+# OLDCARD and NEWCARD.
+#
+# Drivers wishing to not retain OLDCARD compatibility needn't do this.
+#
+# The compat_do_* versions are so that we can make the pccard_compat_probe
+# and _attach static lines and have the bus system pick the right version
+# to use so we don't enshrine pccard_* symbols in the driver's module.
+#
+METHOD int compat_probe {
+ device_t dev;
+}
+
+METHOD int compat_attach {
+ device_t dev;
+}
+
+CODE {
+ static int null_do_probe(device_t bus, device_t dev)
+ {
+ return (CARD_COMPAT_DO_PROBE(device_get_parent(bus), dev));
+ }
+
+ static int null_do_attach(device_t bus, device_t dev)
+ {
+ return (CARD_COMPAT_DO_ATTACH(device_get_parent(bus), dev));
+ }
+}
+
+METHOD int compat_do_probe {
+ device_t bus;
+ device_t dev;
+} DEFAULT null_do_probe;
+
+METHOD int compat_do_attach {
+ device_t bus;
+ device_t dev;
+} DEFAULT null_do_attach;
+
+#
+# Find "dev" in the passed table of devices. Return it or NULL.
+#
+METHOD struct pccard_product * do_product_lookup {
+ device_t bus;
+ device_t dev;
+ const struct pccard_product *tab;
+ size_t ent_size;
+ pccard_product_match_fn matchfn;
+}
+
+#
+# Helper method for the above. When a compatibility driver is converted,
+# one must write a match routine. This routine is unused on OLDCARD but
+# is used as a discriminator for NEWCARD.
+#
+METHOD int compat_match {
+ device_t dev;
+}
diff --git a/sys/dev/pccard/devlist2h.awk b/sys/dev/pccard/devlist2h.awk
new file mode 100644
index 0000000..d53761c
--- /dev/null
+++ b/sys/dev/pccard/devlist2h.awk
@@ -0,0 +1,178 @@
+#! /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
+ hfile="pccarddevs.h"
+}
+NR == 1 {
+ VERSION = $0
+ gsub("\\$", "", VERSION)
+
+ 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
+ if ($3 == "-1")
+ $3 = "0xffffffff";
+ vendors[nvendors, 2] = $3; # id
+ printf("#define\tPCMCIA_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
+ if ($3 == "-1")
+ $3 = "0xffffffff";
+ products[nproducts, 2] = $3; # product id
+ products[nproducts, 3] = $4; # id
+
+ f = 5;
+
+ if ($4 == "{") {
+ products[nproducts, 3] = "0xffffffff";
+ 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\tPCMCIA_CIS_%s_%s\t%s\n",
+ products[nproducts, 1], products[nproducts, 2],
+ products[nproducts, 4]) > hfile
+ printf("#define\tPCMCIA_PRODUCT_%s_%s\t%s\n", products[nproducts, 1],
+ products[nproducts, 2], products[nproducts, 3]) > hfile
+
+ products[nproducts, 5] = collectline(f, line)
+
+ printf("#define\tPCMCIA_STR_%s_%s\t\"%s\"\n",
+ products[nproducts, 1], products[nproducts, 2],
+ products[nproducts, 5]) > hfile
+
+ next
+}
+{
+ print $0 > hfile
+}
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..419d27d
--- /dev/null
+++ b/sys/dev/pccard/pccard.c
@@ -0,0 +1,1356 @@
+/* $NetBSD: pcmcia.c,v 1.23 2000/07/28 19:17:02 drochner Exp $ */
+
+/*
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sysctl.h>
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+
+#include <dev/pccard/pccardreg.h>
+#include <dev/pccard/pccardvar.h>
+
+#include "power_if.h"
+#include "card_if.h"
+
+#define PCCARDDEBUG
+
+/* sysctl vars */
+SYSCTL_NODE(_hw, OID_AUTO, pccard, CTLFLAG_RD, 0, "PCCARD parameters");
+
+int pccard_debug = 0;
+TUNABLE_INT("hw.pccard.debug", &pccard_debug);
+SYSCTL_INT(_hw_pccard, OID_AUTO, debug, CTLFLAG_RW,
+ &pccard_debug, 0,
+ "pccard debug");
+
+int pccard_cis_debug = 0;
+TUNABLE_INT("hw.pccard.cis_debug", &pccard_cis_debug);
+SYSCTL_INT(_hw_pccard, OID_AUTO, cis_debug, CTLFLAG_RW,
+ &pccard_cis_debug, 0, "pccard CIS debug");
+
+#ifdef PCCARDDEBUG
+#define DPRINTF(arg) if (pccard_debug) printf arg
+#define DEVPRINTF(arg) if (pccard_debug) device_printf arg
+#define PRVERBOSE(arg) printf arg
+#define DEVPRVERBOSE(arg) device_printf arg
+#else
+#define DPRINTF(arg)
+#define DEVPRINTF(arg)
+#define PRVERBOSE(arg) if (bootverbose) printf arg
+#define DEVPRVERBOSE(arg) if (bootverbose) device_printf arg
+#endif
+
+static int pccard_ccr_read(struct pccard_function *pf, int ccr);
+static void pccard_ccr_write(struct pccard_function *pf, int ccr, int val);
+static int pccard_attach_card(device_t dev);
+static int pccard_detach_card(device_t dev);
+static void pccard_function_init(struct pccard_function *pf);
+static void pccard_function_free(struct pccard_function *pf);
+static int pccard_function_enable(struct pccard_function *pf);
+static void pccard_function_disable(struct pccard_function *pf);
+static int pccard_compat_do_probe(device_t bus, device_t dev);
+static int pccard_compat_do_attach(device_t bus, device_t dev);
+static int pccard_add_children(device_t dev, int busno);
+static int pccard_probe(device_t dev);
+static int pccard_attach(device_t dev);
+static int pccard_detach(device_t dev);
+static void pccard_print_resources(struct resource_list *rl,
+ const char *name, int type, int count, const char *format);
+static int pccard_print_child(device_t dev, device_t child);
+static int pccard_set_resource(device_t dev, device_t child, int type,
+ int rid, u_long start, u_long count);
+static int pccard_get_resource(device_t dev, device_t child, int type,
+ int rid, u_long *startp, u_long *countp);
+static void pccard_delete_resource(device_t dev, device_t child, int type,
+ int rid);
+static int pccard_set_res_flags(device_t dev, device_t child, int type,
+ int rid, u_int32_t flags);
+static int pccard_set_memory_offset(device_t dev, device_t child, int rid,
+ u_int32_t offset, u_int32_t *deltap);
+static void pccard_probe_nomatch(device_t cbdev, device_t child);
+static int pccard_read_ivar(device_t bus, device_t child, int which,
+ u_char *result);
+static void pccard_driver_added(device_t dev, driver_t *driver);
+static struct resource *pccard_alloc_resource(device_t dev,
+ device_t child, int type, int *rid, u_long start,
+ u_long end, u_long count, u_int flags);
+static int pccard_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r);
+static void pccard_child_detached(device_t parent, device_t dev);
+static void pccard_intr(void *arg);
+static int pccard_setup_intr(device_t dev, device_t child,
+ struct resource *irq, int flags, driver_intr_t *intr,
+ void *arg, void **cookiep);
+static int pccard_teardown_intr(device_t dev, device_t child,
+ struct resource *r, void *cookie);
+
+static const struct pccard_product *
+pccard_do_product_lookup(device_t bus, device_t dev,
+ const struct pccard_product *tab, size_t ent_size,
+ pccard_product_match_fn matchfn);
+
+
+static int
+pccard_ccr_read(struct pccard_function *pf, int ccr)
+{
+ return (bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
+ pf->pf_ccr_offset + ccr));
+}
+
+static void
+pccard_ccr_write(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_set_default_descr(device_t dev)
+{
+ const char *vendorstr, *prodstr;
+ char *str;
+
+ if (pccard_get_vendor_str(dev, &vendorstr))
+ return (0);
+ if (pccard_get_product_str(dev, &prodstr))
+ return (0);
+ str = malloc(strlen(vendorstr) + strlen(prodstr) + 2, M_DEVBUF,
+ M_WAITOK);
+ sprintf(str, "%s %s", vendorstr, prodstr);
+ device_set_desc_copy(dev, str);
+ free(str, M_DEVBUF);
+ return (0);
+}
+
+static int
+pccard_attach_card(device_t dev)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+ struct pccard_function *pf;
+ struct pccard_ivar *ivar;
+ device_t child;
+ int i;
+
+ /*
+ * this is here so that when socket_enable calls gettype, trt happens
+ */
+ STAILQ_INIT(&sc->card.pf_head);
+
+ DEVPRINTF((dev, "chip_socket_enable\n"));
+ POWER_ENABLE_SOCKET(device_get_parent(dev), dev);
+
+ DEVPRINTF((dev, "read_cis\n"));
+ pccard_read_cis(sc);
+
+ DEVPRINTF((dev, "check_cis_quirks\n"));
+ 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) {
+ device_printf(dev, "CARD ERROR!\n");
+ return (1);
+ }
+ if (STAILQ_EMPTY(&sc->card.pf_head)) {
+ device_printf(dev, "Card has no functions!\n");
+ return (1);
+ }
+
+ if (bootverbose || pccard_debug)
+ pccard_print_cis(dev);
+
+ DEVPRINTF((dev, "functions scanning\n"));
+ i = -1;
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ i++;
+ if (STAILQ_EMPTY(&pf->cfe_head)) {
+ device_printf(dev,
+ "Function %d has no config entries.!\n", i);
+ continue;
+ }
+ pf->sc = sc;
+ pf->cfe = NULL;
+ pf->dev = NULL;
+ }
+ DEVPRINTF((dev, "Card has %d functions. pccard_mfc is %d\n", i + 1,
+ pccard_mfc(sc)));
+
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (STAILQ_EMPTY(&pf->cfe_head))
+ continue;
+ /*
+ * In NetBSD, the drivers are responsible for activating
+ * each function of a card. I think that in FreeBSD we
+ * want to activate them enough for the usual bus_*_resource
+ * routines will do the right thing. This many mean a
+ * departure from the current NetBSD model.
+ *
+ * This seems to work well in practice for most cards.
+ * However, there are two cases that are problematic.
+ * If a driver wishes to pick and chose which config
+ * entry to use, then this method falls down. These
+ * are usually older cards. In addition, there are
+ * some cards that have multiple hardware units on the
+ * cards, but presents only one CIS chain. These cards
+ * are combination cards, but only one of these units
+ * can be on at a time.
+ */
+ ivar = malloc(sizeof(struct pccard_ivar), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ child = device_add_child(dev, NULL, -1);
+ device_set_ivars(child, ivar);
+ ivar->fcn = pf;
+ pf->dev = child;
+ /*
+ * XXX We might want to move the next two lines into
+ * XXX the pccard interface layer. For the moment, this
+ * XXX is OK, but some drivers want to pick the config
+ * XXX entry to use as well as some address tweaks (mostly
+ * XXX due to bugs in decode logic that makes some
+ * XXX addresses illegal or broken).
+ */
+ pccard_function_init(pf);
+ if (sc->sc_enabled_count == 0)
+ POWER_ENABLE_SOCKET(device_get_parent(dev), dev);
+ if (pccard_function_enable(pf) == 0 &&
+ pccard_set_default_descr(child) == 0 &&
+ device_probe_and_attach(child) == 0) {
+ DEVPRINTF((sc->dev, "function %d CCR at %d "
+ "offset %x mask %x: "
+ "%x %x %x %x, %x %x %x %x, %x\n",
+ pf->number, pf->pf_ccr_window, pf->pf_ccr_offset,
+ pf->ccr_mask, 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)));
+ } else {
+ if (pf->cfe != NULL)
+ pccard_function_disable(pf);
+ }
+ }
+ return (0);
+}
+
+static int
+pccard_detach_card(device_t dev)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+ struct pccard_function *pf;
+ struct pccard_config_entry *cfe;
+ int state;
+
+ /*
+ * 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 (pf->dev == NULL)
+ continue;
+ state = device_get_state(pf->dev);
+ if (state == DS_ATTACHED || state == DS_BUSY)
+ device_detach(pf->dev);
+ if (pf->cfe != NULL)
+ pccard_function_disable(pf);
+ pccard_function_free(pf);
+ device_delete_child(dev, pf->dev);
+ }
+ if (sc->sc_enabled_count == 0)
+ POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
+
+ while (NULL != (pf = STAILQ_FIRST(&sc->card.pf_head))) {
+ while (NULL != (cfe = STAILQ_FIRST(&pf->cfe_head))) {
+ STAILQ_REMOVE_HEAD(&pf->cfe_head, cfe_list);
+ free(cfe, M_DEVBUF);
+ }
+ STAILQ_REMOVE_HEAD(&sc->card.pf_head, pf_list);
+ free(pf, M_DEVBUF);
+ }
+ return (0);
+}
+
+static const struct pccard_product *
+pccard_do_product_lookup(device_t bus, device_t dev,
+ const struct pccard_product *tab, size_t ent_size,
+ pccard_product_match_fn matchfn)
+{
+ const struct pccard_product *ent;
+ int matches;
+ u_int32_t fcn;
+ u_int32_t vendor;
+ u_int32_t prod;
+ const char *vendorstr;
+ const char *prodstr;
+
+#ifdef DIAGNOSTIC
+ if (sizeof *ent > ent_size)
+ panic("pccard_product_lookup: bogus ent_size %jd",
+ (intmax_t) ent_size);
+#endif
+ if (pccard_get_vendor(dev, &vendor))
+ return (NULL);
+ if (pccard_get_product(dev, &prod))
+ return (NULL);
+ if (pccard_get_function_number(dev, &fcn))
+ return (NULL);
+ if (pccard_get_vendor_str(dev, &vendorstr))
+ return (NULL);
+ if (pccard_get_product_str(dev, &prodstr))
+ return (NULL);
+ for (ent = tab; ent->pp_vendor != 0; ent =
+ (const struct pccard_product *) ((const char *) ent + ent_size)) {
+ matches = 1;
+ if (ent->pp_vendor == PCCARD_VENDOR_ANY &&
+ ent->pp_product == PCCARD_PRODUCT_ANY &&
+ ent->pp_cis[0] == NULL &&
+ ent->pp_cis[1] == NULL) {
+ if (ent->pp_name)
+ device_printf(dev,
+ "Total wildcard entry ignored for %s\n",
+ ent->pp_name);
+ continue;
+ }
+ if (matches && ent->pp_vendor != PCCARD_VENDOR_ANY &&
+ vendor != ent->pp_vendor)
+ matches = 0;
+ if (matches && ent->pp_product != PCCARD_PRODUCT_ANY &&
+ prod != ent->pp_product)
+ matches = 0;
+ if (matches && fcn != ent->pp_expfunc)
+ matches = 0;
+ if (matches && ent->pp_cis[0] &&
+ strcmp(ent->pp_cis[0], vendorstr) != 0)
+ matches = 0;
+ if (matches && ent->pp_cis[1] &&
+ strcmp(ent->pp_cis[1], prodstr) != 0)
+ matches = 0;
+ /* XXX need to match cis[2] and cis[3] also XXX */
+ if (matchfn != NULL)
+ matches = (*matchfn)(dev, ent, matches);
+ if (matches)
+ return (ent);
+ }
+ return (NULL);
+}
+
+/*
+ * Initialize a PCCARD function. May be called as long as the function is
+ * disabled.
+ *
+ * Note: pccard_function_init should not keep resources allocated. It should
+ * only set them up ala isa pnp, set the values in the rl lists, and return.
+ * Any resource held after pccard_function_init is called is a bug. However,
+ * the bus routines to get the resources also assume that pccard_function_init
+ * does this, so they need to be fixed too.
+ */
+static void
+pccard_function_init(struct pccard_function *pf)
+{
+ struct pccard_config_entry *cfe;
+ int i;
+ struct pccard_ivar *devi = PCCARD_IVAR(pf->dev);
+ struct resource_list *rl = &devi->resources;
+ struct resource_list_entry *rle;
+ struct resource *r = 0;
+ device_t bus;
+ int start;
+ int end;
+ int spaces;
+
+ if (pf->pf_flags & PFF_ENABLED) {
+ printf("pccard_function_init: function is enabled");
+ return;
+ }
+ bus = device_get_parent(pf->dev);
+ /* Remember which configuration entry we are using. */
+ STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
+ for (i = 0; i < cfe->num_iospace; i++)
+ cfe->iores[i] = NULL;
+ cfe->irqres = NULL;
+ spaces = 0;
+ for (i = 0; i < cfe->num_iospace; i++) {
+ start = cfe->iospace[i].start;
+ if (start)
+ end = start + cfe->iospace[i].length - 1;
+ else
+ end = ~0;
+ cfe->iorid[i] = i;
+ DEVPRINTF((bus, "I/O rid %d start %x end %x\n",
+ i, start, end));
+ r = cfe->iores[i] = bus_alloc_resource(bus,
+ SYS_RES_IOPORT, &cfe->iorid[i], start, end,
+ cfe->iospace[i].length,
+ rman_make_alignment_flags(cfe->iospace[i].length));
+ if (cfe->iores[i] == NULL)
+ goto not_this_one;
+ resource_list_add(rl, SYS_RES_IOPORT, cfe->iorid[i],
+ rman_get_start(r), rman_get_end(r),
+ cfe->iospace[i].length);
+ rle = resource_list_find(rl, SYS_RES_IOPORT,
+ cfe->iorid[i]);
+ rle->res = r;
+ spaces++;
+ }
+ if (cfe->num_memspace > 0) {
+ /*
+ * Not implement yet, Fix me.
+ */
+ DEVPRINTF((bus, "Memory space not yet implemented.\n"));
+ }
+ if (spaces == 0) {
+ DEVPRINTF((bus, "Neither memory nor I/O mampped\n"));
+ goto not_this_one;
+ }
+ if (cfe->irqmask) {
+ cfe->irqrid = 0;
+ r = cfe->irqres = bus_alloc_resource(bus, SYS_RES_IRQ,
+ &cfe->irqrid, 0, ~0, 1, 0);
+ if (cfe->irqres == NULL)
+ goto not_this_one;
+ resource_list_add(rl, SYS_RES_IRQ, cfe->irqrid,
+ rman_get_start(r), rman_get_end(r), 1);
+ rle = resource_list_find(rl, SYS_RES_IRQ,
+ cfe->irqrid);
+ rle->res = r;
+ }
+ /* If we get to here, we've allocated all we need */
+ pf->cfe = cfe;
+ break;
+ not_this_one:;
+ DEVPRVERBOSE((bus, "Allocation failed for cfe %d\n",
+ cfe->number));
+ /*
+ * Release resources that we partially allocated
+ * from this config entry.
+ */
+ for (i = 0; i < cfe->num_iospace; i++) {
+ if (cfe->iores[i] != NULL) {
+ bus_release_resource(bus, SYS_RES_IOPORT,
+ cfe->iorid[i], cfe->iores[i]);
+ rle = resource_list_find(rl, SYS_RES_IOPORT,
+ cfe->iorid[i]);
+ rle->res = NULL;
+ resource_list_delete(rl, SYS_RES_IOPORT,
+ cfe->iorid[i]);
+ }
+ cfe->iores[i] = NULL;
+ }
+ if (cfe->irqmask && cfe->irqres != NULL) {
+ bus_release_resource(bus, SYS_RES_IRQ,
+ cfe->irqrid, cfe->irqres);
+ rle = resource_list_find(rl, SYS_RES_IRQ,
+ cfe->irqrid);
+ rle->res = NULL;
+ resource_list_delete(rl, SYS_RES_IRQ, cfe->irqrid);
+ cfe->irqres = NULL;
+ }
+ }
+}
+
+/*
+ * Free resources allocated by pccard_function_init(), May be called as long
+ * as the function is disabled.
+ *
+ * NOTE: This function should be unnecessary. pccard_function_init should
+ * never keep resources initialized.
+ */
+static void
+pccard_function_free(struct pccard_function *pf)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(pf->dev);
+ struct resource_list_entry *rle;
+
+ if (pf->pf_flags & PFF_ENABLED) {
+ printf("pccard_function_init: function is enabled");
+ return;
+ }
+
+ SLIST_FOREACH(rle, &devi->resources, link) {
+ if (rle->res) {
+ if (rman_get_device(rle->res) != pf->sc->dev)
+ device_printf(pf->sc->dev,
+ "function_free: Resource still owned by "
+ "child, oops. "
+ "(type=%d, rid=%d, addr=%lx)\n",
+ rle->type, rle->rid,
+ rman_get_start(rle->res));
+ BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev),
+ pf->sc->dev, rle->type, rle->rid, rle->res);
+ rle->res = NULL;
+ }
+ }
+ resource_list_free(&devi->resources);
+}
+
+static void
+pccard_mfc_adjust_iobase(struct pccard_function *pf, bus_addr_t addr,
+ bus_addr_t offset, bus_size_t size)
+{
+ bus_size_t iosize, tmp;
+
+ if (addr != 0) {
+ if (pf->pf_mfc_iomax == 0) {
+ pf->pf_mfc_iobase = addr + offset;
+ pf->pf_mfc_iomax = pf->pf_mfc_iobase + size;
+ } else {
+ /* this makes the assumption that nothing overlaps */
+ if (pf->pf_mfc_iobase > addr + offset)
+ pf->pf_mfc_iobase = addr + offset;
+ if (pf->pf_mfc_iomax < addr + offset + size)
+ pf->pf_mfc_iomax = 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--;
+
+ DEVPRINTF((pf->dev, "MFC: I/O base %#jx IOSIZE %#jx\n",
+ (uintmax_t)pf->pf_mfc_iobase, (uintmax_t)(iosize + 1)));
+ 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);
+}
+
+/* Enable a PCCARD function */
+static int
+pccard_function_enable(struct pccard_function *pf)
+{
+ struct pccard_function *tmp;
+ int reg;
+ device_t dev = pf->sc->dev;
+
+ if (pf->cfe == NULL) {
+ DEVPRVERBOSE((dev, "No config entry could be allocated.\n"));
+ return (ENOMEM);
+ }
+
+ /*
+ * Increase the reference count on the socket, enabling power, if
+ * necessary.
+ */
+ 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) {
+ pf->ccr_rid = 0;
+ pf->ccr_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &pf->ccr_rid, 0, ~0, 1 << 10, RF_ACTIVE);
+ if (!pf->ccr_res)
+ goto bad;
+ DEVPRINTF((dev, "ccr_res == %lx-%lx, base=%x\n",
+ rman_get_start(pf->ccr_res), rman_get_end(pf->ccr_res),
+ pf->ccr_base));
+ CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
+ pf->ccr_rid, PCCARD_A_MEM_ATTR);
+ CARD_SET_MEMORY_OFFSET(device_get_parent(dev), dev,
+ pf->ccr_rid, pf->ccr_base, &pf->pf_ccr_offset);
+ pf->pf_ccrt = rman_get_bustag(pf->ccr_res);
+ pf->pf_ccrh = rman_get_bushandle(pf->ccr_res);
+ pf->pf_ccr_realsize = 1;
+ }
+
+ 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);
+ /* PCCARD_CCR_OPTION_IRQ_ENABLE set elsewhere as needed */
+ }
+ 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))
+ pccard_mfc_adjust_iobase(pf, 0, 0, 0);
+
+#ifdef PCCARDDEBUG
+ if (pccard_debug) {
+ STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) {
+ device_printf(tmp->sc->dev,
+ "function %d CCR at %d offset %x: "
+ "%x %x %x %x, %x %x %x %x, %x\n",
+ 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.
+ */
+ pf->sc->sc_enabled_count--;
+ DEVPRINTF((dev, "bad --enabled_count = %d\n", pf->sc->sc_enabled_count));
+
+ return (1);
+}
+
+/* Disable PCCARD function. */
+static void
+pccard_function_disable(struct pccard_function *pf)
+{
+ struct pccard_function *tmp;
+ device_t dev = pf->sc->dev;
+
+ if (pf->cfe == NULL)
+ panic("pccard_function_disable: function not initialized");
+
+ if ((pf->pf_flags & PFF_ENABLED) == 0) {
+ /*
+ * Don't do anything if we're already disabled.
+ */
+ return;
+ }
+
+ if (pf->intr_handler != NULL) {
+ struct pccard_ivar *devi = PCCARD_IVAR(pf->dev);
+ struct resource_list_entry *rle =
+ resource_list_find(&devi->resources, SYS_RES_IRQ, 0);
+ BUS_TEARDOWN_INTR(dev, pf->dev, rle->res,
+ pf->intr_handler_cookie);
+ }
+
+ /*
+ * 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) {
+ bus_release_resource(dev, SYS_RES_MEMORY, pf->ccr_rid,
+ pf->ccr_res);
+ pf->ccr_res = NULL;
+ }
+
+ /*
+ * Decrement the reference count, and power down the socket, if
+ * necessary.
+ */
+ pf->sc->sc_enabled_count--;
+}
+
+/*
+ * simulate the old "probe" routine. In the new world order, the driver
+ * needs to grab devices while in the old they were assigned to the device by
+ * the pccardd process. These symbols are exported to the upper layers.
+ */
+static int
+pccard_compat_do_probe(device_t bus, device_t dev)
+{
+ return (CARD_COMPAT_MATCH(dev));
+}
+
+static int
+pccard_compat_do_attach(device_t bus, device_t dev)
+{
+ int err;
+
+ err = CARD_COMPAT_PROBE(dev);
+ if (err <= 0)
+ err = CARD_COMPAT_ATTACH(dev);
+ return (err);
+}
+
+#define PCCARD_NPORT 2
+#define PCCARD_NMEM 5
+#define PCCARD_NIRQ 1
+#define PCCARD_NDRQ 0
+
+static int
+pccard_add_children(device_t dev, int busno)
+{
+ /* Call parent to scan for any current children */
+ return (0);
+}
+
+static int
+pccard_probe(device_t dev)
+{
+ device_set_desc(dev, "16-bit PCCard bus");
+ return (pccard_add_children(dev, device_get_unit(dev)));
+}
+
+static int
+pccard_attach(device_t dev)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+
+ sc->dev = dev;
+ sc->sc_enabled_count = 0;
+ return (bus_generic_attach(dev));
+}
+
+static int
+pccard_detach(device_t dev)
+{
+ pccard_detach_card(dev);
+ return 0;
+}
+
+static int
+pccard_suspend(device_t self)
+{
+ pccard_detach_card(self);
+ return (0);
+}
+
+static
+int
+pccard_resume(device_t self)
+{
+ return (0);
+}
+
+static void
+pccard_print_resources(struct resource_list *rl, const char *name, int type,
+ int count, const char *format)
+{
+ struct resource_list_entry *rle;
+ int printed;
+ int i;
+
+ printed = 0;
+ for (i = 0; i < count; i++) {
+ rle = resource_list_find(rl, type, i);
+ if (rle != NULL) {
+ if (printed == 0)
+ printf(" %s ", name);
+ else if (printed > 0)
+ printf(",");
+ printed++;
+ printf(format, rle->start);
+ if (rle->count > 1) {
+ printf("-");
+ printf(format, rle->start + rle->count - 1);
+ }
+ } else if (i > 3) {
+ /* check the first few regardless */
+ break;
+ }
+ }
+}
+
+static int
+pccard_print_child(device_t dev, device_t child)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct resource_list *rl = &devi->resources;
+ int retval = 0;
+
+ retval += bus_print_child_header(dev, child);
+ retval += printf(" at");
+
+ if (devi != NULL) {
+ pccard_print_resources(rl, "port", SYS_RES_IOPORT,
+ PCCARD_NPORT, "%#lx");
+ pccard_print_resources(rl, "iomem", SYS_RES_MEMORY,
+ PCCARD_NMEM, "%#lx");
+ pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ,
+ "%ld");
+ pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ,
+ "%ld");
+ retval += printf(" function %d config %d", devi->fcn->number,
+ devi->fcn->cfe->number);
+ }
+
+ retval += bus_print_child_footer(dev, child);
+
+ return (retval);
+}
+
+static int
+pccard_set_resource(device_t dev, device_t child, int type, int rid,
+ u_long start, u_long count)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct resource_list *rl = &devi->resources;
+
+ if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY
+ && type != SYS_RES_IRQ && type != SYS_RES_DRQ)
+ return (EINVAL);
+ if (rid < 0)
+ return (EINVAL);
+ if (type == SYS_RES_IOPORT && rid >= PCCARD_NPORT)
+ return (EINVAL);
+ if (type == SYS_RES_MEMORY && rid >= PCCARD_NMEM)
+ return (EINVAL);
+ if (type == SYS_RES_IRQ && rid >= PCCARD_NIRQ)
+ return (EINVAL);
+ if (type == SYS_RES_DRQ && rid >= PCCARD_NDRQ)
+ return (EINVAL);
+
+ resource_list_add(rl, type, rid, start, start + count - 1, count);
+ if (NULL != resource_list_alloc(rl, device_get_parent(dev), dev,
+ type, &rid, start, start + count - 1, count, 0))
+ return 0;
+ else
+ return ENOMEM;
+}
+
+static int
+pccard_get_resource(device_t dev, device_t child, int type, int rid,
+ u_long *startp, u_long *countp)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct resource_list *rl = &devi->resources;
+ struct resource_list_entry *rle;
+
+ rle = resource_list_find(rl, type, rid);
+ if (rle == NULL)
+ return (ENOENT);
+
+ if (startp != NULL)
+ *startp = rle->start;
+ if (countp != NULL)
+ *countp = rle->count;
+
+ return (0);
+}
+
+static void
+pccard_delete_resource(device_t dev, device_t child, int type, int rid)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct resource_list *rl = &devi->resources;
+ resource_list_delete(rl, type, rid);
+}
+
+static int
+pccard_set_res_flags(device_t dev, device_t child, int type, int rid,
+ u_int32_t flags)
+{
+ return (CARD_SET_RES_FLAGS(device_get_parent(dev), child, type,
+ rid, flags));
+}
+
+static int
+pccard_set_memory_offset(device_t dev, device_t child, int rid,
+ u_int32_t offset, u_int32_t *deltap)
+
+{
+ return (CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid,
+ offset, deltap));
+}
+
+static void
+pccard_probe_nomatch(device_t bus, device_t child)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *func = devi->fcn;
+ struct pccard_softc *sc = PCCARD_SOFTC(bus);
+
+ device_printf(bus, "<unknown card>");
+ printf(" (manufacturer=0x%04x, product=0x%04x) at function %d\n",
+ sc->card.manufacturer, sc->card.product, func->number);
+ device_printf(bus, " CIS info: %s, %s, %s\n", sc->card.cis1_info[0],
+ sc->card.cis1_info[1], sc->card.cis1_info[2]);
+ return;
+}
+
+static int
+pccard_child_location_str(device_t bus, device_t child, char *buf,
+ size_t buflen)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *func = devi->fcn;
+
+ snprintf(buf, buflen, "function=%d", func->number);
+ return (0);
+}
+
+static int
+pccard_child_pnpinfo_str(device_t bus, device_t child, char *buf,
+ size_t buflen)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *func = devi->fcn;
+ struct pccard_softc *sc = PCCARD_SOFTC(bus);
+
+ snprintf(buf, buflen, "manufacturer=0x%04x product=0x%04x "
+ "cisvendor=\"%s\" cisproduct=\"%s\" function_type=%d",
+ sc->card.manufacturer, sc->card.product, sc->card.cis1_info[0],
+ sc->card.cis1_info[1], func->function);
+ return (0);
+}
+
+static int
+pccard_read_ivar(device_t bus, device_t child, int which, u_char *result)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *func = devi->fcn;
+ struct pccard_softc *sc = PCCARD_SOFTC(bus);
+
+ switch (which) {
+ default:
+ case PCCARD_IVAR_ETHADDR:
+ bcopy(func->pf_funce_lan_nid, result, ETHER_ADDR_LEN);
+ break;
+ case PCCARD_IVAR_VENDOR:
+ *(u_int32_t *) result = sc->card.manufacturer;
+ break;
+ case PCCARD_IVAR_PRODUCT:
+ *(u_int32_t *) result = sc->card.product;
+ break;
+ case PCCARD_IVAR_PRODEXT:
+ *(u_int16_t *) result = sc->card.prodext;
+ break;
+ case PCCARD_IVAR_FUNCTION:
+ *(u_int32_t *) result = func->function;
+ break;
+ case PCCARD_IVAR_FUNCTION_NUMBER:
+ if (!func) {
+ device_printf(bus, "No function number, bug!\n");
+ return (ENOENT);
+ }
+ *(u_int32_t *) result = func->number;
+ break;
+ case PCCARD_IVAR_VENDOR_STR:
+ *(char **) result = sc->card.cis1_info[0];
+ break;
+ case PCCARD_IVAR_PRODUCT_STR:
+ *(char **) result = sc->card.cis1_info[1];
+ break;
+ case PCCARD_IVAR_CIS3_STR:
+ *(char **) result = sc->card.cis1_info[2];
+ break;
+ case PCCARD_IVAR_CIS4_STR:
+ *(char **) result = sc->card.cis1_info[3];
+ break;
+ }
+ return (0);
+}
+
+static void
+pccard_driver_added(device_t dev, driver_t *driver)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+ struct pccard_function *pf;
+ device_t child;
+
+ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
+ if (STAILQ_EMPTY(&pf->cfe_head))
+ continue;
+ child = pf->dev;
+ if (device_get_state(child) != DS_NOTPRESENT)
+ continue;
+ if (pccard_function_enable(pf) == 0 &&
+ device_probe_and_attach(child) == 0) {
+ DEVPRINTF((sc->dev, "function %d CCR at %d "
+ "offset %x: %x %x %x %x, %x %x %x %x, %x\n",
+ 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)));
+ } else {
+ if (pf->cfe != NULL)
+ pccard_function_disable(pf);
+ }
+ }
+ return;
+}
+
+static struct resource *
+pccard_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct pccard_ivar *dinfo;
+ struct resource_list_entry *rle = 0;
+ int passthrough = (device_get_parent(child) != dev);
+ int isdefault = (start == 0 && end == ~0UL && count == 1);
+ struct resource *r = NULL;
+
+ /* XXX I'm no longer sure this is right */
+ if (passthrough) {
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags));
+ }
+
+ dinfo = device_get_ivars(child);
+ rle = resource_list_find(&dinfo->resources, type, *rid);
+
+ if (rle == NULL && isdefault)
+ return (NULL); /* no resource of that type/rid */
+ if (rle == NULL || rle->res == NULL) {
+ /* Do we want this device to own it? */
+ /* XXX I think so, but that might be lame XXX */
+ r = bus_alloc_resource(dev, type, rid, start, end,
+ count, flags /* XXX aligment? */);
+ if (r == NULL)
+ goto bad;
+ resource_list_add(&dinfo->resources, type, *rid,
+ rman_get_start(r), rman_get_end(r), count);
+ rle = resource_list_find(&dinfo->resources, type, *rid);
+ if (!rle)
+ goto bad;
+ rle->res = r;
+ }
+ /*
+ * XXX the following looks wrong, in theory, but likely it is
+ * XXX needed because of how the CIS code allocates resources
+ * XXX for this device.
+ */
+ if (rman_get_device(rle->res) != dev)
+ return (NULL);
+ bus_release_resource(dev, type, *rid, rle->res);
+ rle->res = NULL;
+ switch(type) {
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ if (!(flags & RF_ALIGNMENT_MASK))
+ flags |= rman_make_alignment_flags(rle->count);
+ break;
+ case SYS_RES_IRQ:
+ flags |= RF_SHAREABLE;
+ break;
+ }
+ rle->res = resource_list_alloc(&dinfo->resources, dev, child,
+ type, rid, rle->start, rle->end, rle->count, flags);
+ return (rle->res);
+bad:;
+ device_printf(dev, "WARNING: Resource not reserved by pccard\n");
+ return (NULL);
+}
+
+static int
+pccard_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct pccard_ivar *dinfo;
+ int passthrough = (device_get_parent(child) != dev);
+ struct resource_list_entry *rle = 0;
+ int ret;
+ int flags;
+
+ if (passthrough)
+ return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+ type, rid, r);
+
+ dinfo = device_get_ivars(child);
+
+ rle = resource_list_find(&dinfo->resources, type, rid);
+
+ if (!rle) {
+ device_printf(dev, "Allocated resource not found, "
+ "%d %x %lx %lx\n",
+ type, rid, rman_get_start(r), rman_get_size(r));
+ return ENOENT;
+ }
+ if (!rle->res) {
+ device_printf(dev, "Allocated resource not recorded\n");
+ return ENOENT;
+ }
+
+ ret = BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+ type, rid, r);
+ switch(type) {
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ flags = rman_make_alignment_flags(rle->count);
+ break;
+ case SYS_RES_IRQ:
+ flags = RF_SHAREABLE;
+ break;
+ default:
+ flags = 0;
+ }
+ rle->res = bus_alloc_resource(dev, type, &rid,
+ rle->start, rle->end, rle->count, flags);
+ if (rle->res == NULL)
+ device_printf(dev, "release_resource: "
+ "unable to reaquire resource\n");
+ return ret;
+}
+
+static void
+pccard_child_detached(device_t parent, device_t dev)
+{
+ struct pccard_ivar *ivar = PCCARD_IVAR(dev);
+ struct pccard_function *pf = ivar->fcn;
+
+ pccard_function_disable(pf);
+}
+
+static void
+pccard_intr(void *arg)
+{
+ struct pccard_function *pf = (struct pccard_function*) arg;
+ int reg;
+ int doisr = 1;
+
+ /*
+ * MFC cards know if they interrupted, so we have to ack the
+ * interrupt and call the ISR. Non-MFC cards don't have these
+ * bits, so they always get called. Many non-MFC cards have
+ * this bit set always upon read, but some do not.
+ *
+ * We always ack the interrupt, even if there's no ISR
+ * for the card. This is done on the theory that acking
+ * the interrupt will pacify the card enough to keep an
+ * interrupt storm from happening. Of course this won't
+ * help in the non-MFC case.
+ *
+ * This has no impact for MPSAFEness of the client drivers.
+ * We register this with whatever flags the intr_handler
+ * was registered with. All these functions are MPSAFE.
+ */
+ if (pccard_mfc(pf->sc)) {
+ reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
+ if (reg & PCCARD_CCR_STATUS_INTR)
+ pccard_ccr_write(pf, PCCARD_CCR_STATUS,
+ reg & ~PCCARD_CCR_STATUS_INTR);
+ else
+ doisr = 0;
+ }
+ if (pf->intr_handler != NULL && doisr)
+ pf->intr_handler(pf->intr_handler_arg);
+}
+
+static int
+pccard_setup_intr(device_t dev, device_t child, struct resource *irq,
+ int flags, driver_intr_t *intr, void *arg, void **cookiep)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+ struct pccard_ivar *ivar = PCCARD_IVAR(child);
+ struct pccard_function *func = ivar->fcn;
+ int err;
+
+ if (func->intr_handler != NULL)
+ panic("Only one interrupt handler per function allowed");
+ err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr,
+ func, cookiep);
+ if (err != 0)
+ return (err);
+ func->intr_handler = intr;
+ func->intr_handler_arg = arg;
+ func->intr_handler_cookie = *cookiep;
+ if (pccard_mfc(sc)) {
+ pccard_ccr_write(func, PCCARD_CCR_OPTION,
+ pccard_ccr_read(func, PCCARD_CCR_OPTION) |
+ PCCARD_CCR_OPTION_IREQ_ENABLE);
+ }
+ return (0);
+}
+
+static int
+pccard_teardown_intr(device_t dev, device_t child, struct resource *r,
+ void *cookie)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+ struct pccard_ivar *ivar = PCCARD_IVAR(child);
+ struct pccard_function *func = ivar->fcn;
+ int ret;
+
+ if (pccard_mfc(sc)) {
+ pccard_ccr_write(func, PCCARD_CCR_OPTION,
+ pccard_ccr_read(func, PCCARD_CCR_OPTION) &
+ ~PCCARD_CCR_OPTION_IREQ_ENABLE);
+ }
+ ret = bus_generic_teardown_intr(dev, child, r, cookie);
+ if (ret == 0) {
+ func->intr_handler = NULL;
+ func->intr_handler_arg = NULL;
+ func->intr_handler_cookie = NULL;
+ }
+
+ return (ret);
+}
+
+static int
+pccard_activate_resource(device_t brdev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct pccard_ivar *ivar = PCCARD_IVAR(child);
+ struct pccard_function *pf = ivar->fcn;
+
+ switch(type) {
+ case SYS_RES_IOPORT:
+ /*
+ * We need to adjust IOBASE[01] and IOSIZE if we're an MFC
+ * card.
+ */
+ if (pccard_mfc(pf->sc))
+ pccard_mfc_adjust_iobase(pf, rman_get_start(r), 0,
+ rman_get_size(r));
+ break;
+ default:
+ break;
+ }
+ return (bus_generic_activate_resource(brdev, child, type, rid, r));
+}
+
+static int
+pccard_deactivate_resource(device_t brdev, device_t child, int type,
+ int rid, struct resource *r)
+{
+ /* XXX undo pccard_activate_resource? XXX */
+ return (bus_generic_deactivate_resource(brdev, child, type, rid, r));
+}
+
+static device_method_t pccard_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pccard_probe),
+ DEVMETHOD(device_attach, pccard_attach),
+ DEVMETHOD(device_detach, pccard_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, pccard_suspend),
+ DEVMETHOD(device_resume, pccard_resume),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, pccard_print_child),
+ DEVMETHOD(bus_driver_added, pccard_driver_added),
+ DEVMETHOD(bus_child_detached, pccard_child_detached),
+ DEVMETHOD(bus_alloc_resource, pccard_alloc_resource),
+ DEVMETHOD(bus_release_resource, pccard_release_resource),
+ DEVMETHOD(bus_activate_resource, pccard_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, pccard_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, pccard_setup_intr),
+ DEVMETHOD(bus_teardown_intr, pccard_teardown_intr),
+ DEVMETHOD(bus_set_resource, pccard_set_resource),
+ DEVMETHOD(bus_get_resource, pccard_get_resource),
+ DEVMETHOD(bus_delete_resource, pccard_delete_resource),
+ DEVMETHOD(bus_probe_nomatch, pccard_probe_nomatch),
+ DEVMETHOD(bus_read_ivar, pccard_read_ivar),
+ DEVMETHOD(bus_child_pnpinfo_str, pccard_child_pnpinfo_str),
+ DEVMETHOD(bus_child_location_str, pccard_child_location_str),
+
+ /* Card Interface */
+ DEVMETHOD(card_set_res_flags, pccard_set_res_flags),
+ DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset),
+ DEVMETHOD(card_attach_card, pccard_attach_card),
+ DEVMETHOD(card_detach_card, pccard_detach_card),
+ DEVMETHOD(card_compat_do_probe, pccard_compat_do_probe),
+ DEVMETHOD(card_compat_do_attach, pccard_compat_do_attach),
+ DEVMETHOD(card_do_product_lookup, pccard_do_product_lookup),
+
+ { 0, 0 }
+};
+
+static driver_t pccard_driver = {
+ "pccard",
+ pccard_methods,
+ sizeof(struct pccard_softc)
+};
+
+devclass_t pccard_devclass;
+
+/* Maybe we need to have a slot device? */
+DRIVER_MODULE(pccard, pcic, pccard_driver, pccard_devclass, 0, 0);
+DRIVER_MODULE(pccard, cbb, pccard_driver, pccard_devclass, 0, 0);
+MODULE_VERSION(pccard, 1);
diff --git a/sys/dev/pccard/pccard_cis.c b/sys/dev/pccard/pccard_cis.c
new file mode 100644
index 0000000..9c2307f
--- /dev/null
+++ b/sys/dev/pccard/pccard_cis.c
@@ -0,0 +1,1293 @@
+/* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps 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/pccardvar.h>
+#include <dev/pccard/pccard_cis.h>
+
+#include "card_if.h"
+
+extern int pccard_cis_debug;
+
+#define PCCARDCISDEBUG
+#ifdef PCCARDCISDEBUG
+#define DPRINTF(arg) do { if (pccard_cis_debug) printf arg; } while (0)
+#define DEVPRINTF(arg) do { if (pccard_cis_debug) device_printf arg; } while (0)
+#else
+#define DPRINTF(arg)
+#define DEVPRINTF(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(struct pccard_tuple *, void *);
+static int decode_funce(struct pccard_tuple *, struct pccard_function *);
+
+void
+pccard_read_cis(struct pccard_softc *sc)
+{
+ struct cis_state state;
+
+ bzero(&state, sizeof state);
+
+ 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 = PCMCIA_VENDOR_INVALID;
+ state.card->product = PCMCIA_PRODUCT_INVALID;
+ STAILQ_INIT(&state.card->pf_head);
+
+ state.pf = NULL;
+
+ if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
+ &state) == -1)
+ state.card->error++;
+}
+
+int
+pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
+ void *arg)
+{
+ struct resource *res;
+ int rid;
+ struct pccard_tuple tuple;
+ int longlink_present;
+ int longlink_common;
+ u_long longlink_addr; /* Type suspect */
+ int mfc_count;
+ int mfc_index;
+#ifdef PCCARDCISDEBUG
+ int cis_none_cnt = 10; /* Only report 10 CIS_NONEs */
+#endif
+ struct {
+ int common;
+ u_long addr;
+ } mfc[256 / 5];
+ int ret;
+
+ ret = 0;
+
+ /* allocate some memory */
+
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
+ PCCARD_CIS_SIZE, RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "can't alloc memory to read attributes\n");
+ return -1;
+ }
+ CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
+ rid, PCCARD_A_MEM_ATTR);
+ tuple.memt = rman_get_bustag(res);
+ tuple.memh = rman_get_bushandle(res);
+ tuple.ptr = 0;
+
+ DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n",
+ (unsigned int) tuple.memh, rman_get_start(res)));
+
+ tuple.mult = 2;
+
+ longlink_present = 1;
+ longlink_common = 1;
+ longlink_addr = 0;
+
+ mfc_count = 0;
+ mfc_index = 0;
+
+ DEVPRINTF((dev, "CIS tuple chain:\n"));
+
+ while (1) {
+ while (1) {
+ /*
+ * Perform boundary check for insane cards.
+ * If CIS is too long, simulate CIS end.
+ * (This check may not be sufficient for
+ * malicious cards.)
+ */
+ if (tuple.mult * tuple.ptr >= PCCARD_CIS_SIZE - 1
+ - 32 /* ad hoc value */ ) {
+ printf("CIS is too long -- truncating\n");
+ tuple.code = CISTPL_END;
+ } else {
+ /* get the tuple code */
+ tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
+ }
+
+ /* two special-case tuples */
+
+ if (tuple.code == CISTPL_NULL) {
+#ifdef PCCARDCISDEBUG
+ if (cis_none_cnt > 0)
+ DPRINTF(("CISTPL_NONE\n 00\n"));
+ else if (cis_none_cnt == 0)
+ DPRINTF(("TOO MANY CIS_NONE\n"));
+ cis_none_cnt--;
+#endif
+ tuple.ptr++;
+ continue;
+ } else if (tuple.code == 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)) {
+ 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 CISTPL_LONGLINK_A:
+ case 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 ==
+ 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 CISTPL_NO_LINK:
+ longlink_present = 0;
+ DPRINTF(("CISTPL_NO_LINK\n"));
+ break;
+ case 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;
+
+ offset = (uint16_t)
+ 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) >=
+ 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));
+ device_printf(dev,
+ "CIS checksum failed\n");
+#if 0
+ /*
+ * XXX Some working cards have
+ * XXX bad checksums!!
+ */
+ ret = -1;
+#endif
+ } else {
+ DPRINTF((" ok\n"));
+ }
+ }
+ break;
+ case CISTPL_LONGLINK_MFC:
+ if (tuple.length < 1) {
+ DPRINTF(("CISTPL_LONGLINK_MFC too "
+ "short %d\n", tuple.length));
+ break;
+ }
+ if (((tuple.length - 1) % 5) != 0) {
+ DPRINTF(("CISTPL_LONGLINK_MFC bogus "
+ "length %d\n", tuple.length));
+ break;
+ }
+ /*
+ * this is kind of ad hoc, as I don't have
+ * any real documentation
+ */
+ {
+ int i, tmp_count;
+
+ /*
+ * put count into tmp var so that
+ * if we have to bail (because it's
+ * a bogus count) it won't be
+ * remembered for later use.
+ */
+ tmp_count =
+ pccard_tuple_read_1(&tuple, 0);
+
+ DPRINTF(("CISTPL_LONGLINK_MFC %d",
+ tmp_count));
+
+ /*
+ * make _sure_ it's the right size;
+ * if too short, it may be a weird
+ * (unknown/undefined) format
+ */
+ if (tuple.length != (tmp_count*5 + 1)) {
+ DPRINTF((" bogus length %d\n",
+ tuple.length));
+ break;
+ }
+ /*
+ * sanity check for a programming
+ * error which is difficult to find
+ * when debugging.
+ */
+ if (tmp_count >
+ howmany(sizeof mfc, sizeof mfc[0]))
+ panic("CISTPL_LONGLINK_MFC mfc "
+ "count would blow stack");
+ mfc_count = tmp_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)) {
+ 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) {
+ if (longlink_present) {
+ CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
+ SYS_RES_MEMORY, rid, longlink_common ?
+ PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
+ DPRINTF(("cis mem map %x\n",
+ (unsigned int) tuple.memh));
+ tuple.mult = longlink_common ? 1 : 2;
+ tuple.ptr = longlink_addr;
+ longlink_present = 0;
+ longlink_common = 1;
+ longlink_addr = 0;
+ } else if (mfc_count && (mfc_index < mfc_count)) {
+ CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
+ SYS_RES_MEMORY, rid, mfc[mfc_index].common
+ ? PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
+ DPRINTF(("cis mem map %x\n",
+ (unsigned int) tuple.memh));
+ /* set parse state, and point at the next one */
+ tuple.mult = mfc[mfc_index].common ? 1 : 2;
+ tuple.ptr = mfc[mfc_index].addr;
+ mfc_index++;
+ } else {
+ goto done;
+ }
+
+ /* make sure that the link is valid */
+ tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
+ if (tuple.code != 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;
+ }
+ }
+
+done:
+ bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
+
+ return (ret);
+}
+
+/* XXX this is incredibly verbose. Not sure what trt is */
+
+void
+pccard_print_cis(device_t dev)
+{
+ struct pccard_softc *sc = PCCARD_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 %x mask %x\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", cfe->iospace[i].start);
+ if (cfe->iospace[i].length)
+ printf("-%lx",
+ 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",
+ cfe->memspace[i].cardaddr);
+ if (cfe->memspace[i].length)
+ printf("-%lx",
+ cfe->memspace[i].cardaddr +
+ cfe->memspace[i].length - 1);
+ if (cfe->memspace[i].hostaddr)
+ printf("@%lx",
+ 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(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 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 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 CISTPL_DEVICE:
+ case 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 == 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 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 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);
+ /*
+ * This is for xe driver. But not limited to that driver.
+ * In PC Card Standard,
+ * Manufacturer ID: 2byte.
+ * Product ID: typically 2bytes, but there's no limit on its
+ * size. prodext is a two byte field, so maybe we should
+ * also handle the '6' case. So far no cards have surfaced
+ * with a length of '6'.
+ */
+ if (tuple->length == 5 ) {
+ state->card->prodext = pccard_tuple_read_1(tuple, 4);
+ }
+ DPRINTF(("CISTPL_MANFID\n"));
+ break;
+ case 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 | M_ZERO);
+ 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 CISTPL_FUNCE:
+ if (state->pf == NULL || state->pf->function <= 0) {
+ DPRINTF(("CISTPL_FUNCE is not followed by "
+ "valid CISTPL_FUNCID\n"));
+ break;
+ }
+ if (tuple->length >= 2) {
+ decode_funce(tuple, state->pf);
+ }
+ DPRINTF(("CISTPL_FUNCE\n"));
+ break;
+ case 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 | M_ZERO);
+ 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 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++;
+ cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
+ | PCCARD_CFE_RDYBSY_ACTIVE
+ | PCCARD_CFE_WP_ACTIVE
+ | PCCARD_CFE_BVD_ACTIVE);
+ 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++;
+ cfe->flags &=
+ ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
+ 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++;
+ cfe->flags &= ~(PCCARD_CFE_IRQSHARE
+ | PCCARD_CFE_IRQPULSE
+ | PCCARD_CFE_IRQLEVEL);
+ 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) + 1;
+
+ 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++;
+ cfe->flags &= ~(PCCARD_CFE_POWERDOWN
+ | PCCARD_CFE_READONLY
+ | PCCARD_CFE_AUDIO);
+ 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);
+}
+
+static int
+decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf)
+{
+ int type = pccard_tuple_read_1(tuple, 0);
+
+ switch (pf->function) {
+ case PCCARD_FUNCTION_DISK:
+ if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
+ pf->pf_funce_disk_interface
+ = pccard_tuple_read_1(tuple, 1);
+ }
+ break;
+ case PCCARD_FUNCTION_NETWORK:
+ if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
+ int i;
+ int len = pccard_tuple_read_1(tuple, 1);
+ if (tuple->length < 2 + len || len > 8) {
+ /* tuple length not enough or nid too long */
+ break;
+ }
+ for (i = 0; i < len; i++) {
+ pf->pf_funce_lan_nid[i]
+ = pccard_tuple_read_1(tuple, i + 2);
+ }
+ pf->pf_funce_lan_nidlen = len;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/sys/dev/pccard/pccard_cis.h b/sys/dev/pccard/pccard_cis.h
new file mode 100644
index 0000000..9c8221c
--- /dev/null
+++ b/sys/dev/pccard/pccard_cis.h
@@ -0,0 +1,203 @@
+/* $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.
+ */
+
+/*
+ * CIS Tuples */
+
+/* Layer 1 Basic Compatibility Tuples */
+#define CISTPL_NULL 0x00
+#define 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 CISTPL_LONGLINK_CB 0x02
+#define CISTPL_INDIRECT 0x03
+#define CISTPL_CONFIG_CB 0x04
+#define CISTPL_CFTABLE_ENTRY_CB 0x05
+#define CISTPL_LONGLINK_MFC 0x06
+#define PCCARD_MFC_MEM_ATTR 0x00
+#define PCCARD_MFC_MEM_COMMON 0x01
+#define CISTPL_BAR 0x07
+#define CISTPL_PWR_MGMNT 0x08
+#define CISTPL_EXTDEVICE 0x09
+
+#define CISTPL_CHECKSUM 0x10
+#define CISTPL_LONGLINK_A 0x11
+#define CISTPL_LONGLINK_C 0x12
+#define CISTPL_LINKTARGET 0x13
+#define CISTPL_NO_LINK 0x14
+#define CISTPL_VERS_1 0x15
+#define CISTPL_ALTSTR 0x16
+#define CISTPL_DEVICE_A 0x17
+#define CISTPL_JEDEC_C 0x18
+#define CISTPL_JEDEC_A 0x19
+#define 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 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 CISTPL_DEVICE_OC 0x1C
+#define CISTPL_DEVICE_OA 0x1D
+#define CISTPL_DEVICE_GEO 0x1E
+#define CISTPL_DEVICE_GEO_A 0x1F
+#define CISTPL_MANFID 0x20
+#define 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 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 CISTPL_END 0xFF
+
+/* Layer 2 Data Recording Format Tuples */
+
+#define CISTPL_SWIL 0x23
+/* #define CISTPL_RESERVED 0x24-0x3F */
+#define CISTPL_VERS_2 0x40
+#define CISTPL_FORMAT 0x41
+#define CISTPL_GEOMETRY 0x42
+#define CISTPL_BYTEORDER 0x43
+#define CISTPL_DATE 0x44
+#define CISTPL_BATTERY 0x45
+#define CISTPL_FORAMT_A 0x47
+
+/* Layer 3 Data Organization Tuples */
+
+#define CISTPL_ORG 0x46
+/* #define CISTPL_RESERVED 0x47-0x7F */
+
+/* Layer 4 System-Specific Standard Tuples */
+
+/* #define CISTPL_RESERVED 0x80-0x8F */
+#define CISTPL_SPCL 0x90
+/* #define CISTPL_RESERVED 0x90-0xFE */
+
+#define CISTPL_GENERIC -1
diff --git a/sys/dev/pccard/pccard_cis_quirks.c b/sys/dev/pccard/pccard_cis_quirks.c
new file mode 100644
index 0000000..c491cb2
--- /dev/null
+++ b/sys/dev/pccard/pccard_cis_quirks.c
@@ -0,0 +1,288 @@
+/* $NetBSD: pcmcia_cis_quirks.c,v 1.6 2000/04/12 21:07:55 scw Exp $ */
+
+#include <sys/cdefs.h>
+__FBSDID("$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/pccardvar.h>
+#include <dev/pccard/pccard_cis.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_3ccfem556bi_func0 = {
+ 0, /* function number */
+ PCCARD_FUNCTION_NETWORK,
+ 0x07, /* last cfe number */
+ 0x1000, /* ccr_base */
+ 0x267, /* ccr_mask */
+};
+
+static struct pccard_config_entry pccard_3ccfem556bi_func0_cfe0 = {
+ 0x07, /* cfe number */
+ PCCARD_CFE_IO8 | PCCARD_CFE_IO16 | PCCARD_CFE_IRQLEVEL,
+ PCCARD_IFTYPE_IO,
+ 1, /* num_iospace */
+ 5, /* iomask */
+ { { 0x0020, 0 } }, /* iospace */
+ 0xffff, /* irqmask */
+ 0, /* num_memspace */
+ { }, /* memspace */
+ 0, /* maxtwins */
+};
+
+static struct pccard_function pccard_3ccfem556bi_func1 = {
+ 1, /* function number */
+ PCCARD_FUNCTION_SERIAL,
+ 0x27, /* last cfe number */
+ 0x1100, /* ccr_base */
+ 0x277, /* ccr_mask */
+};
+
+static struct pccard_config_entry pccard_3ccfem556bi_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_function pccard_ndc_nd5100_func0 = {
+ 0, /* function number */
+ PCCARD_FUNCTION_NETWORK,
+ 0x23, /* last cfe number */
+ 0x3f8, /* ccr_base */
+ 0x3, /* ccr_mask */
+};
+
+static struct pccard_config_entry pccard_ndc_nd5100_func0_cfe0 = {
+ 0x20, /* cfe number */
+ PCCARD_CFE_MWAIT_REQUIRED | PCCARD_CFE_IO16 | PCCARD_CFE_IRQLEVEL,
+ 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[] = {
+ { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556, PCMCIA_CIS_INVALID,
+ &pccard_3cxem556_func0, &pccard_3cxem556_func0_cfe0 },
+ { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556, PCMCIA_CIS_INVALID,
+ &pccard_3cxem556_func1, &pccard_3cxem556_func1_cfe0 },
+ { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT, PCMCIA_CIS_INVALID,
+ &pccard_3cxem556_func0, &pccard_3cxem556_func0_cfe0 },
+ { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT, PCMCIA_CIS_INVALID,
+ &pccard_3cxem556_func1, &pccard_3cxem556_func1_cfe0 },
+ { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
+ PCMCIA_CIS_INVALID,
+ &pccard_3ccfem556bi_func0, &pccard_3ccfem556bi_func0_cfe0 },
+ { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
+ PCMCIA_CIS_INVALID,
+ &pccard_3ccfem556bi_func1, &pccard_3ccfem556bi_func1_cfe0 },
+ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, PCMCIA_CIS_SVEC_LANCARD,
+ &pccard_sveclancard_func0, &pccard_sveclancard_func0_cfe0 },
+ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, PCMCIA_CIS_NDC_ND5100_E,
+ &pccard_ndc_nd5100_func0, &pccard_ndc_nd5100_func0_cfe0 },
+};
+
+static int n_pccard_cis_quirks =
+ sizeof(pccard_cis_quirks)/sizeof(pccard_cis_quirks[0]);
+
+static int
+pccard_cis_quirk_match(struct pccard_softc *sc, struct pccard_cis_quirk *q)
+{
+ if ((sc->card.manufacturer == q->manufacturer) &&
+ (sc->card.product == q->product) &&
+ (((sc->card.manufacturer != PCMCIA_VENDOR_INVALID) &&
+ (sc->card.product != PCMCIA_PRODUCT_INVALID)) ||
+ ((sc->card.manufacturer == PCMCIA_VENDOR_INVALID) &&
+ (sc->card.product == PCMCIA_PRODUCT_INVALID) &&
+ sc->card.cis1_info[0] &&
+ (strcmp(sc->card.cis1_info[0], q->cis1_info[0]) == 0) &&
+ sc->card.cis1_info[1] &&
+ (strcmp(sc->card.cis1_info[1], q->cis1_info[1]) == 0))))
+ return (1);
+ return (0);
+}
+
+void pccard_check_cis_quirks(device_t dev)
+{
+ struct pccard_softc *sc = PCCARD_SOFTC(dev);
+ int wiped = 0;
+ int i, j;
+ struct pccard_function *pf, *pf_next, *pf_last;
+ struct pccard_config_entry *cfe, *cfe_next;
+ struct pccard_cis_quirk *q;
+
+ pf = NULL;
+ pf_last = NULL;
+
+ for (i=0; i<n_pccard_cis_quirks; i++) {
+ q = &pccard_cis_quirks[i];
+ if (!pccard_cis_quirk_match(sc, q))
+ continue;
+ if (!wiped) {
+ if (bootverbose) {
+ 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 == q->pf) {
+ cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+ *cfe = *q->cfe;
+ STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
+ } else {
+ pf = malloc(sizeof(*pf), M_DEVBUF, M_NOWAIT);
+ *pf = *q->pf;
+ STAILQ_INIT(&pf->cfe_head);
+ cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+ *cfe = *q->cfe;
+ STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
+ STAILQ_INSERT_TAIL(&sc->card.pf_head, pf, pf_list);
+ pf_last = q->pf;
+ }
+ }
+}
diff --git a/sys/dev/pccard/pccarddevs b/sys/dev/pccard/pccarddevs
new file mode 100644
index 0000000..c59a62d
--- /dev/null
+++ b/sys/dev/pccard/pccarddevs
@@ -0,0 +1,611 @@
+$FreeBSD$
+/* $NetBSD: pcmciadevs,v 1.186 2003/09/16 08:26:37 onoe Exp $ */
+/* $OpenBSD: pcmciadevs,v 1.93 2002/06/21 08:31:10 henning Exp $ */
+
+/*-
+ * 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, sorted by numeric ID.
+ */
+
+vendor FUJITSU 0x0004 Fujitsu Corporation
+vendor INTERSIL 0x000b Intersil
+vendor PANASONIC 0x0032 Matsushita Electric Industrial Co.
+vendor SANDISK 0x0045 Sandisk Corporation
+vendor NEWMEDIA 0x0057 New Media Corporation
+vendor INTEL 0x0089 Intel
+vendor IBM 0x00a4 IBM Corporation
+vendor SHARP 0x00b0 Sharp Corporation
+vendor 3COM 0x0101 3Com Corporation
+vendor MEGAHERTZ 0x0102 Megahertz Corporation
+vendor SOCKET 0x0104 Socket Communications
+vendor TDK 0x0105 TDK Corporation
+vendor XIRCOM 0x0105 Xircom
+vendor SMC 0x0108 Standard Microsystems Corporation
+vendor MOTOROLA 0x0109 Motorola Corporation
+vendor NI 0x010b National Instruments
+vendor QLOGIC 0x0114 QLogic
+vendor USROBOTICS 0x0115 US Robotics Corporation
+vendor OLICOM 0x0121 Olicom
+vendor PROXIM 0x0126 Proxim
+vendor DSPSI 0x0128 DSP Solutions, Inc
+vendor ADAPTEC 0x012f Adaptec Corporation
+vendor QUATECH 0x0137 Quatech
+vendor COMPAQ 0x0138 Compaq
+vendor OSITECH 0x0140 Ositech
+vendor DLINK_2 0x0143 D-Link
+vendor DLINK_3 0x0149 D-Link
+vendor LINKSYS 0x0149 Linksys Corporation
+vendor NETGEAR 0x0149 Netgear
+vendor SIMPLETECH 0x014d Simple Technology
+vendor SYMBOL2 0x014d Symbol
+vendor LUCENT 0x0156 Lucent Technologies
+vendor GEMPLUS 0x0157 Gemplus
+vendor AIRONET 0x015f Aironet Wireless Communications
+vendor ERICSSON 0x016b Ericsson
+vendor PSION 0x016c Psion
+vendor COMPAQ2 0x0183 Compaq
+vendor PARALON 0x0183 Paralon Technologies Inc
+vendor KINGSTON 0x0186 Kingston
+vendor MELCO 0x018a Melco Corporation
+vendor DAYNA 0x0194 Dayna Corporation
+vendor RAYTHEON 0x01a6 Raytheon
+vendor IODATA 0x01bf I-O DATA
+vendor BAY 0x01eb Bay Networks
+vendor FARALLON 0x0200 Farallon Communications
+vendor TELECOMDEVICE 0x021b Telecom Device
+vendor NOKIA 0x023d Nokia Communications
+vendor SAMSUNG 0x0250 Samsung
+vendor HWN 0x0261 Home Wireless Networks
+vendor ARTEM 0x0268 ARtem
+vendor SYMBOL 0x026c Symbol
+vendor BUFFALO 0x026f BUFFALO (Melco Corporation)
+vendor BROMAX 0x0274 Bromax communications, Inc
+vendor IODATA2 0x028a I-O DATA
+vendor ASUS 0x02aa ASUS
+vendor SIEMENS 0x02ac Siemens
+vendor MICROSOFT 0x02d2 Microsoft Corporation
+
+/*
+ * The following vendor IDs are byte-swapped from what the company is assigned.
+ */
+vendor NWN 0x0602 No Wires Needed
+vendor BREEZECOM 0x0a02 BreezeCOM
+vendor LASAT 0x3401 Lasat Communications A/S
+vendor BONDWELL 0x3b01 Bondwell
+vendor LEXARMEDIA 0x4e01 Lexar Media
+vendor COMPEX 0x8a01 Compex Corporation
+vendor ZONET 0x8a01 Zonet Technology Inc.
+vendor ELSA 0xd601 Elsa
+
+/*
+ * The following vendor IDs are not, as far as I can tell, actually
+ * assigned to these people. However, all the ones starting with '0xc'
+ * look coherent enough that maybe somebody other than PCMCIA is
+ * assigning numbers in that range.
+ */
+vendor NEWMEDIA2 0x10cd NewMedia
+vendor PLANEX_2 0x14ea PLANEX
+vendor ACTIONTEC 0x1668 ACTIONTEC
+vendor AIRVAST 0x50c2 AirVast Technology
+vendor ARCHOS 0x5241 Archos
+vendor DUAL 0x890f Dual
+vendor EDIMAX 0x890f Edimax Technology Inc.
+vendor CONTEC 0xc001 Contec
+vendor MACNICA 0xc00b MACNICA
+vendor ROLAND 0xc00c Roland
+vendor COREGA2 0xc00f Corega K.K.
+vendor ALLIEDTELESIS 0xc00f Allied Telesis K.K.
+vendor HAGIWARASYSCOM 0xc012 Hagiwara SYS-COM
+vendor RATOC 0xc015 RATOC System Inc.
+vendor WORKBIT 0xc024 WORKBIT
+vendor EMTAC 0xc250 EMTAC Technology Corporation
+
+/*
+ * List of known products. Grouped by vendor, sorted by number within the
+ * group.
+ */
+
+/* 3COM Products */
+product 3COM 3CRWE737A 0x0001 3Com AirConnect Wireless LAN
+product 3COM 3CXM056BNW 0x002f 3Com/NoteWorthy 3CXM056-BNW 56K Modem
+product 3COM 3CXEM556 0x0035 3Com/Megahertz 3CXEM556 Ethernet/Modem
+product 3COM 3CXEM556INT 0x003d 3Com/Megahertz 3CXEM556-INT Ethernet/Modem
+product 3COM 3CCFEM556BI 0x0556 3Com/Megahertz 3CCFEM556BI Ethernet/Modem
+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 3CRWE777A 0x0777 3Com 3CRWE777A Airconnect
+product 3COM 3C1 0x0cf1 3Com Megahertz 3C1 10Mbps LAN CF+ Card
+product 3COM 3CRWE62092A 0x2092 3Com 3CRWE62092A Wireless LAN
+
+/* ACTIONTEC Products */
+product ACTIONTEC PRISM 0x0101 PRISM Wireless LAN PC Card
+
+/* Adaptec Products */
+product ADAPTEC APA1460 0x0001 Adaptec APA-1460 SlimSCSI
+product ADAPTEC APA1460A 0x0002 Adaptec APA-1460A SlimSCSI
+
+/* Aironet */
+product AIRONET PC4500 0x0005 Aironet PC4500 Wireless LAN Adapter
+product AIRONET PC4800 0x0007 Aironet PC4800 Wireless LAN Adapter
+product AIRONET 350 0x000a Aironet 350 Wireless LAN Adapter
+
+/* AirVast */
+product AIRVAST WN_100 0x7300 AirVast WN-100
+
+/* Allied Telesis K.K. */
+product ALLIEDTELESIS LA_PCM 0x0002 Allied Telesis LA-PCM
+
+/* Archos */
+product ARCHOS ARC_ATAPI 0x0043 MiniCD
+
+/* ARtem */
+product ARTEM ONAIR 0x0001 ARtem OnAir
+
+/* ASUS WL-100 */
+product ASUS WL100 0x0002 ASUS SpaceLink WL-100 Wireless LAN
+
+/* Bay Networks */
+product BAY STACK_650 0x0804 BayStack 650 Wireless LAN
+product BAY SURFER_PRO 0x0806 AirSurfer Pro Wireless LAN
+product BAY STACK_660 0x0807 BayStack 660 Wireless LAN
+product BAY EMOBILITY_11B 0x080a e-Mobility 11Mb Wireless LAN
+
+/* Bondwell */
+product BONDWELL B236 0x0000 Game Card Joystick
+
+/* BreezeCOM */
+product BREEZECOM BREEZENET 0x0102 BreezeCOM BreezeNET
+
+/* Bromax Communications, Inc (Linksys OEM) */
+product BROMAX IWN 0x1612 Instant Wireless Network PC Card
+product BROMAX IWN3 0x1613 Instant Wireless Network PC Card, Versin 3
+product BROMAX WCF11 0x3301 Instant Wireless Network CF Card
+
+/* BUFFALO */
+product BUFFALO LPC3_CLX 0x0301 BUFFALO LPC3-CLX Ethernet Adapter
+product BUFFALO WLI_PCM_S11 0x0305 BUFFALO AirStation 11Mbps WLAN
+product BUFFALO LPC_CF_CLT 0x0307 BUFFALO LPC-CF-CLT
+product BUFFALO LPC3_CLT 0x030a BUFFALO LPC3-CLT Ethernet Adapter
+product BUFFALO WLI_CF_S11G 0x030b BUFFALO AirStation 11Mbps CF WLAN
+
+/* Compaq Products */
+product COMPAQ NC5004 0x0002 Compaq Agency NC5004 Wireless Card
+product COMPAQ2 CPQ_10_100 0x010a Compaq Netelligent 10/100 Ethernet
+
+/* Compex Products */
+product COMPEX AMP_WIRELESS 0x0066 AMP
+product COMPEX LINKPORT_ENET_B 0x0100 Compex Linkport ENET-B Ethernet
+
+/* Contec C-NET(PC) */
+product CONTEC CNETPC 0x0000 Contec C-NET(PC)C
+product CONTEC FX_DS110_PCC 0x0008 Contec FLEXLAN/FX-DS110-PCC
+
+/* 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
+
+/* D-Link Products */
+product DLINK_2 DMF560TX 0xc0ab D-Link DMF-650TX
+
+/* DSP Solutions, Inc. (Megahertz OEM) */
+product DSPSI XJEM1144 0x0101 Megahertz X-JACK
+product DSPSI XJACK 0x0103 Megahertz X-JACK Ethernet
+
+/* Dual */
+product DUAL NE2000 0x0100 Dual NE2000
+
+/* Edimax Products */
+product EDIMAX EP4000A 0x0100 Edimax EP4000A
+
+/* ELSA Products */
+product ELSA MC2_IEEE 0x0001 AirLancer MC-2 IEEE
+product ELSA XI300_IEEE 0x0002 XI300 Wireless LAN
+product ELSA XI800_IEEE 0x0004 XI800 CF Wireless LAN
+product ELSA XI325_IEEE 0x0005 XI325 Wireless LAN
+
+/* EMTAC */
+product EMTAC WLAN 0x0002 EMTAC A2424i 11Mbps WLAN Card
+
+/* Ericsson */
+product ERICSSON WIRELESSLAN 0x0001 DSSS Wireless LAN PC Card
+
+/* Farallon */
+product FARALLON SKYLINE 0x0a01 SkyLINE Wireless
+
+/* Fujutsu Products */
+product FUJITSU SCSI600 0x0401 Fujitsu SCSI 600 Interface
+product FUJITSU LA10S 0x1003 Fujitsu Compact Flash Ethernet
+product FUJITSU LA501 0x2000 Fujitsu Towa LA501 Ethernet
+product FUJITSU WL110 0x2003 PEGA-WL110 Wireless LAN
+
+/* Gemplus */
+product GEMPLUS GPR400 0x3004 GPR400 Smartcard Reader
+
+/* Home Wireless Networks */
+product HWN AIRWAY80211 0x0002 HWN Airway Wireless PCMCIA Card
+
+/* IBM Products */
+product IBM MICRODRIVE 0x0000 IBM Microdrive
+product IBM 3270 0x0001 IBM 3270 Emulation
+product IBM INFOMOVER 0x0002 IBM InfoMover
+product IBM 5250 0x000b IBM 5250 Emulation
+product IBM TROPIC 0x001e IBM Token Ring 4/16
+product IBM SCSI 0x0026 IBM SCSI PCMCIA
+product IBM PORTABLE_CDROM 0x002d IBM PCMCIA Portable CD-ROM Drive
+product IBM HOME_AND_AWAY 0x002e IBM Home and Away Modem
+product IBM WIRELESS_LAN_ENTRY 0x0032 IBM Wireless LAN Entry
+product IBM SMART_CAPTURE_II 0x003c IBM Smart Capture Card II
+product IBM ETHERJET 0x003f IBM EtherJet Ethernet
+
+/* Intel Products */
+product INTEL PRO_WLAN_2011 0x0001 Intel PRO/Wireless 2011 LAN PC Card
+product INTEL EEPRO100 0x010a Intel EtherExpress PRO/100
+product INTEL ETHEREXPPRO 0x0301 Intel EtherExpress Pro PCMCIA Card
+
+/* Intersil */
+/* Note: The following likely is an OEM card under a different Intersil name */
+product INTERSIL MA401RA 0x7300 Netgear MA401RA
+
+/* I-O DATA */
+product IODATA PCLATE 0x2216 I-O DATA PCLA/TE
+product IODATA2 WNB11PCM 0x0002 I-O DATA WN-B11/PCM
+product IODATA2 WCF12 0x0673 Wireless CF Card
+
+/* Kingston Products */
+product KINGSTON KNE2 0x0100 Kingston KNE-PC2 Ethernet
+
+/* Lasat Products */
+product LASAT CREDIT_288 0x2811 Lasat Credit 288 Modem
+
+/* Lexar Media */
+product LEXARMEDIA COMPACTFLASH 0x0100 Lexar Media CompactFlash
+
+/* Linksys corporation */
+product LINKSYS TRUST_COMBO_ECARD 0x021b Trust (Linksys) Combo EthernetCard
+product LINKSYS ETHERFAST 0x0230 Linksys Etherfast 10/100 Ethernet
+product LINKSYS ECARD_1 0x0265 Linksys EthernetCard or D-Link DE-650
+product LINKSYS COMBO_ECARD 0xc1ab Linksys Combo EthernetCard
+
+/* Lucent WaveLAN/IEEE */
+product LUCENT WAVELAN_IEEE 0x0002 WaveLAN/IEEE
+
+/* MACNICA */
+product MACNICA ME1_JEIDA 0x3300 MACNICA ME1 for JEIDA
+product MACNICA MPS110 0xa041 MACNICA Miracle SCSI-II mPS110
+
+/* Megahertz Products */
+product MEGAHERTZ XJEM3336 0x0006 Megahertz X-JACK Ethernet Modem
+product MEGAHERTZ XJ4288 0x0023 Megahertz XJ4288 Modem
+product MEGAHERTZ XJ4336 0x0027 Megahertz XJ4336 Modem
+product MEGAHERTZ XJ5560 0x0034 Megahertz X-JACK 56kbps Modem
+
+/* Melco Products */
+product MELCO LPC3_TX 0xc1ab Melco LPC3-TX
+product MELCO LPC3_CLX 0x0301 Melco LPC3-CLX Ethernet Adapter
+
+/* Microsoft Products */
+product MICROSOFT MN_520 0x0001 Microsoft MN-520 WLAN Card
+
+/* Motorola Products */
+product MOTOROLA POWER144 0x0105 Motorola Power 14.4 Modem
+product MOTOROLA PM100C 0x0302 Motorola Personal Messenger 100C CDPD Modem
+product MOTOROLA MONTANA_336 0x0505 Motorola Montana 33.6
+
+/* New Media Products */
+product NEWMEDIA BASICS 0x0019 New Media BASICS Ethernet
+product NEWMEDIA LANSURFER 0x0021 NewMedia LANSurfer
+product NEWMEDIA LIVEWIRE 0x1004 NewMedia LiveWire Ethernet LAN Adapter
+product NEWMEDIA MULTIMEDIA 0x100b NewMedia Multimedia
+product NEWMEDIA BUSTOASTER2 0xa002 New Media SCSI Bus Toaster
+product NEWMEDIA BUSTOASTER 0xc102 New Media SCSI Bus Toaster
+product NEWMEDIA BUSTOASTER3 0xd302 New Media SCSI Bus Toaster
+product NEWMEDIA WAVJAMMER 0xe005 NewMedia .WAVjammer
+product NEWMEDIA2 BUSTOASTER 0x0001 NewMedia BusToaster
+
+/* Netgear */
+product NETGEAR FA410TX 0x0230 Netgear FA410TX
+product NETGEAR FA410TXC 0x4530 Netgear FA410TXC
+product NETGEAR FA411 0x0411 Netgear FA411
+
+/* National Instruments */
+product NI PCMCIA_GPIB 0x4882 National Instruments PCMCIA-GPIB
+
+/* Nokia Products */
+product NOKIA C110_WLAN 0x1110 Nokia C110/C111
+product NOKIA C020_WLAN 0x20c0 Nokia C020 WLAN Card
+
+/* No Wires Needed */
+product NWN WLAN_550 0x0002 NWN 550 WLAN
+product NWN WLAN_1148 0x0003 NWN 1148 WLAN
+
+/* Olicom Products */
+product OLICOM TR 0x2132 GoCard Token Ring 16/4
+product OLICOM OC2220 0x2022 GoCard Ethernet
+product OLICOM OC2231 0x3122 GoCard Combo Eth/Modem 288
+product OLICOM OC2232 0x3222 GoCard Combo Eth/Modem 336
+
+/* Ositech Products */
+product OSITECH TRUMPCARD_SOD 0x0008 Ositech Seven of Diamonds Ethernet Card
+
+/* Panasonic Products */
+product PANASONIC KXLC002 0x0304 Panasonic 4X CD-ROM Interface Card
+product PANASONIC KXLC003 0x0504 Panasonic 8X CD-ROM Interface Card
+product PANASONIC KXLC004 0x0604 Panasonic KXL-810AN Interface Card
+product PANASONIC KXLC005 0x2704 Panasonic 16X CD-ROM Interface Card
+product PANASONIC KME 0x2604 Panasonic CD-R/RW Interface
+
+/* Planex */
+product PLANEX_2 GWNS11H 0xb001 Planex GW-NS11H
+
+/* Proxim */
+product PROXIM HARMONY 0x0002 Proxim HARMONY 80211B
+product PROXIM ROAMABOUT_2400FH 0x1058 Digital RoamAbout 2400FH
+product PROXIM RANGELAN2_7401 0x1158 Proxim RangeLAN2 7401
+product PROXIM RANGELANDS_8430 0x8000 Proxim RangeLAN-DS 8430
+
+/* Psion */
+product PSION GOLDCARD 0x0020 Psion Gold Card
+
+/* QLogic */
+product QLOGIC PC05 0x0104 Qlogic Fast SCSI
+
+/* Quatech */
+product QUATECH SPP_100 0x0003 Quatech Enhanced Parallel Port
+product QUATECH DSP_225 0x0008 Quatech Dual Serial Port
+
+/* RATOC System Inc. Products */
+/* Don't use because both cards have same product id */
+product RATOC REX_R280_9530 0x0001 RATOC REX-R280/REX-9530
+
+/* Raylink/WebGear */
+product RAYTHEON WLAN 0x0000 WLAN Adapter
+
+/* Roland */
+product ROLAND SCP55 0x0001 Roland SCP-55
+
+/* Samsung */
+product SAMSUNG SWL_2000N 0x0002 Samsung MagicLAN SWL-2000N
+
+/* Sandisk Products */
+product SANDISK SDCFB 0x0401 Sandisk CompactFlash Card
+
+/* Sharp Products */
+product SHARP PALDIO611S 0x0000 PALDIO 611S PC CARD
+
+/* Siemens */
+product SIEMENS SS1021 0x0002 Siemens SpeedStream 1021
+
+/* Simple Technology Products */
+product SIMPLETECH COMMUNICATOR288 0x0100 Simple Technology 28.8 Communicator
+/* Simpletech ID also used by Symbol */
+product SIMPLETECH SPECTRUM24 0x801 Symbol Spectrum24 WLAN Adapter
+
+/* Standard Microsystems Corporation Products */
+product SMC 8016 0x0105 SMC 8016 EtherCard
+product SMC EZCARD 0x8022 SMC EZCard 10 PCMCIA
+
+/* Socket Communications Products */
+product SOCKET EA_ETHER 0x0000 Socket Communications EA
+product SOCKET LP_WLAN_CF 0x0001 Socket Communications Low Power WLAN Card
+product SOCKET PAGECARD 0x0003 Socket Communications PageCard
+product SOCKET DUAL_RS232 0x0006 Socket Communications Dual RS232
+product SOCKET LP_ETHER 0x000d Socket Communications LP-E
+product SOCKET LP_ETHER_CF 0x0075 Socket Communications LP-E CF
+product SOCKET LP_ETH_10_100_CF 0x0145 Socket Communications 10/100 Ethernet
+
+/* Symbol */
+product SYMBOL LA4100 0x0001 Symbol Spectrum24 LA4100 Series WLAN
+
+/* TDK Products */
+product TDK LAK_CD011WL 0x0000 TDK LAK-CD011WL
+product TDK LAK_CD021BX 0x0200 TDK LAK-CD021BX Ethernet
+product TDK LAK_CF010 0x0900 TDK LAC-CF010
+product TDK DFL9610 0x0d0a TDK DFL9610 Ethernet & Digital Cellular
+product TDK C6500012 0x410a TDK ELSA MicroLink MC all
+product TDK LAK_CD031 0xc1ab TDK LAK-CD031 Ethernet
+
+/* Telecom Device */
+product TELECOMDEVICE TCD_HPC100 0x0202 Telecom Device TCD-HPC100
+
+/* US Robotics Products */
+product USROBOTICS WORLDPORT144 0x3330 US Robotics WorldPort 14.4 Modem
+
+/* WORKBIT Products */
+product WORKBIT ULTRA_NINJA_16 0x8006 WORKBIT Ultra Ninja-16 (16bit mode)
+
+/* Xircom Products */
+product XIRCOM CWE1130 0x0007 Xircom Wireless Ethernet Adapter
+product XIRCOM CE 0x0108 Xircom CreditCard Ethernet
+product XIRCOM CE3 0x010a Xircom CreditCard 10/100 Ethernet
+product XIRCOM CE2 0x010b Xircom CreditCard Ethernet II
+product XIRCOM XE2000 0x0153 Xircom XE2000 10/100 Ethernet
+product XIRCOM CNW_801 0x0801 Xircom CreditCard Netwave (Canada)
+product XIRCOM CNW_802 0x0802 Xircom CreditCard Netwave (US)
+product XIRCOM CT2 0x1101 Xircom CreditCard Token Ring II
+product XIRCOM CEM 0x110a Xircom CreditCard Ethernet + Modem
+product XIRCOM REM56 0x110a Xircom RealPort Ethernet 10/100 + Modem 56
+product XIRCOM CEM28 0x110b Xircom CreditCard Ethernet + Modem 28
+product XIRCOM CEM56 0x110b Xircom CreditCard Ethernet + Modem 56
+product XIRCOM CEM33 0x110d Xircom CreditCard Ethernet + Modem 33
+
+/* ZONET */
+product ZONET ZEN 0x0100 Zonet Zen 10/10
+
+/*
+ * Cards we know only by their cis, sorted by name.
+ */
+vendor AMBICOM -1 AmbiCom Inc
+vendor ACCTON -1 ACCTON
+vendor ADDTRON -1 Addtron
+vendor ARGOSY -1 ARGOSY
+vendor AMD -1 AMD
+vendor BILLIONTON -1 Billionton Systems Inc.
+vendor CNET -1 CNet
+vendor COREGA -1 Corega K.K.
+vendor DIGITAL -1 Digital Equipment Corporation
+vendor DLINK -1 D-Link
+vendor DYNALINK -1 DynaLink
+vendor EIGERLABS -1 Eiger labs,Inc.
+vendor EPSON -1 Seiko Epson Corporation
+vendor EXP -1 EXP Computer Inc
+vendor FUJITSU2 -1 Fujitsu
+vendor FUTUREDOMAIN -1 FutureDomain
+vendor FREECOM -1 Freecom
+vendor GEMTEK -1 Gem Tek
+vendor ICOM -1 ICOM Inc
+vendor INTERSIL2 -1 Intersil
+vendor IODATA3 -1 I-O DATA
+vendor LANTECH -1 Lantech Computer Company
+vendor MELCO2 -1 Melco Corporation
+vendor NAKAGAWAMETAL -1 NAKAGAWA METAL
+vendor NDC -1 NDC
+vendor NEC -1 NEC
+vendor OEM2 -1 Generic OEM
+vendor PLANET -1 Planet
+vendor PLANEX -1 Planex Communications Inc
+vendor PREMAX -1 Premax
+vendor RPTI -1 RPTI
+vendor SVEC -1 SVEC/Hawking Technology
+vendor SYNERGY21 -1 Synergy 21
+vendor TEAC -1 TEAC
+vendor TOSHIBA -1 TOSHIBA
+vendor WORKBIT2 -1 WORKBIT
+vendor YEDATA -1 Y-E DATA
+vendor YIS -1 YIS Corporation
+vendor ZOOM -1 ZOOM
+
+product ACCTON EN2212 { "ACCTON", "EN2212", NULL, NULL } Accton EN2212
+product ACCTON EN2216 { "ACCTON", "EN2216-PCMCIA-ETHERNET", "EN2216R01", NULL } Accton EN2216
+product ACCTON EN2226 { "Accton", "Fast&spEtherCard-16", "EN2226", "1.00" } Accton EN2226
+product ADDTRON AWP100 { "Addtron", "AWP-100&spWireless&spPCMCIA", "Version&sp01.02", NULL }
+product ALLIEDTELESIS WR211PCM { "Allied&spTelesis&spK.K.", "WR211PCM", NULL, NULL } Allied Telesis WR211PCM
+product AMBICOM AMB8002T { "AmbiCom&spInc", "AMB8002T", NULL, NULL } AmbiCom AMB8002T
+product AMD AM79C930 { "AMD", "Am79C930", NULL, NULL } AMD Am79C930
+product ARGOSY SP320 { "PCMCIA", "RS-COM 2P", NULL, NULL } ARGOSY SP320 Dual port serial PCMCIA
+product BILLIONTON CFLT10N { "CF", "10Base-Ethernet", "1.0", NULL } Billionton Systems Inc. CFLT10N Ethernet
+product BILLIONTON LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL } Billionton Systems Inc. LNT-10TN NE2000 Compatible Card
+product CNET NE2000 { "CNet", "CN40BC&spEthernet", "D", "NE2000" } CNet CN40BC NE2000 Compatible
+product COREGA ETHER_PCC_T { "corega&spK.K.", "corega&spEther&spPCC-T", NULL, NULL } Corega Ether PCC-T
+product COREGA ETHER_PCC_TD { "corega&spK.K.", "corega&spEther&spPCC-TD", NULL, NULL } Corega Ether PCC-TD
+product COREGA ETHER_II_PCC_T { "corega&spK.K.", "corega&spEtherII&spPCC-T", NULL, NULL } Corega EtherII PCC-T
+product COREGA ETHER_II_PCC_TD { "corega&spK.K.", "corega&spEtherII&spPCC-TD", NULL, NULL } Corega EtherII PCC-TD
+product COREGA FAST_ETHER_PCC_TX { "corega&spK.K.", "corega&spFastEther&spPCC-TX", NULL, NULL } Corega FastEther PCC-TX
+product COREGA FETHER_PCC_TXD { "corega&spK.K.", "corega&spFEther&spPCC-TXD", NULL, NULL } Corega FEther PCC-TXD
+product COREGA FETHER_PCC_TXF { "corega", "FEther&spPCC-TXF", NULL, NULL } Corega FEther PCC-TXF
+product COREGA WIRELESS_LAN_PCC_11 { "corega&spK.K.", "Wireless&spLAN&spPCC-11", NULL, NULL } Corega Wireless LAN PCC-11
+product COREGA WIRELESS_LAN_PCCA_11 { "corega&spK.K.", "Wireless&spLAN&spPCCA-11", NULL, NULL } Corega Wireless LAN PCCA-11
+product COREGA WIRELESS_LAN_PCCB_11 { "corega_K.K.", "Wireless_LAN_PCCB-11", NULL, NULL } Corega Wireless LAN PCCB-11
+product COREGA WIRELESS_LAN_PCCL_11 { "corega", "WL&spPCCL-11", NULL, NULL } Corega Wireless LAN PCCL-11
+
+product DIGITAL DEPCMXX { "DIGITAL", "DEPCM-XX", NULL, NULL } DEC DEPCM-BA
+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 DLINK DE660PLUS { "D-Link", "DE-660+", NULL, NULL } D-Link DE-660+
+product DLINK DFE670TXD { "D-Link", "DFE-670TXD", NULL, NULL } D-Link DFE-670TXD
+product DLINK DWL650H { "D-Link&spCorporation", "D-Link&spDWL-650H&sp11Mbps&spWLAN&spAdapter", NULL, NULL } D-Link DWL-650H
+product DYNALINK L10C { "DYNALINK", "L10C", NULL, NULL } Dynalink L10C
+/*
+ * vendor ID of EPX_AA2000 is Fujitsu (0x0004) and product ID is 0x2000, but
+ * it conflicts with Fujitsu Towa LA501 Ethernet.
+ */
+product EIGERLABS EPX_AA2000 { "Eiger&splabs,Inc.", "EPX-AA2000&spPC&spSound&spCard", NULL, NULL } EPX-AA2000 PC Sound Card
+product EPSON EEN10B { "Seiko&spEpson&spCorp.", "Ethernet", "P/N:&spEEN10B&spRev.&sp00", NULL } Epson EEN10B
+product EPSON SC200 { "EPSON", "SCSI-2&spPC&spCard&spSC200", NULL, NULL } Media Intelligent SCSI-2 PC Card MSC-200
+product EXP EXPMULTIMEDIA { "EXP&sp&sp&sp", "PnPIDE", "F1", NULL } EXP IDE/ATAPI DVD Card
+product EXP THINLANCOMBO { "PCMCIA&spLAN", "Ethernet", NULL, NULL } EXP ThinLan Combo
+product FREECOM PCCARDIDE { "FREECOM", "PCCARD-IDE", NULL, NULL } FREECOM PCCARD-IDE
+product FUJITSU2 FMV_J181 { "PCMCIA&spMBH10302", "01", NULL, NULL } FUJITSU FMV-J181 PCMCIA Card
+product FUJITSU2 FMV_J182 { "FUJITSU", "LAN&spCard(FMV-J182)", "Ver.01", NULL } FUJITSU FMV-J182 PCMCIA Card
+product FUJITSU2 FMV_J182A { "FUJITSU", "LAN&spCard(FMV-J182)", "Ver.02", NULL } FUJITSU FMV-J182A PCMCIA Card
+product FUJITSU2 ITCFJ182A { "FUJITSU", "LAN&spCard(ITCFJ182)", "Ver.01", NULL } FUJITSU ITCFJ182A CompactCard
+product FUTUREDOMAIN SCSI2GO { "Future&spDomain&spCorporation" "SCSI&spPCMCIA&spCredit&spCard&spController", NULL, NULL } Future Domain SCSI2GO
+product GEMTEK WLAN { "Intersil", "PRISM&sp2_5&spPCMCIA&spADAPTER", "ISL37300P", "Eval-RevA" } GEMTEK Prism2_5 WaveLAN Card
+product IBM SCSICARD { "IBM&spCorp.", "SCSI&spPCMCIA&spCard", NULL, NULL } IBM SCSI PCMCIA Card
+product ICOM SL200 { "Icom", "SL-200", NULL, NULL } Icom SL-200
+product INTERSIL2 PRISM2 { "INTERSIL", "HFA384x/IEEE", "Version&sp01.02", NULL } Intersil Prism II
+product IODATA CBIDE2 { "IO&spDATA", "CBIDE2&sp&sp&sp&sp&sp&sp", NULL, NULL } IO-DATA CBIDE2/16-bit mode
+product IODATA3 CBSC16 { "IO&spDATA", "CBSC16&sp&sp&sp&sp&sp&sp&sp", NULL, NULL } IO-DATA CBSC16
+product IODATA PCLAT { "I-O&spDATA", "PCLA", "ETHERNET", NULL } IO-DATA PCLA/T
+product LANTECH FASTNETTX { "ASIX", "AX88190", NULL, NULL } Lantech Fastnet/TX
+product LINKSYS ECARD_2 { "LINKSYS", "E-CARD", NULL, NULL } Linksys E-Card
+product LINKSYS PCM100 { "Linksys", "EtherFast&sp10/100&spIntegrated&spPC&spCard&sp(PCM100)", "Ver&sp1.0", NULL }
+product MACNICA MPS100 { "MACNICA", "MIRACLE&spSCSI", "mPS100", "D.0" } Macnica Miracle SCSI mPS100
+product MEGAHERTZ XJ2288 { "MEGAHERTZ", "MODEM&spXJ2288", NULL, NULL } Megahertz XJ2288 Modem
+product MELCO2 LPC2_TX { "MELCO", "LPC2-TX", NULL, NULL } Melco LPC2-TX
+product NAKAGAWAMETAL LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL } NAKAGAWA METAL LNT-10TN NE2000 Compatible Card
+product NANOSPEED PRISM2 { "NANOSPEED", "HFA384x/IEEE", "Version&sp01.02", NULL } NANOSPEED ROOT-RZ2000 WLAN Card
+product NDC ND5100_E { "NDC", "Ethernet", "A", NULL } Sohoware ND5100E NE2000 Compatible Card
+product NEC CMZ_RT_WP { "NEC", "Wireless&spCard&spCMZ-RT-WP", "Version&sp01.01", NULL } NEC Wireless Card CMZ-RT-WP
+product NEC PC9801N_J03R { "NEC", "PC-9801N-J03R", NULL, NULL } NEC PC-9801N-J03R
+product NEWMEDIA BASICS_SCSI { "BASICS&spby&spNew&spMedia&spCorporation" "SCSI&spSym53C500", NULL, NULL } New Media Corporation BASICS SCSI
+product NTT_ME WLAN { "NTT-ME", "11Mbps&spWireless&spLAN&spPC&spCard", NULL, NULL } NTT-ME 11Mbps Wireless LAN PC Card
+product OEM2 CDROM1 { "PCMCIA", "CD-ROM", NULL, NULL } Generic PCMCIA CD-ROM
+product OEM2 IDE { "PCMCIA", "IDE&spCARD", NULL, NULL } Generic PCMCIA IDE CARD
+product PLANET SMARTCOM2000 { "PCMCIA", "UE2212", NULL, NULL } Planet SmartCOM 2000
+/*
+ * vendor ID of both FNW-3600-T and FNW-3700-T is LINKSYS (0x0149) and
+ * product ID is 0xc1ab, but it conflicts with LINKSYS Combo EthernetCard.
+ */
+product PLANEX FNW3600T -1 Planex FNW-3600-T
+product PLANEX FNW3700T -1 Planex FNW-3700-T
+product RPTI EP400 { "RPTI&spLTD.", "EP400", "CISV100", NULL } RPTI EP400
+product RPTI EP401 { "RPTI", "EP401&spEthernet&spNE2000&spCompatible", NULL, NULL } RPTI EP401
+product PREMAX PE200 { "PMX&sp&sp&sp", "PE-200", NULL, NULL } PreMax PE-200
+product RATOC REX_R280 { "RATOC&spSystem&spInc.", "10BASE_T&spCARD&spR280", NULL, NULL } RATOC REX-R280
+product RATOC REX5536 { "1195&spRATOC&spSystem&spInc.", "REX5536&spSCSI2&spCARD", NULL, NULL } RATOC REX-5536
+product RATOC REX5536AM { "PCMCIA&spSCSI&spMBH10404", "01", NULL, NULL } RATOC REX-5536AM
+product RATOC REX5536M { "PCMCIA&spSCSI2&spCARD", "01", NULL, NULL } RATOC REX-5536M
+product RATOC REX5572 { "RATOC&spSystem&spInc.", "SOUND/SCSI2&spCARD", NULL, NULL } RATOC REX-5572
+product RATOC REX9530 { "RATOC&spSystem&spInc.", "SCSI2&spCARD&sp37", NULL, NULL } RATOC REX-9530
+product SIMPLETECH SPECTRUM24_ALT { "Symbol&spTechnologies", "LA4111&spSpectrum24&spWireless&spLAN&spPC&spCard", NULL, NULL } LA4111 Spectrum24 Wireless LAN PC Card
+product SMC 2632W { "SMC", "SMC2632W", "Version&sp01.02", NULL } SMC 2632 EZ Connect Wireless PC Card
+product SMC 8041 { "SMC", "8041TX-10/100-PC-Card-V2", NULL, NULL } SMC 8041TX 10/100 PC Card
+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 SYNERGY21 S21810 { "PCMCIA", "Ethernet", "A", "004743118001" } Synergy 21 S21810+ NE2000 Compatible Card
+product TEAC IDECARDII { NULL, "NinjaATA-", NULL, NULL } TEAC IDE Card/II
+product TOSHIBA CBIDE2 { "LOOKMEET", "CBIDE2&sp&sp&sp&sp&sp&sp", NULL, NULL } TOSHIBA PA2673U CBIDE2/16-bit mode (IO-DATA OEM)
+product WORKBIT2 NINJA_SCSI3 { "WBT", "NinjaSCSI-3", NULL, NULL } WORKBIT Ninja SCSI series
+product XIRCOM CFE_10 { "Xircom", "CompactCard&spEthernet", "CFE-10", "1.00" } Xircom CompactCard CFE-10
+product YEDATA EXTERNAL_FDD { "Y-E&spDATA", "External&spFDD", NULL, NULL } Y-E DATA External FDD
+product YIS YWL11B { "YIS&spCorp.", "YWL-11b", NULL, NULL } YIS Corp. YWL-11b
+product ZOOM AIR_4000 { "Zoom", "Air-4000", NULL, NULL } Zoom Air-4000
diff --git a/sys/dev/pccard/pccarddevs.h b/sys/dev/pccard/pccarddevs.h
new file mode 100644
index 0000000..54223fc
--- /dev/null
+++ b/sys/dev/pccard/pccarddevs.h
@@ -0,0 +1,1150 @@
+/* $FreeBSD$ */
+
+/*
+ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
+ *
+ * generated from:
+ * FreeBSD: src/sys/dev/pccard/pccarddevs,v 1.80 2003/12/31 04:19:50 kato Exp
+ */
+/* $NetBSD: pcmciadevs,v 1.186 2003/09/16 08:26:37 onoe Exp $ */
+/* $OpenBSD: pcmciadevs,v 1.93 2002/06/21 08:31:10 henning Exp $ */
+
+/*-
+ * 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, sorted by numeric ID.
+ */
+
+#define PCMCIA_VENDOR_FUJITSU 0x0004 /* Fujitsu Corporation */
+#define PCMCIA_VENDOR_INTERSIL 0x000b /* Intersil */
+#define PCMCIA_VENDOR_PANASONIC 0x0032 /* Matsushita Electric Industrial Co. */
+#define PCMCIA_VENDOR_SANDISK 0x0045 /* Sandisk Corporation */
+#define PCMCIA_VENDOR_NEWMEDIA 0x0057 /* New Media Corporation */
+#define PCMCIA_VENDOR_INTEL 0x0089 /* Intel */
+#define PCMCIA_VENDOR_IBM 0x00a4 /* IBM Corporation */
+#define PCMCIA_VENDOR_SHARP 0x00b0 /* Sharp Corporation */
+#define PCMCIA_VENDOR_3COM 0x0101 /* 3Com Corporation */
+#define PCMCIA_VENDOR_MEGAHERTZ 0x0102 /* Megahertz Corporation */
+#define PCMCIA_VENDOR_SOCKET 0x0104 /* Socket Communications */
+#define PCMCIA_VENDOR_TDK 0x0105 /* TDK Corporation */
+#define PCMCIA_VENDOR_XIRCOM 0x0105 /* Xircom */
+#define PCMCIA_VENDOR_SMC 0x0108 /* Standard Microsystems Corporation */
+#define PCMCIA_VENDOR_MOTOROLA 0x0109 /* Motorola Corporation */
+#define PCMCIA_VENDOR_NI 0x010b /* National Instruments */
+#define PCMCIA_VENDOR_QLOGIC 0x0114 /* QLogic */
+#define PCMCIA_VENDOR_USROBOTICS 0x0115 /* US Robotics Corporation */
+#define PCMCIA_VENDOR_OLICOM 0x0121 /* Olicom */
+#define PCMCIA_VENDOR_PROXIM 0x0126 /* Proxim */
+#define PCMCIA_VENDOR_DSPSI 0x0128 /* DSP Solutions, Inc */
+#define PCMCIA_VENDOR_ADAPTEC 0x012f /* Adaptec Corporation */
+#define PCMCIA_VENDOR_QUATECH 0x0137 /* Quatech */
+#define PCMCIA_VENDOR_COMPAQ 0x0138 /* Compaq */
+#define PCMCIA_VENDOR_OSITECH 0x0140 /* Ositech */
+#define PCMCIA_VENDOR_DLINK_2 0x0143 /* D-Link */
+#define PCMCIA_VENDOR_DLINK_3 0x0149 /* D-Link */
+#define PCMCIA_VENDOR_LINKSYS 0x0149 /* Linksys Corporation */
+#define PCMCIA_VENDOR_NETGEAR 0x0149 /* Netgear */
+#define PCMCIA_VENDOR_SIMPLETECH 0x014d /* Simple Technology */
+#define PCMCIA_VENDOR_SYMBOL2 0x014d /* Symbol */
+#define PCMCIA_VENDOR_LUCENT 0x0156 /* Lucent Technologies */
+#define PCMCIA_VENDOR_GEMPLUS 0x0157 /* Gemplus */
+#define PCMCIA_VENDOR_AIRONET 0x015f /* Aironet Wireless Communications */
+#define PCMCIA_VENDOR_ERICSSON 0x016b /* Ericsson */
+#define PCMCIA_VENDOR_PSION 0x016c /* Psion */
+#define PCMCIA_VENDOR_COMPAQ2 0x0183 /* Compaq */
+#define PCMCIA_VENDOR_PARALON 0x0183 /* Paralon Technologies Inc */
+#define PCMCIA_VENDOR_KINGSTON 0x0186 /* Kingston */
+#define PCMCIA_VENDOR_MELCO 0x018a /* Melco Corporation */
+#define PCMCIA_VENDOR_DAYNA 0x0194 /* Dayna Corporation */
+#define PCMCIA_VENDOR_RAYTHEON 0x01a6 /* Raytheon */
+#define PCMCIA_VENDOR_IODATA 0x01bf /* I-O DATA */
+#define PCMCIA_VENDOR_BAY 0x01eb /* Bay Networks */
+#define PCMCIA_VENDOR_FARALLON 0x0200 /* Farallon Communications */
+#define PCMCIA_VENDOR_TELECOMDEVICE 0x021b /* Telecom Device */
+#define PCMCIA_VENDOR_NOKIA 0x023d /* Nokia Communications */
+#define PCMCIA_VENDOR_SAMSUNG 0x0250 /* Samsung */
+#define PCMCIA_VENDOR_HWN 0x0261 /* Home Wireless Networks */
+#define PCMCIA_VENDOR_ARTEM 0x0268 /* ARtem */
+#define PCMCIA_VENDOR_SYMBOL 0x026c /* Symbol */
+#define PCMCIA_VENDOR_BUFFALO 0x026f /* BUFFALO (Melco Corporation) */
+#define PCMCIA_VENDOR_BROMAX 0x0274 /* Bromax communications, Inc */
+#define PCMCIA_VENDOR_IODATA2 0x028a /* I-O DATA */
+#define PCMCIA_VENDOR_ASUS 0x02aa /* ASUS */
+#define PCMCIA_VENDOR_SIEMENS 0x02ac /* Siemens */
+#define PCMCIA_VENDOR_MICROSOFT 0x02d2 /* Microsoft Corporation */
+
+/*
+ * The following vendor IDs are byte-swapped from what the company is assigned.
+ */
+#define PCMCIA_VENDOR_NWN 0x0602 /* No Wires Needed */
+#define PCMCIA_VENDOR_BREEZECOM 0x0a02 /* BreezeCOM */
+#define PCMCIA_VENDOR_LASAT 0x3401 /* Lasat Communications A/S */
+#define PCMCIA_VENDOR_BONDWELL 0x3b01 /* Bondwell */
+#define PCMCIA_VENDOR_LEXARMEDIA 0x4e01 /* Lexar Media */
+#define PCMCIA_VENDOR_COMPEX 0x8a01 /* Compex Corporation */
+#define PCMCIA_VENDOR_ZONET 0x8a01 /* Zonet Technology Inc. */
+#define PCMCIA_VENDOR_ELSA 0xd601 /* Elsa */
+
+/*
+ * The following vendor IDs are not, as far as I can tell, actually
+ * assigned to these people. However, all the ones starting with '0xc'
+ * look coherent enough that maybe somebody other than PCMCIA is
+ * assigning numbers in that range.
+ */
+#define PCMCIA_VENDOR_NEWMEDIA2 0x10cd /* NewMedia */
+#define PCMCIA_VENDOR_PLANEX_2 0x14ea /* PLANEX */
+#define PCMCIA_VENDOR_ACTIONTEC 0x1668 /* ACTIONTEC */
+#define PCMCIA_VENDOR_AIRVAST 0x50c2 /* AirVast Technology */
+#define PCMCIA_VENDOR_ARCHOS 0x5241 /* Archos */
+#define PCMCIA_VENDOR_DUAL 0x890f /* Dual */
+#define PCMCIA_VENDOR_EDIMAX 0x890f /* Edimax Technology Inc. */
+#define PCMCIA_VENDOR_CONTEC 0xc001 /* Contec */
+#define PCMCIA_VENDOR_MACNICA 0xc00b /* MACNICA */
+#define PCMCIA_VENDOR_ROLAND 0xc00c /* Roland */
+#define PCMCIA_VENDOR_COREGA2 0xc00f /* Corega K.K. */
+#define PCMCIA_VENDOR_ALLIEDTELESIS 0xc00f /* Allied Telesis K.K. */
+#define PCMCIA_VENDOR_HAGIWARASYSCOM 0xc012 /* Hagiwara SYS-COM */
+#define PCMCIA_VENDOR_RATOC 0xc015 /* RATOC System Inc. */
+#define PCMCIA_VENDOR_WORKBIT 0xc024 /* WORKBIT */
+#define PCMCIA_VENDOR_EMTAC 0xc250 /* EMTAC Technology Corporation */
+
+/*
+ * List of known products. Grouped by vendor, sorted by number within the
+ * group.
+ */
+
+/* 3COM Products */
+#define PCMCIA_CIS_3COM_3CRWE737A { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CRWE737A 0x0001
+#define PCMCIA_STR_3COM_3CRWE737A "3Com AirConnect Wireless LAN"
+#define PCMCIA_CIS_3COM_3CXM056BNW { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CXM056BNW 0x002f
+#define PCMCIA_STR_3COM_3CXM056BNW "3Com/NoteWorthy 3CXM056-BNW 56K Modem"
+#define PCMCIA_CIS_3COM_3CXEM556 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CXEM556 0x0035
+#define PCMCIA_STR_3COM_3CXEM556 "3Com/Megahertz 3CXEM556 Ethernet/Modem"
+#define PCMCIA_CIS_3COM_3CXEM556INT { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CXEM556INT 0x003d
+#define PCMCIA_STR_3COM_3CXEM556INT "3Com/Megahertz 3CXEM556-INT Ethernet/Modem"
+#define PCMCIA_CIS_3COM_3CCFEM556BI { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CCFEM556BI 0x0556
+#define PCMCIA_STR_3COM_3CCFEM556BI "3Com/Megahertz 3CCFEM556BI Ethernet/Modem"
+#define PCMCIA_CIS_3COM_3C562 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3C562 0x0562
+#define PCMCIA_STR_3COM_3C562 "3Com 3c562 33.6 Modem/10Mbps Ethernet"
+#define PCMCIA_CIS_3COM_3C589 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3C589 0x0589
+#define PCMCIA_STR_3COM_3C589 "3Com 3c589 10Mbps Ethernet"
+#define PCMCIA_CIS_3COM_3C574 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3C574 0x0574
+#define PCMCIA_STR_3COM_3C574 "3Com 3c574-TX 10/100Mbps Ethernet"
+#define PCMCIA_CIS_3COM_3CRWE777A { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CRWE777A 0x0777
+#define PCMCIA_STR_3COM_3CRWE777A "3Com 3CRWE777A Airconnect"
+#define PCMCIA_CIS_3COM_3C1 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3C1 0x0cf1
+#define PCMCIA_STR_3COM_3C1 "3Com Megahertz 3C1 10Mbps LAN CF+ Card"
+#define PCMCIA_CIS_3COM_3CRWE62092A { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_3COM_3CRWE62092A 0x2092
+#define PCMCIA_STR_3COM_3CRWE62092A "3Com 3CRWE62092A Wireless LAN"
+
+/* ACTIONTEC Products */
+#define PCMCIA_CIS_ACTIONTEC_PRISM { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ACTIONTEC_PRISM 0x0101
+#define PCMCIA_STR_ACTIONTEC_PRISM "PRISM Wireless LAN PC Card"
+
+/* Adaptec Products */
+#define PCMCIA_CIS_ADAPTEC_APA1460 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ADAPTEC_APA1460 0x0001
+#define PCMCIA_STR_ADAPTEC_APA1460 "Adaptec APA-1460 SlimSCSI"
+#define PCMCIA_CIS_ADAPTEC_APA1460A { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ADAPTEC_APA1460A 0x0002
+#define PCMCIA_STR_ADAPTEC_APA1460A "Adaptec APA-1460A SlimSCSI"
+
+/* Aironet */
+#define PCMCIA_CIS_AIRONET_PC4500 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_AIRONET_PC4500 0x0005
+#define PCMCIA_STR_AIRONET_PC4500 "Aironet PC4500 Wireless LAN Adapter"
+#define PCMCIA_CIS_AIRONET_PC4800 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_AIRONET_PC4800 0x0007
+#define PCMCIA_STR_AIRONET_PC4800 "Aironet PC4800 Wireless LAN Adapter"
+#define PCMCIA_CIS_AIRONET_350 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_AIRONET_350 0x000a
+#define PCMCIA_STR_AIRONET_350 "Aironet 350 Wireless LAN Adapter"
+
+/* AirVast */
+#define PCMCIA_CIS_AIRVAST_WN_100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_AIRVAST_WN_100 0x7300
+#define PCMCIA_STR_AIRVAST_WN_100 "AirVast WN-100"
+
+/* Allied Telesis K.K. */
+#define PCMCIA_CIS_ALLIEDTELESIS_LA_PCM { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ALLIEDTELESIS_LA_PCM 0x0002
+#define PCMCIA_STR_ALLIEDTELESIS_LA_PCM "Allied Telesis LA-PCM"
+
+/* Archos */
+#define PCMCIA_CIS_ARCHOS_ARC_ATAPI { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ARCHOS_ARC_ATAPI 0x0043
+#define PCMCIA_STR_ARCHOS_ARC_ATAPI "MiniCD"
+
+/* ARtem */
+#define PCMCIA_CIS_ARTEM_ONAIR { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ARTEM_ONAIR 0x0001
+#define PCMCIA_STR_ARTEM_ONAIR "ARtem OnAir"
+
+/* ASUS WL-100 */
+#define PCMCIA_CIS_ASUS_WL100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ASUS_WL100 0x0002
+#define PCMCIA_STR_ASUS_WL100 "ASUS SpaceLink WL-100 Wireless LAN"
+
+/* Bay Networks */
+#define PCMCIA_CIS_BAY_STACK_650 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BAY_STACK_650 0x0804
+#define PCMCIA_STR_BAY_STACK_650 "BayStack 650 Wireless LAN"
+#define PCMCIA_CIS_BAY_SURFER_PRO { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BAY_SURFER_PRO 0x0806
+#define PCMCIA_STR_BAY_SURFER_PRO "AirSurfer Pro Wireless LAN"
+#define PCMCIA_CIS_BAY_STACK_660 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BAY_STACK_660 0x0807
+#define PCMCIA_STR_BAY_STACK_660 "BayStack 660 Wireless LAN"
+#define PCMCIA_CIS_BAY_EMOBILITY_11B { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BAY_EMOBILITY_11B 0x080a
+#define PCMCIA_STR_BAY_EMOBILITY_11B "e-Mobility 11Mb Wireless LAN"
+
+/* Bondwell */
+#define PCMCIA_CIS_BONDWELL_B236 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BONDWELL_B236 0x0000
+#define PCMCIA_STR_BONDWELL_B236 "Game Card Joystick"
+
+/* BreezeCOM */
+#define PCMCIA_CIS_BREEZECOM_BREEZENET { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BREEZECOM_BREEZENET 0x0102
+#define PCMCIA_STR_BREEZECOM_BREEZENET "BreezeCOM BreezeNET"
+
+/* Bromax Communications, Inc (Linksys OEM) */
+#define PCMCIA_CIS_BROMAX_IWN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BROMAX_IWN 0x1612
+#define PCMCIA_STR_BROMAX_IWN "Instant Wireless Network PC Card"
+#define PCMCIA_CIS_BROMAX_IWN3 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BROMAX_IWN3 0x1613
+#define PCMCIA_STR_BROMAX_IWN3 "Instant Wireless Network PC Card, Versin 3"
+#define PCMCIA_CIS_BROMAX_WCF11 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BROMAX_WCF11 0x3301
+#define PCMCIA_STR_BROMAX_WCF11 "Instant Wireless Network CF Card"
+
+/* BUFFALO */
+#define PCMCIA_CIS_BUFFALO_LPC3_CLX { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BUFFALO_LPC3_CLX 0x0301
+#define PCMCIA_STR_BUFFALO_LPC3_CLX "BUFFALO LPC3-CLX Ethernet Adapter"
+#define PCMCIA_CIS_BUFFALO_WLI_PCM_S11 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BUFFALO_WLI_PCM_S11 0x0305
+#define PCMCIA_STR_BUFFALO_WLI_PCM_S11 "BUFFALO AirStation 11Mbps WLAN"
+#define PCMCIA_CIS_BUFFALO_LPC_CF_CLT { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BUFFALO_LPC_CF_CLT 0x0307
+#define PCMCIA_STR_BUFFALO_LPC_CF_CLT "BUFFALO LPC-CF-CLT"
+#define PCMCIA_CIS_BUFFALO_LPC3_CLT { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BUFFALO_LPC3_CLT 0x030a
+#define PCMCIA_STR_BUFFALO_LPC3_CLT "BUFFALO LPC3-CLT Ethernet Adapter"
+#define PCMCIA_CIS_BUFFALO_WLI_CF_S11G { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_BUFFALO_WLI_CF_S11G 0x030b
+#define PCMCIA_STR_BUFFALO_WLI_CF_S11G "BUFFALO AirStation 11Mbps CF WLAN"
+
+/* Compaq Products */
+#define PCMCIA_CIS_COMPAQ_NC5004 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_COMPAQ_NC5004 0x0002
+#define PCMCIA_STR_COMPAQ_NC5004 "Compaq Agency NC5004 Wireless Card"
+#define PCMCIA_CIS_COMPAQ2_CPQ_10_100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_COMPAQ2_CPQ_10_100 0x010a
+#define PCMCIA_STR_COMPAQ2_CPQ_10_100 "Compaq Netelligent 10/100 Ethernet"
+
+/* Compex Products */
+#define PCMCIA_CIS_COMPEX_AMP_WIRELESS { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_COMPEX_AMP_WIRELESS 0x0066
+#define PCMCIA_STR_COMPEX_AMP_WIRELESS "AMP"
+#define PCMCIA_CIS_COMPEX_LINKPORT_ENET_B { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_COMPEX_LINKPORT_ENET_B 0x0100
+#define PCMCIA_STR_COMPEX_LINKPORT_ENET_B "Compex Linkport ENET-B Ethernet"
+
+/* Contec C-NET(PC) */
+#define PCMCIA_CIS_CONTEC_CNETPC { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_CONTEC_CNETPC 0x0000
+#define PCMCIA_STR_CONTEC_CNETPC "Contec C-NET(PC)C"
+#define PCMCIA_CIS_CONTEC_FX_DS110_PCC { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_CONTEC_FX_DS110_PCC 0x0008
+#define PCMCIA_STR_CONTEC_FX_DS110_PCC "Contec FLEXLAN/FX-DS110-PCC"
+
+/* Dayna Products */
+#define PCMCIA_CIS_DAYNA_COMMUNICARD_E_1 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_1 0x002d
+#define PCMCIA_STR_DAYNA_COMMUNICARD_E_1 "Dayna CommuniCard E"
+#define PCMCIA_CIS_DAYNA_COMMUNICARD_E_2 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_2 0x002f
+#define PCMCIA_STR_DAYNA_COMMUNICARD_E_2 "Dayna CommuniCard E"
+
+/* DIGITAL Products */
+#define PCMCIA_CIS_DIGITAL_MOBILE_MEDIA_CDROM { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DIGITAL_MOBILE_MEDIA_CDROM 0x0d00
+#define PCMCIA_STR_DIGITAL_MOBILE_MEDIA_CDROM "Digital Mobile Media CD-ROM"
+
+/* D-Link Products */
+#define PCMCIA_CIS_DLINK_2_DMF560TX { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DLINK_2_DMF560TX 0xc0ab
+#define PCMCIA_STR_DLINK_2_DMF560TX "D-Link DMF-650TX"
+
+/* DSP Solutions, Inc. (Megahertz OEM) */
+#define PCMCIA_CIS_DSPSI_XJEM1144 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DSPSI_XJEM1144 0x0101
+#define PCMCIA_STR_DSPSI_XJEM1144 "Megahertz X-JACK"
+#define PCMCIA_CIS_DSPSI_XJACK { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DSPSI_XJACK 0x0103
+#define PCMCIA_STR_DSPSI_XJACK "Megahertz X-JACK Ethernet"
+
+/* Dual */
+#define PCMCIA_CIS_DUAL_NE2000 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_DUAL_NE2000 0x0100
+#define PCMCIA_STR_DUAL_NE2000 "Dual NE2000"
+
+/* Edimax Products */
+#define PCMCIA_CIS_EDIMAX_EP4000A { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_EDIMAX_EP4000A 0x0100
+#define PCMCIA_STR_EDIMAX_EP4000A "Edimax EP4000A"
+
+/* ELSA Products */
+#define PCMCIA_CIS_ELSA_MC2_IEEE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ELSA_MC2_IEEE 0x0001
+#define PCMCIA_STR_ELSA_MC2_IEEE "AirLancer MC-2 IEEE"
+#define PCMCIA_CIS_ELSA_XI300_IEEE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ELSA_XI300_IEEE 0x0002
+#define PCMCIA_STR_ELSA_XI300_IEEE "XI300 Wireless LAN"
+#define PCMCIA_CIS_ELSA_XI800_IEEE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ELSA_XI800_IEEE 0x0004
+#define PCMCIA_STR_ELSA_XI800_IEEE "XI800 CF Wireless LAN"
+#define PCMCIA_CIS_ELSA_XI325_IEEE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ELSA_XI325_IEEE 0x0005
+#define PCMCIA_STR_ELSA_XI325_IEEE "XI325 Wireless LAN"
+
+/* EMTAC */
+#define PCMCIA_CIS_EMTAC_WLAN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_EMTAC_WLAN 0x0002
+#define PCMCIA_STR_EMTAC_WLAN "EMTAC A2424i 11Mbps WLAN Card"
+
+/* Ericsson */
+#define PCMCIA_CIS_ERICSSON_WIRELESSLAN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ERICSSON_WIRELESSLAN 0x0001
+#define PCMCIA_STR_ERICSSON_WIRELESSLAN "DSSS Wireless LAN PC Card"
+
+/* Farallon */
+#define PCMCIA_CIS_FARALLON_SKYLINE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_FARALLON_SKYLINE 0x0a01
+#define PCMCIA_STR_FARALLON_SKYLINE "SkyLINE Wireless"
+
+/* Fujutsu Products */
+#define PCMCIA_CIS_FUJITSU_SCSI600 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_FUJITSU_SCSI600 0x0401
+#define PCMCIA_STR_FUJITSU_SCSI600 "Fujitsu SCSI 600 Interface"
+#define PCMCIA_CIS_FUJITSU_LA10S { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_FUJITSU_LA10S 0x1003
+#define PCMCIA_STR_FUJITSU_LA10S "Fujitsu Compact Flash Ethernet"
+#define PCMCIA_CIS_FUJITSU_LA501 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_FUJITSU_LA501 0x2000
+#define PCMCIA_STR_FUJITSU_LA501 "Fujitsu Towa LA501 Ethernet"
+#define PCMCIA_CIS_FUJITSU_WL110 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_FUJITSU_WL110 0x2003
+#define PCMCIA_STR_FUJITSU_WL110 "PEGA-WL110 Wireless LAN"
+
+/* Gemplus */
+#define PCMCIA_CIS_GEMPLUS_GPR400 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_GEMPLUS_GPR400 0x3004
+#define PCMCIA_STR_GEMPLUS_GPR400 "GPR400 Smartcard Reader"
+
+/* Home Wireless Networks */
+#define PCMCIA_CIS_HWN_AIRWAY80211 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_HWN_AIRWAY80211 0x0002
+#define PCMCIA_STR_HWN_AIRWAY80211 "HWN Airway Wireless PCMCIA Card"
+
+/* IBM Products */
+#define PCMCIA_CIS_IBM_MICRODRIVE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_MICRODRIVE 0x0000
+#define PCMCIA_STR_IBM_MICRODRIVE "IBM Microdrive"
+#define PCMCIA_CIS_IBM_3270 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_3270 0x0001
+#define PCMCIA_STR_IBM_3270 "IBM 3270 Emulation"
+#define PCMCIA_CIS_IBM_INFOMOVER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_INFOMOVER 0x0002
+#define PCMCIA_STR_IBM_INFOMOVER "IBM InfoMover"
+#define PCMCIA_CIS_IBM_5250 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_5250 0x000b
+#define PCMCIA_STR_IBM_5250 "IBM 5250 Emulation"
+#define PCMCIA_CIS_IBM_TROPIC { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_TROPIC 0x001e
+#define PCMCIA_STR_IBM_TROPIC "IBM Token Ring 4/16"
+#define PCMCIA_CIS_IBM_SCSI { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_SCSI 0x0026
+#define PCMCIA_STR_IBM_SCSI "IBM SCSI PCMCIA"
+#define PCMCIA_CIS_IBM_PORTABLE_CDROM { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_PORTABLE_CDROM 0x002d
+#define PCMCIA_STR_IBM_PORTABLE_CDROM "IBM PCMCIA Portable CD-ROM Drive"
+#define PCMCIA_CIS_IBM_HOME_AND_AWAY { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_HOME_AND_AWAY 0x002e
+#define PCMCIA_STR_IBM_HOME_AND_AWAY "IBM Home and Away Modem"
+#define PCMCIA_CIS_IBM_WIRELESS_LAN_ENTRY { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_WIRELESS_LAN_ENTRY 0x0032
+#define PCMCIA_STR_IBM_WIRELESS_LAN_ENTRY "IBM Wireless LAN Entry"
+#define PCMCIA_CIS_IBM_SMART_CAPTURE_II { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_SMART_CAPTURE_II 0x003c
+#define PCMCIA_STR_IBM_SMART_CAPTURE_II "IBM Smart Capture Card II"
+#define PCMCIA_CIS_IBM_ETHERJET { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_ETHERJET 0x003f
+#define PCMCIA_STR_IBM_ETHERJET "IBM EtherJet Ethernet"
+
+/* Intel Products */
+#define PCMCIA_CIS_INTEL_PRO_WLAN_2011 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_INTEL_PRO_WLAN_2011 0x0001
+#define PCMCIA_STR_INTEL_PRO_WLAN_2011 "Intel PRO/Wireless 2011 LAN PC Card"
+#define PCMCIA_CIS_INTEL_EEPRO100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_INTEL_EEPRO100 0x010a
+#define PCMCIA_STR_INTEL_EEPRO100 "Intel EtherExpress PRO/100"
+#define PCMCIA_CIS_INTEL_ETHEREXPPRO { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_INTEL_ETHEREXPPRO 0x0301
+#define PCMCIA_STR_INTEL_ETHEREXPPRO "Intel EtherExpress Pro PCMCIA Card"
+
+/* Intersil */
+/* Note: The following likely is an OEM card under a different Intersil name */
+#define PCMCIA_CIS_INTERSIL_MA401RA { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_INTERSIL_MA401RA 0x7300
+#define PCMCIA_STR_INTERSIL_MA401RA "Netgear MA401RA"
+
+/* I-O DATA */
+#define PCMCIA_CIS_IODATA_PCLATE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IODATA_PCLATE 0x2216
+#define PCMCIA_STR_IODATA_PCLATE "I-O DATA PCLA/TE"
+#define PCMCIA_CIS_IODATA2_WNB11PCM { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IODATA2_WNB11PCM 0x0002
+#define PCMCIA_STR_IODATA2_WNB11PCM "I-O DATA WN-B11/PCM"
+#define PCMCIA_CIS_IODATA2_WCF12 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_IODATA2_WCF12 0x0673
+#define PCMCIA_STR_IODATA2_WCF12 "Wireless CF Card"
+
+/* Kingston Products */
+#define PCMCIA_CIS_KINGSTON_KNE2 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_KINGSTON_KNE2 0x0100
+#define PCMCIA_STR_KINGSTON_KNE2 "Kingston KNE-PC2 Ethernet"
+
+/* Lasat Products */
+#define PCMCIA_CIS_LASAT_CREDIT_288 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LASAT_CREDIT_288 0x2811
+#define PCMCIA_STR_LASAT_CREDIT_288 "Lasat Credit 288 Modem"
+
+/* Lexar Media */
+#define PCMCIA_CIS_LEXARMEDIA_COMPACTFLASH { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LEXARMEDIA_COMPACTFLASH 0x0100
+#define PCMCIA_STR_LEXARMEDIA_COMPACTFLASH "Lexar Media CompactFlash"
+
+/* Linksys corporation */
+#define PCMCIA_CIS_LINKSYS_TRUST_COMBO_ECARD { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LINKSYS_TRUST_COMBO_ECARD 0x021b
+#define PCMCIA_STR_LINKSYS_TRUST_COMBO_ECARD "Trust (Linksys) Combo EthernetCard"
+#define PCMCIA_CIS_LINKSYS_ETHERFAST { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LINKSYS_ETHERFAST 0x0230
+#define PCMCIA_STR_LINKSYS_ETHERFAST "Linksys Etherfast 10/100 Ethernet"
+#define PCMCIA_CIS_LINKSYS_ECARD_1 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LINKSYS_ECARD_1 0x0265
+#define PCMCIA_STR_LINKSYS_ECARD_1 "Linksys EthernetCard or D-Link DE-650"
+#define PCMCIA_CIS_LINKSYS_COMBO_ECARD { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD 0xc1ab
+#define PCMCIA_STR_LINKSYS_COMBO_ECARD "Linksys Combo EthernetCard"
+
+/* Lucent WaveLAN/IEEE */
+#define PCMCIA_CIS_LUCENT_WAVELAN_IEEE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE 0x0002
+#define PCMCIA_STR_LUCENT_WAVELAN_IEEE "WaveLAN/IEEE"
+
+/* MACNICA */
+#define PCMCIA_CIS_MACNICA_ME1_JEIDA { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MACNICA_ME1_JEIDA 0x3300
+#define PCMCIA_STR_MACNICA_ME1_JEIDA "MACNICA ME1 for JEIDA"
+#define PCMCIA_CIS_MACNICA_MPS110 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MACNICA_MPS110 0xa041
+#define PCMCIA_STR_MACNICA_MPS110 "MACNICA Miracle SCSI-II mPS110"
+
+/* Megahertz Products */
+#define PCMCIA_CIS_MEGAHERTZ_XJEM3336 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MEGAHERTZ_XJEM3336 0x0006
+#define PCMCIA_STR_MEGAHERTZ_XJEM3336 "Megahertz X-JACK Ethernet Modem"
+#define PCMCIA_CIS_MEGAHERTZ_XJ4288 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MEGAHERTZ_XJ4288 0x0023
+#define PCMCIA_STR_MEGAHERTZ_XJ4288 "Megahertz XJ4288 Modem"
+#define PCMCIA_CIS_MEGAHERTZ_XJ4336 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MEGAHERTZ_XJ4336 0x0027
+#define PCMCIA_STR_MEGAHERTZ_XJ4336 "Megahertz XJ4336 Modem"
+#define PCMCIA_CIS_MEGAHERTZ_XJ5560 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MEGAHERTZ_XJ5560 0x0034
+#define PCMCIA_STR_MEGAHERTZ_XJ5560 "Megahertz X-JACK 56kbps Modem"
+
+/* Melco Products */
+#define PCMCIA_CIS_MELCO_LPC3_TX { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MELCO_LPC3_TX 0xc1ab
+#define PCMCIA_STR_MELCO_LPC3_TX "Melco LPC3-TX"
+#define PCMCIA_CIS_MELCO_LPC3_CLX { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MELCO_LPC3_CLX 0x0301
+#define PCMCIA_STR_MELCO_LPC3_CLX "Melco LPC3-CLX Ethernet Adapter"
+
+/* Microsoft Products */
+#define PCMCIA_CIS_MICROSOFT_MN_520 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MICROSOFT_MN_520 0x0001
+#define PCMCIA_STR_MICROSOFT_MN_520 "Microsoft MN-520 WLAN Card"
+
+/* Motorola Products */
+#define PCMCIA_CIS_MOTOROLA_POWER144 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MOTOROLA_POWER144 0x0105
+#define PCMCIA_STR_MOTOROLA_POWER144 "Motorola Power 14.4 Modem"
+#define PCMCIA_CIS_MOTOROLA_PM100C { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MOTOROLA_PM100C 0x0302
+#define PCMCIA_STR_MOTOROLA_PM100C "Motorola Personal Messenger 100C CDPD Modem"
+#define PCMCIA_CIS_MOTOROLA_MONTANA_336 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_MOTOROLA_MONTANA_336 0x0505
+#define PCMCIA_STR_MOTOROLA_MONTANA_336 "Motorola Montana 33.6"
+
+/* New Media Products */
+#define PCMCIA_CIS_NEWMEDIA_BASICS { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_BASICS 0x0019
+#define PCMCIA_STR_NEWMEDIA_BASICS "New Media BASICS Ethernet"
+#define PCMCIA_CIS_NEWMEDIA_LANSURFER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_LANSURFER 0x0021
+#define PCMCIA_STR_NEWMEDIA_LANSURFER "NewMedia LANSurfer"
+#define PCMCIA_CIS_NEWMEDIA_LIVEWIRE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_LIVEWIRE 0x1004
+#define PCMCIA_STR_NEWMEDIA_LIVEWIRE "NewMedia LiveWire Ethernet LAN Adapter"
+#define PCMCIA_CIS_NEWMEDIA_MULTIMEDIA { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_MULTIMEDIA 0x100b
+#define PCMCIA_STR_NEWMEDIA_MULTIMEDIA "NewMedia Multimedia"
+#define PCMCIA_CIS_NEWMEDIA_BUSTOASTER2 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_BUSTOASTER2 0xa002
+#define PCMCIA_STR_NEWMEDIA_BUSTOASTER2 "New Media SCSI Bus Toaster"
+#define PCMCIA_CIS_NEWMEDIA_BUSTOASTER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_BUSTOASTER 0xc102
+#define PCMCIA_STR_NEWMEDIA_BUSTOASTER "New Media SCSI Bus Toaster"
+#define PCMCIA_CIS_NEWMEDIA_BUSTOASTER3 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_BUSTOASTER3 0xd302
+#define PCMCIA_STR_NEWMEDIA_BUSTOASTER3 "New Media SCSI Bus Toaster"
+#define PCMCIA_CIS_NEWMEDIA_WAVJAMMER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_WAVJAMMER 0xe005
+#define PCMCIA_STR_NEWMEDIA_WAVJAMMER "NewMedia .WAVjammer"
+#define PCMCIA_CIS_NEWMEDIA2_BUSTOASTER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA2_BUSTOASTER 0x0001
+#define PCMCIA_STR_NEWMEDIA2_BUSTOASTER "NewMedia BusToaster"
+
+/* Netgear */
+#define PCMCIA_CIS_NETGEAR_FA410TX { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NETGEAR_FA410TX 0x0230
+#define PCMCIA_STR_NETGEAR_FA410TX "Netgear FA410TX"
+#define PCMCIA_CIS_NETGEAR_FA410TXC { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NETGEAR_FA410TXC 0x4530
+#define PCMCIA_STR_NETGEAR_FA410TXC "Netgear FA410TXC"
+#define PCMCIA_CIS_NETGEAR_FA411 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NETGEAR_FA411 0x0411
+#define PCMCIA_STR_NETGEAR_FA411 "Netgear FA411"
+
+/* National Instruments */
+#define PCMCIA_CIS_NI_PCMCIA_GPIB { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NI_PCMCIA_GPIB 0x4882
+#define PCMCIA_STR_NI_PCMCIA_GPIB "National Instruments PCMCIA-GPIB"
+
+/* Nokia Products */
+#define PCMCIA_CIS_NOKIA_C110_WLAN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NOKIA_C110_WLAN 0x1110
+#define PCMCIA_STR_NOKIA_C110_WLAN "Nokia C110/C111"
+#define PCMCIA_CIS_NOKIA_C020_WLAN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NOKIA_C020_WLAN 0x20c0
+#define PCMCIA_STR_NOKIA_C020_WLAN "Nokia C020 WLAN Card"
+
+/* No Wires Needed */
+#define PCMCIA_CIS_NWN_WLAN_550 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NWN_WLAN_550 0x0002
+#define PCMCIA_STR_NWN_WLAN_550 "NWN 550 WLAN"
+#define PCMCIA_CIS_NWN_WLAN_1148 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_NWN_WLAN_1148 0x0003
+#define PCMCIA_STR_NWN_WLAN_1148 "NWN 1148 WLAN"
+
+/* Olicom Products */
+#define PCMCIA_CIS_OLICOM_TR { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_OLICOM_TR 0x2132
+#define PCMCIA_STR_OLICOM_TR "GoCard Token Ring 16/4"
+#define PCMCIA_CIS_OLICOM_OC2220 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_OLICOM_OC2220 0x2022
+#define PCMCIA_STR_OLICOM_OC2220 "GoCard Ethernet"
+#define PCMCIA_CIS_OLICOM_OC2231 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_OLICOM_OC2231 0x3122
+#define PCMCIA_STR_OLICOM_OC2231 "GoCard Combo Eth/Modem 288"
+#define PCMCIA_CIS_OLICOM_OC2232 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_OLICOM_OC2232 0x3222
+#define PCMCIA_STR_OLICOM_OC2232 "GoCard Combo Eth/Modem 336"
+
+/* Ositech Products */
+#define PCMCIA_CIS_OSITECH_TRUMPCARD_SOD { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_OSITECH_TRUMPCARD_SOD 0x0008
+#define PCMCIA_STR_OSITECH_TRUMPCARD_SOD "Ositech Seven of Diamonds Ethernet Card"
+
+/* Panasonic Products */
+#define PCMCIA_CIS_PANASONIC_KXLC002 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PANASONIC_KXLC002 0x0304
+#define PCMCIA_STR_PANASONIC_KXLC002 "Panasonic 4X CD-ROM Interface Card"
+#define PCMCIA_CIS_PANASONIC_KXLC003 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PANASONIC_KXLC003 0x0504
+#define PCMCIA_STR_PANASONIC_KXLC003 "Panasonic 8X CD-ROM Interface Card"
+#define PCMCIA_CIS_PANASONIC_KXLC004 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PANASONIC_KXLC004 0x0604
+#define PCMCIA_STR_PANASONIC_KXLC004 "Panasonic KXL-810AN Interface Card"
+#define PCMCIA_CIS_PANASONIC_KXLC005 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PANASONIC_KXLC005 0x2704
+#define PCMCIA_STR_PANASONIC_KXLC005 "Panasonic 16X CD-ROM Interface Card"
+#define PCMCIA_CIS_PANASONIC_KME { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PANASONIC_KME 0x2604
+#define PCMCIA_STR_PANASONIC_KME "Panasonic CD-R/RW Interface"
+
+/* Planex */
+#define PCMCIA_CIS_PLANEX_2_GWNS11H { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PLANEX_2_GWNS11H 0xb001
+#define PCMCIA_STR_PLANEX_2_GWNS11H "Planex GW-NS11H"
+
+/* Proxim */
+#define PCMCIA_CIS_PROXIM_HARMONY { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PROXIM_HARMONY 0x0002
+#define PCMCIA_STR_PROXIM_HARMONY "Proxim HARMONY 80211B"
+#define PCMCIA_CIS_PROXIM_ROAMABOUT_2400FH { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PROXIM_ROAMABOUT_2400FH 0x1058
+#define PCMCIA_STR_PROXIM_ROAMABOUT_2400FH "Digital RoamAbout 2400FH"
+#define PCMCIA_CIS_PROXIM_RANGELAN2_7401 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PROXIM_RANGELAN2_7401 0x1158
+#define PCMCIA_STR_PROXIM_RANGELAN2_7401 "Proxim RangeLAN2 7401"
+#define PCMCIA_CIS_PROXIM_RANGELANDS_8430 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PROXIM_RANGELANDS_8430 0x8000
+#define PCMCIA_STR_PROXIM_RANGELANDS_8430 "Proxim RangeLAN-DS 8430"
+
+/* Psion */
+#define PCMCIA_CIS_PSION_GOLDCARD { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PSION_GOLDCARD 0x0020
+#define PCMCIA_STR_PSION_GOLDCARD "Psion Gold Card"
+
+/* QLogic */
+#define PCMCIA_CIS_QLOGIC_PC05 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_QLOGIC_PC05 0x0104
+#define PCMCIA_STR_QLOGIC_PC05 "Qlogic Fast SCSI"
+
+/* Quatech */
+#define PCMCIA_CIS_QUATECH_SPP_100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_QUATECH_SPP_100 0x0003
+#define PCMCIA_STR_QUATECH_SPP_100 "Quatech Enhanced Parallel Port"
+#define PCMCIA_CIS_QUATECH_DSP_225 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_QUATECH_DSP_225 0x0008
+#define PCMCIA_STR_QUATECH_DSP_225 "Quatech Dual Serial Port"
+
+/* RATOC System Inc. Products */
+/* Don't use because both cards have same product id */
+#define PCMCIA_CIS_RATOC_REX_R280_9530 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX_R280_9530 0x0001
+#define PCMCIA_STR_RATOC_REX_R280_9530 "RATOC REX-R280/REX-9530"
+
+/* Raylink/WebGear */
+#define PCMCIA_CIS_RAYTHEON_WLAN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_RAYTHEON_WLAN 0x0000
+#define PCMCIA_STR_RAYTHEON_WLAN "WLAN Adapter"
+
+/* Roland */
+#define PCMCIA_CIS_ROLAND_SCP55 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ROLAND_SCP55 0x0001
+#define PCMCIA_STR_ROLAND_SCP55 "Roland SCP-55"
+
+/* Samsung */
+#define PCMCIA_CIS_SAMSUNG_SWL_2000N { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SAMSUNG_SWL_2000N 0x0002
+#define PCMCIA_STR_SAMSUNG_SWL_2000N "Samsung MagicLAN SWL-2000N"
+
+/* Sandisk Products */
+#define PCMCIA_CIS_SANDISK_SDCFB { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SANDISK_SDCFB 0x0401
+#define PCMCIA_STR_SANDISK_SDCFB "Sandisk CompactFlash Card"
+
+/* Sharp Products */
+#define PCMCIA_CIS_SHARP_PALDIO611S { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SHARP_PALDIO611S 0x0000
+#define PCMCIA_STR_SHARP_PALDIO611S "PALDIO 611S PC CARD"
+
+/* Siemens */
+#define PCMCIA_CIS_SIEMENS_SS1021 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SIEMENS_SS1021 0x0002
+#define PCMCIA_STR_SIEMENS_SS1021 "Siemens SpeedStream 1021"
+
+/* Simple Technology Products */
+#define PCMCIA_CIS_SIMPLETECH_COMMUNICATOR288 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SIMPLETECH_COMMUNICATOR288 0x0100
+#define PCMCIA_STR_SIMPLETECH_COMMUNICATOR288 "Simple Technology 28.8 Communicator"
+/* Simpletech ID also used by Symbol */
+#define PCMCIA_CIS_SIMPLETECH_SPECTRUM24 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SIMPLETECH_SPECTRUM24 0x801
+#define PCMCIA_STR_SIMPLETECH_SPECTRUM24 "Symbol Spectrum24 WLAN Adapter"
+
+/* Standard Microsystems Corporation Products */
+#define PCMCIA_CIS_SMC_8016 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SMC_8016 0x0105
+#define PCMCIA_STR_SMC_8016 "SMC 8016 EtherCard"
+#define PCMCIA_CIS_SMC_EZCARD { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SMC_EZCARD 0x8022
+#define PCMCIA_STR_SMC_EZCARD "SMC EZCard 10 PCMCIA"
+
+/* Socket Communications Products */
+#define PCMCIA_CIS_SOCKET_EA_ETHER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_EA_ETHER 0x0000
+#define PCMCIA_STR_SOCKET_EA_ETHER "Socket Communications EA"
+#define PCMCIA_CIS_SOCKET_LP_WLAN_CF { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_LP_WLAN_CF 0x0001
+#define PCMCIA_STR_SOCKET_LP_WLAN_CF "Socket Communications Low Power WLAN Card"
+#define PCMCIA_CIS_SOCKET_PAGECARD { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_PAGECARD 0x0003
+#define PCMCIA_STR_SOCKET_PAGECARD "Socket Communications PageCard"
+#define PCMCIA_CIS_SOCKET_DUAL_RS232 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_DUAL_RS232 0x0006
+#define PCMCIA_STR_SOCKET_DUAL_RS232 "Socket Communications Dual RS232"
+#define PCMCIA_CIS_SOCKET_LP_ETHER { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_LP_ETHER 0x000d
+#define PCMCIA_STR_SOCKET_LP_ETHER "Socket Communications LP-E"
+#define PCMCIA_CIS_SOCKET_LP_ETHER_CF { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_LP_ETHER_CF 0x0075
+#define PCMCIA_STR_SOCKET_LP_ETHER_CF "Socket Communications LP-E CF"
+#define PCMCIA_CIS_SOCKET_LP_ETH_10_100_CF { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SOCKET_LP_ETH_10_100_CF 0x0145
+#define PCMCIA_STR_SOCKET_LP_ETH_10_100_CF "Socket Communications 10/100 Ethernet"
+
+/* Symbol */
+#define PCMCIA_CIS_SYMBOL_LA4100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_SYMBOL_LA4100 0x0001
+#define PCMCIA_STR_SYMBOL_LA4100 "Symbol Spectrum24 LA4100 Series WLAN"
+
+/* TDK Products */
+#define PCMCIA_CIS_TDK_LAK_CD011WL { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TDK_LAK_CD011WL 0x0000
+#define PCMCIA_STR_TDK_LAK_CD011WL "TDK LAK-CD011WL"
+#define PCMCIA_CIS_TDK_LAK_CD021BX { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TDK_LAK_CD021BX 0x0200
+#define PCMCIA_STR_TDK_LAK_CD021BX "TDK LAK-CD021BX Ethernet"
+#define PCMCIA_CIS_TDK_LAK_CF010 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TDK_LAK_CF010 0x0900
+#define PCMCIA_STR_TDK_LAK_CF010 "TDK LAC-CF010"
+#define PCMCIA_CIS_TDK_DFL9610 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TDK_DFL9610 0x0d0a
+#define PCMCIA_STR_TDK_DFL9610 "TDK DFL9610 Ethernet & Digital Cellular"
+#define PCMCIA_CIS_TDK_C6500012 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TDK_C6500012 0x410a
+#define PCMCIA_STR_TDK_C6500012 "TDK ELSA MicroLink MC all"
+#define PCMCIA_CIS_TDK_LAK_CD031 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TDK_LAK_CD031 0xc1ab
+#define PCMCIA_STR_TDK_LAK_CD031 "TDK LAK-CD031 Ethernet"
+
+/* Telecom Device */
+#define PCMCIA_CIS_TELECOMDEVICE_TCD_HPC100 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_TELECOMDEVICE_TCD_HPC100 0x0202
+#define PCMCIA_STR_TELECOMDEVICE_TCD_HPC100 "Telecom Device TCD-HPC100"
+
+/* US Robotics Products */
+#define PCMCIA_CIS_USROBOTICS_WORLDPORT144 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_USROBOTICS_WORLDPORT144 0x3330
+#define PCMCIA_STR_USROBOTICS_WORLDPORT144 "US Robotics WorldPort 14.4 Modem"
+
+/* WORKBIT Products */
+#define PCMCIA_CIS_WORKBIT_ULTRA_NINJA_16 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_WORKBIT_ULTRA_NINJA_16 0x8006
+#define PCMCIA_STR_WORKBIT_ULTRA_NINJA_16 "WORKBIT Ultra Ninja-16 (16bit mode)"
+
+/* Xircom Products */
+#define PCMCIA_CIS_XIRCOM_CWE1130 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CWE1130 0x0007
+#define PCMCIA_STR_XIRCOM_CWE1130 "Xircom Wireless Ethernet Adapter"
+#define PCMCIA_CIS_XIRCOM_CE { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CE 0x0108
+#define PCMCIA_STR_XIRCOM_CE "Xircom CreditCard Ethernet"
+#define PCMCIA_CIS_XIRCOM_CE3 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CE3 0x010a
+#define PCMCIA_STR_XIRCOM_CE3 "Xircom CreditCard 10/100 Ethernet"
+#define PCMCIA_CIS_XIRCOM_CE2 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CE2 0x010b
+#define PCMCIA_STR_XIRCOM_CE2 "Xircom CreditCard Ethernet II"
+#define PCMCIA_CIS_XIRCOM_XE2000 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_XE2000 0x0153
+#define PCMCIA_STR_XIRCOM_XE2000 "Xircom XE2000 10/100 Ethernet"
+#define PCMCIA_CIS_XIRCOM_CNW_801 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CNW_801 0x0801
+#define PCMCIA_STR_XIRCOM_CNW_801 "Xircom CreditCard Netwave (Canada)"
+#define PCMCIA_CIS_XIRCOM_CNW_802 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CNW_802 0x0802
+#define PCMCIA_STR_XIRCOM_CNW_802 "Xircom CreditCard Netwave (US)"
+#define PCMCIA_CIS_XIRCOM_CT2 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CT2 0x1101
+#define PCMCIA_STR_XIRCOM_CT2 "Xircom CreditCard Token Ring II"
+#define PCMCIA_CIS_XIRCOM_CEM { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CEM 0x110a
+#define PCMCIA_STR_XIRCOM_CEM "Xircom CreditCard Ethernet + Modem"
+#define PCMCIA_CIS_XIRCOM_REM56 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_REM56 0x110a
+#define PCMCIA_STR_XIRCOM_REM56 "Xircom RealPort Ethernet 10/100 + Modem 56"
+#define PCMCIA_CIS_XIRCOM_CEM28 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CEM28 0x110b
+#define PCMCIA_STR_XIRCOM_CEM28 "Xircom CreditCard Ethernet + Modem 28"
+#define PCMCIA_CIS_XIRCOM_CEM56 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CEM56 0x110b
+#define PCMCIA_STR_XIRCOM_CEM56 "Xircom CreditCard Ethernet + Modem 56"
+#define PCMCIA_CIS_XIRCOM_CEM33 { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_XIRCOM_CEM33 0x110d
+#define PCMCIA_STR_XIRCOM_CEM33 "Xircom CreditCard Ethernet + Modem 33"
+
+/* ZONET */
+#define PCMCIA_CIS_ZONET_ZEN { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_ZONET_ZEN 0x0100
+#define PCMCIA_STR_ZONET_ZEN "Zonet Zen 10/10"
+
+/*
+ * Cards we know only by their cis, sorted by name.
+ */
+#define PCMCIA_VENDOR_AMBICOM 0xffffffff /* AmbiCom Inc */
+#define PCMCIA_VENDOR_ACCTON 0xffffffff /* ACCTON */
+#define PCMCIA_VENDOR_ADDTRON 0xffffffff /* Addtron */
+#define PCMCIA_VENDOR_ARGOSY 0xffffffff /* ARGOSY */
+#define PCMCIA_VENDOR_AMD 0xffffffff /* AMD */
+#define PCMCIA_VENDOR_BILLIONTON 0xffffffff /* Billionton Systems Inc. */
+#define PCMCIA_VENDOR_CNET 0xffffffff /* CNet */
+#define PCMCIA_VENDOR_COREGA 0xffffffff /* Corega K.K. */
+#define PCMCIA_VENDOR_DIGITAL 0xffffffff /* Digital Equipment Corporation */
+#define PCMCIA_VENDOR_DLINK 0xffffffff /* D-Link */
+#define PCMCIA_VENDOR_DYNALINK 0xffffffff /* DynaLink */
+#define PCMCIA_VENDOR_EIGERLABS 0xffffffff /* Eiger labs,Inc. */
+#define PCMCIA_VENDOR_EPSON 0xffffffff /* Seiko Epson Corporation */
+#define PCMCIA_VENDOR_EXP 0xffffffff /* EXP Computer Inc */
+#define PCMCIA_VENDOR_FUJITSU2 0xffffffff /* Fujitsu */
+#define PCMCIA_VENDOR_FUTUREDOMAIN 0xffffffff /* FutureDomain */
+#define PCMCIA_VENDOR_FREECOM 0xffffffff /* Freecom */
+#define PCMCIA_VENDOR_GEMTEK 0xffffffff /* Gem Tek */
+#define PCMCIA_VENDOR_ICOM 0xffffffff /* ICOM Inc */
+#define PCMCIA_VENDOR_INTERSIL2 0xffffffff /* Intersil */
+#define PCMCIA_VENDOR_IODATA3 0xffffffff /* I-O DATA */
+#define PCMCIA_VENDOR_LANTECH 0xffffffff /* Lantech Computer Company */
+#define PCMCIA_VENDOR_MELCO2 0xffffffff /* Melco Corporation */
+#define PCMCIA_VENDOR_NAKAGAWAMETAL 0xffffffff /* NAKAGAWA METAL */
+#define PCMCIA_VENDOR_NDC 0xffffffff /* NDC */
+#define PCMCIA_VENDOR_NEC 0xffffffff /* NEC */
+#define PCMCIA_VENDOR_OEM2 0xffffffff /* Generic OEM */
+#define PCMCIA_VENDOR_PLANET 0xffffffff /* Planet */
+#define PCMCIA_VENDOR_PLANEX 0xffffffff /* Planex Communications Inc */
+#define PCMCIA_VENDOR_PREMAX 0xffffffff /* Premax */
+#define PCMCIA_VENDOR_RPTI 0xffffffff /* RPTI */
+#define PCMCIA_VENDOR_SVEC 0xffffffff /* SVEC/Hawking Technology */
+#define PCMCIA_VENDOR_SYNERGY21 0xffffffff /* Synergy 21 */
+#define PCMCIA_VENDOR_TEAC 0xffffffff /* TEAC */
+#define PCMCIA_VENDOR_TOSHIBA 0xffffffff /* TOSHIBA */
+#define PCMCIA_VENDOR_WORKBIT2 0xffffffff /* WORKBIT */
+#define PCMCIA_VENDOR_YEDATA 0xffffffff /* Y-E DATA */
+#define PCMCIA_VENDOR_YIS 0xffffffff /* YIS Corporation */
+#define PCMCIA_VENDOR_ZOOM 0xffffffff /* ZOOM */
+
+#define PCMCIA_CIS_ACCTON_EN2212 { "ACCTON", "EN2212", NULL, NULL }
+#define PCMCIA_PRODUCT_ACCTON_EN2212 0xffffffff
+#define PCMCIA_STR_ACCTON_EN2212 "Accton EN2212"
+#define PCMCIA_CIS_ACCTON_EN2216 { "ACCTON", "EN2216-PCMCIA-ETHERNET", "EN2216R01", NULL }
+#define PCMCIA_PRODUCT_ACCTON_EN2216 0xffffffff
+#define PCMCIA_STR_ACCTON_EN2216 "Accton EN2216"
+#define PCMCIA_CIS_ACCTON_EN2226 { "Accton", "Fast EtherCard-16", "EN2226", "1.00" }
+#define PCMCIA_PRODUCT_ACCTON_EN2226 0xffffffff
+#define PCMCIA_STR_ACCTON_EN2226 "Accton EN2226"
+#define PCMCIA_CIS_ADDTRON_AWP100 { "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", NULL }
+#define PCMCIA_PRODUCT_ADDTRON_AWP100 0xffffffff
+#define PCMCIA_STR_ADDTRON_AWP100 ""
+#define PCMCIA_CIS_ALLIEDTELESIS_WR211PCM { "Allied Telesis K.K.", "WR211PCM", NULL, NULL }
+#define PCMCIA_PRODUCT_ALLIEDTELESIS_WR211PCM 0xffffffff
+#define PCMCIA_STR_ALLIEDTELESIS_WR211PCM "Allied Telesis WR211PCM"
+#define PCMCIA_CIS_AMBICOM_AMB8002T { "AmbiCom Inc", "AMB8002T", NULL, NULL }
+#define PCMCIA_PRODUCT_AMBICOM_AMB8002T 0xffffffff
+#define PCMCIA_STR_AMBICOM_AMB8002T "AmbiCom AMB8002T"
+#define PCMCIA_CIS_AMD_AM79C930 { "AMD", "Am79C930", NULL, NULL }
+#define PCMCIA_PRODUCT_AMD_AM79C930 0xffffffff
+#define PCMCIA_STR_AMD_AM79C930 "AMD Am79C930"
+#define PCMCIA_CIS_ARGOSY_SP320 { "PCMCIA", "RS-COM 2P", NULL, NULL
+#define PCMCIA_PRODUCT_ARGOSY_SP320 0xffffffff
+#define PCMCIA_STR_ARGOSY_SP320 "} ARGOSY SP320 Dual port serial PCMCIA"
+#define PCMCIA_CIS_BILLIONTON_CFLT10N { "CF", "10Base-Ethernet", "1.0", NULL }
+#define PCMCIA_PRODUCT_BILLIONTON_CFLT10N 0xffffffff
+#define PCMCIA_STR_BILLIONTON_CFLT10N "Billionton Systems Inc. CFLT10N Ethernet"
+#define PCMCIA_CIS_BILLIONTON_LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL }
+#define PCMCIA_PRODUCT_BILLIONTON_LNT10TN 0xffffffff
+#define PCMCIA_STR_BILLIONTON_LNT10TN "Billionton Systems Inc. LNT-10TN NE2000 Compatible Card"
+#define PCMCIA_CIS_CNET_NE2000 { "CNet", "CN40BC Ethernet", "D", "NE2000" }
+#define PCMCIA_PRODUCT_CNET_NE2000 0xffffffff
+#define PCMCIA_STR_CNET_NE2000 "CNet CN40BC NE2000 Compatible"
+#define PCMCIA_CIS_COREGA_ETHER_PCC_T { "corega K.K.", "corega Ether PCC-T", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_ETHER_PCC_T 0xffffffff
+#define PCMCIA_STR_COREGA_ETHER_PCC_T "Corega Ether PCC-T"
+#define PCMCIA_CIS_COREGA_ETHER_PCC_TD { "corega K.K.", "corega Ether PCC-TD", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_ETHER_PCC_TD 0xffffffff
+#define PCMCIA_STR_COREGA_ETHER_PCC_TD "Corega Ether PCC-TD"
+#define PCMCIA_CIS_COREGA_ETHER_II_PCC_T { "corega K.K.", "corega EtherII PCC-T", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_ETHER_II_PCC_T 0xffffffff
+#define PCMCIA_STR_COREGA_ETHER_II_PCC_T "Corega EtherII PCC-T"
+#define PCMCIA_CIS_COREGA_ETHER_II_PCC_TD { "corega K.K.", "corega EtherII PCC-TD", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_ETHER_II_PCC_TD 0xffffffff
+#define PCMCIA_STR_COREGA_ETHER_II_PCC_TD "Corega EtherII PCC-TD"
+#define PCMCIA_CIS_COREGA_FAST_ETHER_PCC_TX { "corega K.K.", "corega FastEther PCC-TX", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_FAST_ETHER_PCC_TX 0xffffffff
+#define PCMCIA_STR_COREGA_FAST_ETHER_PCC_TX "Corega FastEther PCC-TX"
+#define PCMCIA_CIS_COREGA_FETHER_PCC_TXD { "corega K.K.", "corega FEther PCC-TXD", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_FETHER_PCC_TXD 0xffffffff
+#define PCMCIA_STR_COREGA_FETHER_PCC_TXD "Corega FEther PCC-TXD"
+#define PCMCIA_CIS_COREGA_FETHER_PCC_TXF { "corega", "FEther PCC-TXF", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_FETHER_PCC_TXF 0xffffffff
+#define PCMCIA_STR_COREGA_FETHER_PCC_TXF "Corega FEther PCC-TXF"
+#define PCMCIA_CIS_COREGA_WIRELESS_LAN_PCC_11 { "corega K.K.", "Wireless LAN PCC-11", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCC_11 0xffffffff
+#define PCMCIA_STR_COREGA_WIRELESS_LAN_PCC_11 "Corega Wireless LAN PCC-11"
+#define PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCA_11 { "corega K.K.", "Wireless LAN PCCA-11", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCA_11 0xffffffff
+#define PCMCIA_STR_COREGA_WIRELESS_LAN_PCCA_11 "Corega Wireless LAN PCCA-11"
+#define PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCB_11 { "corega_K.K.", "Wireless_LAN_PCCB-11", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCB_11 0xffffffff
+#define PCMCIA_STR_COREGA_WIRELESS_LAN_PCCB_11 "Corega Wireless LAN PCCB-11"
+#define PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCL_11 { "corega", "WL PCCL-11", NULL, NULL }
+#define PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCL_11 0xffffffff
+#define PCMCIA_STR_COREGA_WIRELESS_LAN_PCCL_11 "Corega Wireless LAN PCCL-11"
+
+#define PCMCIA_CIS_DIGITAL_DEPCMXX { "DIGITAL", "DEPCM-XX", NULL, NULL }
+#define PCMCIA_PRODUCT_DIGITAL_DEPCMXX 0xffffffff
+#define PCMCIA_STR_DIGITAL_DEPCMXX "DEC DEPCM-BA"
+#define PCMCIA_CIS_DLINK_DE650 { "D-Link", "DE-650", NULL, NULL }
+#define PCMCIA_PRODUCT_DLINK_DE650 0xffffffff
+#define PCMCIA_STR_DLINK_DE650 "D-Link DE-650"
+#define PCMCIA_CIS_DLINK_DE660 { "D-Link", "DE-660", NULL, NULL }
+#define PCMCIA_PRODUCT_DLINK_DE660 0xffffffff
+#define PCMCIA_STR_DLINK_DE660 "D-Link DE-660"
+#define PCMCIA_CIS_DLINK_DE660PLUS { "D-Link", "DE-660+", NULL, NULL }
+#define PCMCIA_PRODUCT_DLINK_DE660PLUS 0xffffffff
+#define PCMCIA_STR_DLINK_DE660PLUS "D-Link DE-660+"
+#define PCMCIA_CIS_DLINK_DFE670TXD { "D-Link", "DFE-670TXD", NULL, NULL }
+#define PCMCIA_PRODUCT_DLINK_DFE670TXD 0xffffffff
+#define PCMCIA_STR_DLINK_DFE670TXD "D-Link DFE-670TXD"
+#define PCMCIA_CIS_DLINK_DWL650H { "D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", NULL, NULL }
+#define PCMCIA_PRODUCT_DLINK_DWL650H 0xffffffff
+#define PCMCIA_STR_DLINK_DWL650H "D-Link DWL-650H"
+#define PCMCIA_CIS_DYNALINK_L10C { "DYNALINK", "L10C", NULL, NULL }
+#define PCMCIA_PRODUCT_DYNALINK_L10C 0xffffffff
+#define PCMCIA_STR_DYNALINK_L10C "Dynalink L10C"
+/*
+ * vendor ID of EPX_AA2000 is Fujitsu (0x0004) and product ID is 0x2000, but
+ * it conflicts with Fujitsu Towa LA501 Ethernet.
+ */
+#define PCMCIA_CIS_EIGERLABS_EPX_AA2000 { "Eiger labs,Inc.", "EPX-AA2000 PC Sound Card", NULL, NULL }
+#define PCMCIA_PRODUCT_EIGERLABS_EPX_AA2000 0xffffffff
+#define PCMCIA_STR_EIGERLABS_EPX_AA2000 "EPX-AA2000 PC Sound Card"
+#define PCMCIA_CIS_EPSON_EEN10B { "Seiko Epson Corp.", "Ethernet", "P/N: EEN10B Rev. 00", NULL }
+#define PCMCIA_PRODUCT_EPSON_EEN10B 0xffffffff
+#define PCMCIA_STR_EPSON_EEN10B "Epson EEN10B"
+#define PCMCIA_CIS_EPSON_SC200 { "EPSON", "SCSI-2 PC Card SC200", NULL, NULL }
+#define PCMCIA_PRODUCT_EPSON_SC200 0xffffffff
+#define PCMCIA_STR_EPSON_SC200 "Media Intelligent SCSI-2 PC Card MSC-200"
+#define PCMCIA_CIS_EXP_EXPMULTIMEDIA { "EXP ", "PnPIDE", "F1", NULL }
+#define PCMCIA_PRODUCT_EXP_EXPMULTIMEDIA 0xffffffff
+#define PCMCIA_STR_EXP_EXPMULTIMEDIA "EXP IDE/ATAPI DVD Card"
+#define PCMCIA_CIS_EXP_THINLANCOMBO { "PCMCIA LAN", "Ethernet", NULL, NULL }
+#define PCMCIA_PRODUCT_EXP_THINLANCOMBO 0xffffffff
+#define PCMCIA_STR_EXP_THINLANCOMBO "EXP ThinLan Combo"
+#define PCMCIA_CIS_FREECOM_PCCARDIDE { "FREECOM", "PCCARD-IDE", NULL, NULL }
+#define PCMCIA_PRODUCT_FREECOM_PCCARDIDE 0xffffffff
+#define PCMCIA_STR_FREECOM_PCCARDIDE "FREECOM PCCARD-IDE"
+#define PCMCIA_CIS_FUJITSU2_FMV_J181 { "PCMCIA MBH10302", "01", NULL, NULL }
+#define PCMCIA_PRODUCT_FUJITSU2_FMV_J181 0xffffffff
+#define PCMCIA_STR_FUJITSU2_FMV_J181 "FUJITSU FMV-J181 PCMCIA Card"
+#define PCMCIA_CIS_FUJITSU2_FMV_J182 { "FUJITSU", "LAN Card(FMV-J182)", "Ver.01", NULL }
+#define PCMCIA_PRODUCT_FUJITSU2_FMV_J182 0xffffffff
+#define PCMCIA_STR_FUJITSU2_FMV_J182 "FUJITSU FMV-J182 PCMCIA Card"
+#define PCMCIA_CIS_FUJITSU2_FMV_J182A { "FUJITSU", "LAN Card(FMV-J182)", "Ver.02", NULL }
+#define PCMCIA_PRODUCT_FUJITSU2_FMV_J182A 0xffffffff
+#define PCMCIA_STR_FUJITSU2_FMV_J182A "FUJITSU FMV-J182A PCMCIA Card"
+#define PCMCIA_CIS_FUJITSU2_ITCFJ182A { "FUJITSU", "LAN Card(ITCFJ182)", "Ver.01", NULL }
+#define PCMCIA_PRODUCT_FUJITSU2_ITCFJ182A 0xffffffff
+#define PCMCIA_STR_FUJITSU2_ITCFJ182A "FUJITSU ITCFJ182A CompactCard"
+#define PCMCIA_CIS_FUTUREDOMAIN_SCSI2GO { "Future Domain Corporation" "SCSI PCMCIA Credit Card Controller", NULL, NULL }
+#define PCMCIA_PRODUCT_FUTUREDOMAIN_SCSI2GO 0xffffffff
+#define PCMCIA_STR_FUTUREDOMAIN_SCSI2GO "Future Domain SCSI2GO"
+#define PCMCIA_CIS_GEMTEK_WLAN { "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P", "Eval-RevA" }
+#define PCMCIA_PRODUCT_GEMTEK_WLAN 0xffffffff
+#define PCMCIA_STR_GEMTEK_WLAN "GEMTEK Prism2_5 WaveLAN Card"
+#define PCMCIA_CIS_IBM_SCSICARD { "IBM Corp.", "SCSI PCMCIA Card", NULL, NULL }
+#define PCMCIA_PRODUCT_IBM_SCSICARD 0xffffffff
+#define PCMCIA_STR_IBM_SCSICARD "IBM SCSI PCMCIA Card"
+#define PCMCIA_CIS_ICOM_SL200 { "Icom", "SL-200", NULL, NULL }
+#define PCMCIA_PRODUCT_ICOM_SL200 0xffffffff
+#define PCMCIA_STR_ICOM_SL200 "Icom SL-200"
+#define PCMCIA_CIS_INTERSIL2_PRISM2 { "INTERSIL", "HFA384x/IEEE", "Version 01.02", NULL }
+#define PCMCIA_PRODUCT_INTERSIL2_PRISM2 0xffffffff
+#define PCMCIA_STR_INTERSIL2_PRISM2 "Intersil Prism II"
+#define PCMCIA_CIS_IODATA_CBIDE2 { "IO DATA", "CBIDE2 ", NULL, NULL }
+#define PCMCIA_PRODUCT_IODATA_CBIDE2 0xffffffff
+#define PCMCIA_STR_IODATA_CBIDE2 "IO-DATA CBIDE2/16-bit mode"
+#define PCMCIA_CIS_IODATA3_CBSC16 { "IO DATA", "CBSC16 ", NULL, NULL }
+#define PCMCIA_PRODUCT_IODATA3_CBSC16 0xffffffff
+#define PCMCIA_STR_IODATA3_CBSC16 "IO-DATA CBSC16"
+#define PCMCIA_CIS_IODATA_PCLAT { "I-O DATA", "PCLA", "ETHERNET", NULL }
+#define PCMCIA_PRODUCT_IODATA_PCLAT 0xffffffff
+#define PCMCIA_STR_IODATA_PCLAT "IO-DATA PCLA/T"
+#define PCMCIA_CIS_LANTECH_FASTNETTX { "ASIX", "AX88190", NULL, NULL }
+#define PCMCIA_PRODUCT_LANTECH_FASTNETTX 0xffffffff
+#define PCMCIA_STR_LANTECH_FASTNETTX "Lantech Fastnet/TX"
+#define PCMCIA_CIS_LINKSYS_ECARD_2 { "LINKSYS", "E-CARD", NULL, NULL }
+#define PCMCIA_PRODUCT_LINKSYS_ECARD_2 0xffffffff
+#define PCMCIA_STR_LINKSYS_ECARD_2 "Linksys E-Card"
+#define PCMCIA_CIS_LINKSYS_PCM100 { "Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", "Ver 1.0", NULL }
+#define PCMCIA_PRODUCT_LINKSYS_PCM100 0xffffffff
+#define PCMCIA_STR_LINKSYS_PCM100 ""
+#define PCMCIA_CIS_MACNICA_MPS100 { "MACNICA", "MIRACLE SCSI", "mPS100", "D.0" }
+#define PCMCIA_PRODUCT_MACNICA_MPS100 0xffffffff
+#define PCMCIA_STR_MACNICA_MPS100 "Macnica Miracle SCSI mPS100"
+#define PCMCIA_CIS_MEGAHERTZ_XJ2288 { "MEGAHERTZ", "MODEM XJ2288", NULL, NULL }
+#define PCMCIA_PRODUCT_MEGAHERTZ_XJ2288 0xffffffff
+#define PCMCIA_STR_MEGAHERTZ_XJ2288 "Megahertz XJ2288 Modem"
+#define PCMCIA_CIS_MELCO2_LPC2_TX { "MELCO", "LPC2-TX", NULL, NULL }
+#define PCMCIA_PRODUCT_MELCO2_LPC2_TX 0xffffffff
+#define PCMCIA_STR_MELCO2_LPC2_TX "Melco LPC2-TX"
+#define PCMCIA_CIS_NAKAGAWAMETAL_LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL }
+#define PCMCIA_PRODUCT_NAKAGAWAMETAL_LNT10TN 0xffffffff
+#define PCMCIA_STR_NAKAGAWAMETAL_LNT10TN "NAKAGAWA METAL LNT-10TN NE2000 Compatible Card"
+#define PCMCIA_CIS_NANOSPEED_PRISM2 { "NANOSPEED", "HFA384x/IEEE", "Version 01.02", NULL }
+#define PCMCIA_PRODUCT_NANOSPEED_PRISM2 0xffffffff
+#define PCMCIA_STR_NANOSPEED_PRISM2 "NANOSPEED ROOT-RZ2000 WLAN Card"
+#define PCMCIA_CIS_NDC_ND5100_E { "NDC", "Ethernet", "A", NULL }
+#define PCMCIA_PRODUCT_NDC_ND5100_E 0xffffffff
+#define PCMCIA_STR_NDC_ND5100_E "Sohoware ND5100E NE2000 Compatible Card"
+#define PCMCIA_CIS_NEC_CMZ_RT_WP { "NEC", "Wireless Card CMZ-RT-WP", "Version 01.01", NULL }
+#define PCMCIA_PRODUCT_NEC_CMZ_RT_WP 0xffffffff
+#define PCMCIA_STR_NEC_CMZ_RT_WP "NEC Wireless Card CMZ-RT-WP"
+#define PCMCIA_CIS_NEC_PC9801N_J03R { "NEC", "PC-9801N-J03R", NULL, NULL }
+#define PCMCIA_PRODUCT_NEC_PC9801N_J03R 0xffffffff
+#define PCMCIA_STR_NEC_PC9801N_J03R "NEC PC-9801N-J03R"
+#define PCMCIA_CIS_NEWMEDIA_BASICS_SCSI { "BASICS by New Media Corporation" "SCSI Sym53C500", NULL, NULL }
+#define PCMCIA_PRODUCT_NEWMEDIA_BASICS_SCSI 0xffffffff
+#define PCMCIA_STR_NEWMEDIA_BASICS_SCSI "New Media Corporation BASICS SCSI"
+#define PCMCIA_CIS_NTT_ME_WLAN { "NTT-ME", "11Mbps Wireless LAN PC Card", NULL, NULL }
+#define PCMCIA_PRODUCT_NTT_ME_WLAN 0xffffffff
+#define PCMCIA_STR_NTT_ME_WLAN "NTT-ME 11Mbps Wireless LAN PC Card"
+#define PCMCIA_CIS_OEM2_CDROM1 { "PCMCIA", "CD-ROM", NULL, NULL }
+#define PCMCIA_PRODUCT_OEM2_CDROM1 0xffffffff
+#define PCMCIA_STR_OEM2_CDROM1 "Generic PCMCIA CD-ROM"
+#define PCMCIA_CIS_OEM2_IDE { "PCMCIA", "IDE CARD", NULL, NULL }
+#define PCMCIA_PRODUCT_OEM2_IDE 0xffffffff
+#define PCMCIA_STR_OEM2_IDE "Generic PCMCIA IDE CARD"
+#define PCMCIA_CIS_PLANET_SMARTCOM2000 { "PCMCIA", "UE2212", NULL, NULL }
+#define PCMCIA_PRODUCT_PLANET_SMARTCOM2000 0xffffffff
+#define PCMCIA_STR_PLANET_SMARTCOM2000 "Planet SmartCOM 2000"
+/*
+ * vendor ID of both FNW-3600-T and FNW-3700-T is LINKSYS (0x0149) and
+ * product ID is 0xc1ab, but it conflicts with LINKSYS Combo EthernetCard.
+ */
+#define PCMCIA_CIS_PLANEX_FNW3600T { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PLANEX_FNW3600T -1
+#define PCMCIA_STR_PLANEX_FNW3600T "Planex FNW-3600-T"
+#define PCMCIA_CIS_PLANEX_FNW3700T { NULL, NULL, NULL, NULL }
+#define PCMCIA_PRODUCT_PLANEX_FNW3700T -1
+#define PCMCIA_STR_PLANEX_FNW3700T "Planex FNW-3700-T"
+#define PCMCIA_CIS_RPTI_EP400 { "RPTI LTD.", "EP400", "CISV100", NULL }
+#define PCMCIA_PRODUCT_RPTI_EP400 0xffffffff
+#define PCMCIA_STR_RPTI_EP400 "RPTI EP400"
+#define PCMCIA_CIS_RPTI_EP401 { "RPTI", "EP401 Ethernet NE2000 Compatible", NULL, NULL }
+#define PCMCIA_PRODUCT_RPTI_EP401 0xffffffff
+#define PCMCIA_STR_RPTI_EP401 "RPTI EP401"
+#define PCMCIA_CIS_PREMAX_PE200 { "PMX ", "PE-200", NULL, NULL }
+#define PCMCIA_PRODUCT_PREMAX_PE200 0xffffffff
+#define PCMCIA_STR_PREMAX_PE200 "PreMax PE-200"
+#define PCMCIA_CIS_RATOC_REX_R280 { "RATOC System Inc.", "10BASE_T CARD R280", NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX_R280 0xffffffff
+#define PCMCIA_STR_RATOC_REX_R280 "RATOC REX-R280"
+#define PCMCIA_CIS_RATOC_REX5536 { "1195 RATOC System Inc.", "REX5536 SCSI2 CARD", NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX5536 0xffffffff
+#define PCMCIA_STR_RATOC_REX5536 "RATOC REX-5536"
+#define PCMCIA_CIS_RATOC_REX5536AM { "PCMCIA SCSI MBH10404", "01", NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX5536AM 0xffffffff
+#define PCMCIA_STR_RATOC_REX5536AM "RATOC REX-5536AM"
+#define PCMCIA_CIS_RATOC_REX5536M { "PCMCIA SCSI2 CARD", "01", NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX5536M 0xffffffff
+#define PCMCIA_STR_RATOC_REX5536M "RATOC REX-5536M"
+#define PCMCIA_CIS_RATOC_REX5572 { "RATOC System Inc.", "SOUND/SCSI2 CARD", NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX5572 0xffffffff
+#define PCMCIA_STR_RATOC_REX5572 "RATOC REX-5572"
+#define PCMCIA_CIS_RATOC_REX9530 { "RATOC System Inc.", "SCSI2 CARD 37", NULL, NULL }
+#define PCMCIA_PRODUCT_RATOC_REX9530 0xffffffff
+#define PCMCIA_STR_RATOC_REX9530 "RATOC REX-9530"
+#define PCMCIA_CIS_SIMPLETECH_SPECTRUM24_ALT { "Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", NULL, NULL }
+#define PCMCIA_PRODUCT_SIMPLETECH_SPECTRUM24_ALT 0xffffffff
+#define PCMCIA_STR_SIMPLETECH_SPECTRUM24_ALT "LA4111 Spectrum24 Wireless LAN PC Card"
+#define PCMCIA_CIS_SMC_2632W { "SMC", "SMC2632W", "Version 01.02", NULL }
+#define PCMCIA_PRODUCT_SMC_2632W 0xffffffff
+#define PCMCIA_STR_SMC_2632W "SMC 2632 EZ Connect Wireless PC Card"
+#define PCMCIA_CIS_SMC_8041 { "SMC", "8041TX-10/100-PC-Card-V2", NULL, NULL }
+#define PCMCIA_PRODUCT_SMC_8041 0xffffffff
+#define PCMCIA_STR_SMC_8041 "SMC 8041TX 10/100 PC Card"
+#define PCMCIA_CIS_SVEC_COMBOCARD { "Ethernet", "Adapter", NULL, NULL }
+#define PCMCIA_PRODUCT_SVEC_COMBOCARD 0xffffffff
+#define PCMCIA_STR_SVEC_COMBOCARD "SVEC/Hawking Tech. Combo Card"
+#define PCMCIA_CIS_SVEC_LANCARD { "SVEC", "FD605 PCMCIA EtherNet Card", "V1-1", NULL }
+#define PCMCIA_PRODUCT_SVEC_LANCARD 0xffffffff
+#define PCMCIA_STR_SVEC_LANCARD "SVEC PCMCIA Lan Card"
+#define PCMCIA_CIS_SYNERGY21_S21810 { "PCMCIA", "Ethernet", "A", "004743118001" }
+#define PCMCIA_PRODUCT_SYNERGY21_S21810 0xffffffff
+#define PCMCIA_STR_SYNERGY21_S21810 "Synergy 21 S21810+ NE2000 Compatible Card"
+#define PCMCIA_CIS_TEAC_IDECARDII { NULL, "NinjaATA-", NULL, NULL }
+#define PCMCIA_PRODUCT_TEAC_IDECARDII 0xffffffff
+#define PCMCIA_STR_TEAC_IDECARDII "TEAC IDE Card/II"
+#define PCMCIA_CIS_TOSHIBA_CBIDE2 { "LOOKMEET", "CBIDE2 ", NULL, NULL }
+#define PCMCIA_PRODUCT_TOSHIBA_CBIDE2 0xffffffff
+#define PCMCIA_STR_TOSHIBA_CBIDE2 "TOSHIBA PA2673U CBIDE2/16-bit mode (IO-DATA OEM)"
+#define PCMCIA_CIS_WORKBIT2_NINJA_SCSI3 { "WBT", "NinjaSCSI-3", NULL, NULL }
+#define PCMCIA_PRODUCT_WORKBIT2_NINJA_SCSI3 0xffffffff
+#define PCMCIA_STR_WORKBIT2_NINJA_SCSI3 "WORKBIT Ninja SCSI series"
+#define PCMCIA_CIS_XIRCOM_CFE_10 { "Xircom", "CompactCard Ethernet", "CFE-10", "1.00" }
+#define PCMCIA_PRODUCT_XIRCOM_CFE_10 0xffffffff
+#define PCMCIA_STR_XIRCOM_CFE_10 "Xircom CompactCard CFE-10"
+#define PCMCIA_CIS_YEDATA_EXTERNAL_FDD { "Y-E DATA", "External FDD", NULL, NULL }
+#define PCMCIA_PRODUCT_YEDATA_EXTERNAL_FDD 0xffffffff
+#define PCMCIA_STR_YEDATA_EXTERNAL_FDD "Y-E DATA External FDD"
+#define PCMCIA_CIS_YIS_YWL11B { "YIS Corp.", "YWL-11b", NULL, NULL }
+#define PCMCIA_PRODUCT_YIS_YWL11B 0xffffffff
+#define PCMCIA_STR_YIS_YWL11B "YIS Corp. YWL-11b"
+#define PCMCIA_CIS_ZOOM_AIR_4000 { "Zoom", "Air-4000", NULL, NULL }
+#define PCMCIA_PRODUCT_ZOOM_AIR_4000 0xffffffff
+#define PCMCIA_STR_ZOOM_AIR_4000 "Zoom Air-4000"
diff --git a/sys/dev/pccard/pccardreg.h b/sys/dev/pccard/pccardreg.h
new file mode 100644
index 0000000..f6f67f8
--- /dev/null
+++ b/sys/dev/pccard/pccardreg.h
@@ -0,0 +1,74 @@
+/* $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.
+ */
+
+/*
+ * 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..1868a37
--- /dev/null
+++ b/sys/dev/pccard/pccardvar.h
@@ -0,0 +1,380 @@
+/* $NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 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.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <machine/bus.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 */
+ int width;
+};
+
+#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 */
+ bus_size_t realsize; /* how much we really allocated */
+ bus_addr_t cardaddr; /* Absolute address on card */
+ int kind;
+};
+
+/* 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;
+ uint32_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 */
+ uint16_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;
+ struct resource *iores[4];
+ int iorid[4];
+ struct resource *irqres;
+ int irqrid;
+ struct resource *memres[2];
+ int memrid[2];
+ STAILQ_ENTRY(pccard_config_entry) cfe_list;
+};
+
+struct pccard_funce_disk {
+ int pfd_interface;
+};
+
+struct pccard_funce_lan {
+ int pfl_nidlen;
+ uint8_t pfl_nid[8];
+};
+
+union pccard_funce {
+ struct pccard_funce_disk pfv_disk;
+ struct pccard_funce_lan pfv_lan;
+};
+
+struct pccard_function {
+ /* read off the card */
+ int number;
+ int function;
+ int last_config_index;
+ uint32_t ccr_base; /* Offset with card's memory */
+ uint32_t ccr_mask;
+ struct resource *ccr_res;
+ int ccr_rid;
+ STAILQ_HEAD(, pccard_config_entry) cfe_head;
+ STAILQ_ENTRY(pccard_function) pf_list;
+ /* run-time state */
+ struct pccard_softc *sc;
+ struct pccard_config_entry *cfe;
+ struct pccard_mem_handle pf_pcmh;
+ device_t dev;
+#define pf_ccrt pf_pcmh.memt
+#define pf_ccrh pf_pcmh.memh
+#define pf_ccr_realsize pf_pcmh.realsize
+ uint32_t pf_ccr_offset; /* Offset from ccr_base of CIS */
+ int pf_ccr_window;
+ bus_addr_t pf_mfc_iobase;
+ bus_addr_t pf_mfc_iomax;
+ int pf_flags;
+ driver_intr_t *intr_handler;
+ void *intr_handler_arg;
+ void *intr_handler_cookie;
+
+ union pccard_funce pf_funce; /* CISTPL_FUNCE */
+#define pf_funce_disk_interface pf_funce.pfv_disk.pfd_interface
+#define pf_funce_lan_nid pf_funce.pfv_lan.pfl_nid
+#define pf_funce_lan_nidlen pf_funce.pfv_lan.pfl_nidlen
+};
+
+/* 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 PCMCIA_VENDOR_INVALID -1
+ int32_t product;
+#define PCMCIA_PRODUCT_INVALID -1
+ int16_t prodext;
+ uint16_t error;
+#define PCMCIA_CIS_INVALID { NULL, NULL, NULL, NULL }
+ STAILQ_HEAD(, pccard_function) pf_head;
+};
+
+#define PCCARD_WIDTH_AUTO 0
+#define PCCARD_WIDTH_IO8 1
+#define PCCARD_WIDTH_IO16 2
+
+/* More later? */
+struct pccard_ivar {
+ struct resource_list resources;
+ struct pccard_function *fcn;
+};
+
+struct pccard_softc {
+ device_t dev;
+ /* this stuff is for the socket */
+
+ /* this stuff is for the card */
+ struct pccard_card card;
+ int sc_enabled_count; /* num functions enabled */
+};
+
+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_tuple {
+ unsigned int code;
+ unsigned int length;
+ u_long mult;
+ bus_addr_t ptr;
+ bus_space_tag_t memt;
+ bus_space_handle_t memh;
+};
+
+struct pccard_product {
+ const char *pp_name; /* NULL if end of table */
+#define PCCARD_VENDOR_ANY (0xffffffff)
+ uint32_t pp_vendor;
+#define PCCARD_PRODUCT_ANY (0xffffffff)
+ uint32_t pp_product;
+ int pp_expfunc;
+ const char *pp_cis[4];
+};
+
+typedef int (*pccard_product_match_fn) (device_t dev,
+ const struct pccard_product *ent, int vpfmatch);
+
+#include "card_if.h"
+
+/*
+ * make this inline so that we don't have to worry about dangling references
+ * to it in the modules or the code.
+ */
+static __inline const struct pccard_product *
+pccard_product_lookup(device_t dev, const struct pccard_product *tab,
+ size_t ent_size, pccard_product_match_fn matchfn)
+{
+ return CARD_DO_PRODUCT_LOOKUP(device_get_parent(dev), dev,
+ tab, ent_size, matchfn);
+}
+
+void pccard_read_cis(struct pccard_softc *);
+void pccard_check_cis_quirks(device_t);
+void pccard_print_cis(device_t);
+int pccard_scan_cis(device_t,
+ 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
+
+#define pccard_mfc(sc) \
+ (STAILQ_FIRST(&(sc)->card.pf_head) && \
+ STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list))
+
+#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(struct pccard_function *, int, bus_addr_t,
+ bus_size_t, struct pccard_io_handle *, int *);
+void pccard_io_unmap(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)))
+
+/* compat layer */
+static __inline int
+pccard_compat_probe(device_t dev)
+{
+ return (CARD_COMPAT_DO_PROBE(device_get_parent(dev), dev));
+}
+
+static __inline int
+pccard_compat_attach(device_t dev)
+{
+ return (CARD_COMPAT_DO_ATTACH(device_get_parent(dev), dev));
+}
+
+/* ivar interface */
+enum {
+ PCCARD_IVAR_ETHADDR, /* read ethernet address from CIS tupple */
+ PCCARD_IVAR_VENDOR,
+ PCCARD_IVAR_PRODUCT,
+ PCCARD_IVAR_PRODEXT,
+ PCCARD_IVAR_FUNCTION_NUMBER,
+ PCCARD_IVAR_VENDOR_STR, /* CIS string for "Manufacturer" */
+ PCCARD_IVAR_PRODUCT_STR,/* CIS strnig for "Product" */
+ PCCARD_IVAR_CIS3_STR,
+ PCCARD_IVAR_CIS4_STR,
+ PCCARD_IVAR_FUNCTION
+};
+
+#define PCCARD_ACCESSOR(A, B, T) \
+__inline static int \
+pccard_get_ ## A(device_t dev, T *t) \
+{ \
+ return BUS_READ_IVAR(device_get_parent(dev), dev, \
+ PCCARD_IVAR_ ## B, (uintptr_t *) t); \
+}
+
+PCCARD_ACCESSOR(ether, ETHADDR, uint8_t)
+PCCARD_ACCESSOR(vendor, VENDOR, uint32_t)
+PCCARD_ACCESSOR(product, PRODUCT, uint32_t)
+PCCARD_ACCESSOR(prodext, PRODEXT, uint16_t)
+PCCARD_ACCESSOR(function_number,FUNCTION_NUMBER, uint32_t)
+PCCARD_ACCESSOR(function, FUNCTION, uint32_t)
+PCCARD_ACCESSOR(vendor_str, VENDOR_STR, const char *)
+PCCARD_ACCESSOR(product_str, PRODUCT_STR, const char *)
+PCCARD_ACCESSOR(cis3_str, CIS3_STR, const char *)
+PCCARD_ACCESSOR(cis4_str, CIS4_STR, const char *)
+
+/* shared memory flags */
+enum {
+ PCCARD_A_MEM_COM, /* common */
+ PCCARD_A_MEM_ATTR, /* attribute */
+ PCCARD_A_MEM_8BIT, /* 8 bit */
+ PCCARD_A_MEM_16BIT /* 16 bit */
+};
+
+#define PCCARD_SOFTC(d) (struct pccard_softc *) device_get_softc(d)
+#define PCCARD_IVAR(d) (struct pccard_ivar *) device_get_ivars(d)
+
+#define PCCARD_S(a, b) PCMCIA_STR_ ## a ## _ ## b
+#define PCCARD_P(a, b) PCMCIA_PRODUCT_ ## a ## _ ## b
+#define PCCARD_C(a, b) PCMCIA_CIS_ ## a ## _ ## b
+#define PCMCIA_CARD_D(v, p, f) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \
+ PCCARD_P(v, p), f, PCCARD_C(v, p) }
+#define PCMCIA_CARD2_D(v1, p1, p2, f) \
+ { PCMCIA_STR_ ## p2, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \
+ f, PCMCIA_CIS_ ## p2}
+#define PCMCIA_CARD(v, p, f) { NULL, PCMCIA_VENDOR_ ## v, \
+ PCCARD_P(v, p), f, PCCARD_C(v, p) }
+#define PCMCIA_CARD2(v1, p1, p2, f) \
+ { NULL, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \
+ f, PCMCIA_CIS_ ## p2}
diff --git a/sys/dev/pccard/power_if.m b/sys/dev/pccard/power_if.m
new file mode 100644
index 0000000..d661d5c
--- /dev/null
+++ b/sys/dev/pccard/power_if.m
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 1999 M. Warner Losh.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+#
+# $FreeBSD$
+#
+
+#include <sys/bus.h>
+
+INTERFACE power;
+
+#
+# Interface for powering cards on/off. It is hoped that this will be
+# generic enough to be used for other systems in addition to the pccard
+# <-> pcic interface that it was originally written for.
+#
+METHOD int enable_socket {
+ device_t dev;
+ device_t child;
+};
+
+METHOD int disable_socket {
+ device_t dev;
+ device_t child;
+};
OpenPOWER on IntegriCloud