summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1999-10-26 13:06:15 +0000
committerJason Downs <downsj@cvs.openbsd.org>1999-10-26 13:06:15 +0000
commit77eca97247ae8ee00f39dc9a83c7bcbb00c73540 (patch)
treef36a86fe673cce5881d841b9fcb45bc90a70efa2 /sys/dev
parent106d52347bb8621a040770aa053eff56a9698938 (diff)
PCI "universal" communication device driver, by cgd@netbsd.org.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/files.pci9
-rw-r--r--sys/dev/pci/puc.c348
-rw-r--r--sys/dev/pci/pucdata.c519
-rw-r--r--sys/dev/pci/pucvar.h79
4 files changed, 954 insertions, 1 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index e44c9771ac2..555763fa4a5 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.50 1999/10/05 19:24:41 csapuntz Exp $
+# $OpenBSD: files.pci,v 1.51 1999/10/26 13:06:14 downsj Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -208,3 +208,10 @@ attach skc at pci
device sk: ether, ifnet, ifmedia
attach sk at skc
file dev/pci/if_sk.c skc | sk
+
+# PCI "universal" communication device driver, for PCI com, lpt, etc. ports
+# (see documentation in the driver for what, exactly, should be supported)
+device puc { port = -1 }
+attach puc at pci
+file dev/pci/puc.c puc
+file dev/pci/pucdata.c puc
diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c
new file mode 100644
index 00000000000..670b20e8220
--- /dev/null
+++ b/sys/dev/pci/puc.c
@@ -0,0 +1,348 @@
+/* $OpenBSD: puc.c,v 1.1 1999/10/26 13:06:14 downsj Exp $ */
+/* $NetBSD: puc.c,v 1.3 1999/02/06 06:29:54 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996, 1998, 1999
+ * 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
+ * for the NetBSD Project.
+ * 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.
+ */
+
+/*
+ * PCI "universal" communication card device driver, glues com, lpt,
+ * and similar ports to PCI via bridge chip often much larger than
+ * the devices being glued.
+ *
+ * Author: Christopher G. Demetriou, May 14, 1998 (derived from NetBSD
+ * sys/dev/pci/pciide.c, revision 1.6).
+ *
+ * These devices could be (and some times are) described as
+ * communications/{serial,parallel}, etc. devices with known
+ * programming interfaces, but those programming interfaces (in
+ * particular the BAR assignments for devices, etc.) in fact are not
+ * particularly well defined.
+ *
+ * After I/we have seen more of these devices, it may be possible
+ * to generalize some of these bits. In particular, devices which
+ * describe themselves as communications/serial/16[45]50, and
+ * communications/parallel/??? might be attached via direct
+ * 'com' and 'lpt' attachments to pci.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pucvar.h>
+
+struct puc_softc {
+ struct device sc_dev;
+
+ /* static configuration data */
+ const struct puc_device_description *sc_desc;
+
+ /* card-global dynamic data */
+ void *sc_ih;
+ struct {
+ int mapped;
+ bus_addr_t a;
+ bus_size_t s;
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ } sc_bar_mappings[6]; /* XXX constant */
+
+ /* per-port dynamic data */
+ struct {
+ struct device *dev;
+
+ /* filled in by port attachments */
+ int (*ihand) __P((void *));
+ void *ihandarg;
+ } sc_ports[PUC_MAX_PORTS];
+};
+
+int puc_match __P((struct device *, void *, void *));
+void puc_attach __P((struct device *, struct device *, void *));
+int puc_print __P((void *, const char *));
+int puc_submatch __P((struct device *, void *, void *));
+
+struct cfattach puc_ca = {
+ sizeof(struct puc_softc), puc_match, puc_attach
+};
+
+struct cfdriver puc_cd = {
+ NULL, "puc", DV_DULL
+};
+
+static const struct puc_device_description *
+ puc_find_description __P((pcireg_t, pcireg_t, pcireg_t, pcireg_t));
+static const char *
+ puc_port_type_name __P((int));
+
+int
+puc_match(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct pci_attach_args *pa = aux;
+ const struct puc_device_description *desc;
+ pcireg_t bhlc, subsys;
+
+ bhlc = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
+ if (PCI_HDRTYPE_TYPE(bhlc) != 0)
+ return (0);
+
+ subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
+
+ desc = puc_find_description(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id), PCI_VENDOR(subsys), PCI_PRODUCT(subsys));
+ if (desc != NULL)
+ return (10);
+
+ /*
+ * Match class/subclass, so we can tell people to compile kernel
+ * with options that cause this driver to spew.
+ */
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_COMMUNICATIONS &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI)
+ return (1);
+
+ return (0);
+}
+
+void
+puc_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct puc_softc *sc = (struct puc_softc *)self;
+ struct pci_attach_args *pa = aux;
+ struct puc_attach_args paa;
+ pci_intr_handle_t intrhandle;
+ pcireg_t subsys;
+ int i, barindex;
+
+ subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
+ sc->sc_desc = puc_find_description(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id), PCI_VENDOR(subsys), PCI_PRODUCT(subsys));
+ if (sc->sc_desc == NULL) {
+ /*
+ * This was a class/subclass match, so tell people to compile
+ * kernel with options that cause this driver to spew.
+ */
+#ifdef PUC_PRINT_REGS
+ printf(":\n");
+ pci_conf_print(pa->pa_pc, pa->pa_tag, NULL);
+#else
+ printf(": unknown PCI communications device\n");
+ printf("%s: compile kernel with PUC_PRINT_REGS and larger\n",
+ sc->sc_dev.dv_xname);
+ printf("%s: mesage buffer (via 'options MSGBUFSIZE=...'),\n",
+ sc->sc_dev.dv_xname);
+ printf("%s: and report the result with send-pr\n",
+ sc->sc_dev.dv_xname);
+#endif
+ return;
+ }
+
+ printf(": %s (", sc->sc_desc->name);
+ for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++)
+ printf("%s%s", i ? ", " : "",
+ puc_port_type_name(sc->sc_desc->ports[i].type));
+ printf(")\n");
+
+ /*
+ * XXX This driver assumes that 'com' ports attached to it
+ * XXX can not be console. That isn't unreasonable, because PCI
+ * XXX devices are supposed to be dynamically mapped, and com
+ * XXX console ports want fixed addresses. When/if baseboard
+ * XXX 'com' ports are identified as PCI/communications/serial
+ * XXX devices and are known to be mapped at the standard
+ * XXX addresses, if they can be the system console then we have
+ * XXX to cope with doing the mapping right. Then this will get
+ * XXX really ugly. Of course, by then we might know the real
+ * XXX definition of PCI/communications/serial, and attach 'com'
+ * XXX directly on PCI.
+ */
+ for (i = 0; i < 6; i++) {
+ pcireg_t bar, type;
+
+ sc->sc_bar_mappings[i].mapped = 0;
+
+ bar = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ PCI_MAPREG_START + 4 * i); /* XXX const */
+ if (bar == 0) /* BAR not implemented(?) */
+ continue;
+
+ type = (PCI_MAPREG_TYPE(bar) == PCI_MAPREG_TYPE_IO ?
+ PCI_MAPREG_TYPE_IO : PCI_MAPREG_MEM_TYPE(bar));
+
+ sc->sc_bar_mappings[i].mapped = (pci_mapreg_map(pa,
+ PCI_MAPREG_START + 4 * i, type, 0,
+ &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
+ &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s)
+ == 0);
+ if (sc->sc_bar_mappings[i].mapped)
+ continue;
+
+ printf("%s: couldn't map BAR at offset 0x%lx\n",
+ sc->sc_dev.dv_xname, (long)(PCI_MAPREG_START + 4 * i));
+ }
+
+ /* Map interrupt. */
+ if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
+ pa->pa_intrline, &intrhandle)) {
+ printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
+ return;
+ }
+ /*
+ * XXX the sub-devices establish the interrupts, for the
+ * XXX following reasons:
+ * XXX
+ * XXX * we can't really know what IPLs they'd want
+ * XXX
+ * XXX * the MD dispatching code can ("should") dispatch
+ * XXX chained interrupts better than we can.
+ * XXX
+ * XXX It would be nice if we could indicate to the MD interrupt
+ * XXX handling code that the interrupt line used by the device
+ * XXX was a PCI (level triggered) interrupt.
+ * XXX
+ * XXX It's not pretty, but hey, what is?
+ */
+
+ /* Configure each port. */
+ for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) {
+ bus_space_handle_t subregion_handle;
+
+ /* make sure the base address register is mapped */
+ barindex = PUC_PORT_BAR_INDEX(sc->sc_desc->ports[i].bar);
+ if (!sc->sc_bar_mappings[barindex].mapped) {
+ printf("%s: %s port uses unmapped BAR (0x%x)\n",
+ sc->sc_dev.dv_xname,
+ puc_port_type_name(sc->sc_desc->ports[i].type),
+ sc->sc_desc->ports[i].bar);
+ continue;
+ }
+
+ /* set up to configure the child device */
+ paa.port = i;
+ paa.type = sc->sc_desc->ports[i].type;
+ paa.pc = pa->pa_pc;
+ paa.intrhandle = intrhandle;
+ paa.a = sc->sc_bar_mappings[barindex].a;
+ paa.t = sc->sc_bar_mappings[barindex].t;
+
+ if (bus_space_subregion(sc->sc_bar_mappings[barindex].t,
+ sc->sc_bar_mappings[barindex].h,
+ sc->sc_desc->ports[i].offset,
+ sc->sc_bar_mappings[barindex].s -
+ sc->sc_desc->ports[i].offset,
+ &subregion_handle)) {
+ printf("%s: couldn't get subregion for port %d\n",
+ sc->sc_dev.dv_xname, i);
+ continue;
+ }
+ paa.h = subregion_handle;
+
+#if 0
+ printf("%s: port %d: %s @ (index %d) 0x%x (0x%lx, 0x%lx)\n",
+ sc->sc_dev.dv_xname, paa.port,
+ puc_port_type_name(paa.type), barindex, (int)paa.a,
+ (long)paa.t, (long)paa.h);
+#endif
+
+ /* and configure it */
+ sc->sc_ports[i].dev = config_found_sm(self, &paa, puc_print,
+ puc_submatch);
+ }
+}
+
+int
+puc_print(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ struct puc_attach_args *paa = aux;
+
+ if (pnp)
+ printf("%s at %s", puc_port_type_name(paa->type), pnp);
+ printf(" port %d", paa->port);
+ return (UNCONF);
+}
+
+int
+puc_submatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = (struct cfdata *)vcf;
+ struct puc_attach_args *aa = aux;
+
+ if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != aa->port)
+ return 0;
+ return ((*cf->cf_attach->ca_match)(parent, cf, aux));
+}
+
+static const struct puc_device_description *
+puc_find_description(vend, prod, svend, sprod)
+ pcireg_t vend, prod, svend, sprod;
+{
+ int i;
+
+#define checkreg(val, index) \
+ (((val) & puc_devices[i].rmask[(index)]) == puc_devices[i].rval[(index)])
+
+ for (i = 0; puc_devices[i].name != NULL; i++) {
+ if (checkreg(vend, PUC_REG_VEND) &&
+ checkreg(prod, PUC_REG_PROD) &&
+ checkreg(svend, PUC_REG_SVEND) &&
+ checkreg(sprod, PUC_REG_SPROD))
+ return (&puc_devices[i]);
+ }
+
+#undef checkreg
+
+ return (NULL);
+}
+
+static const char *
+puc_port_type_name(type)
+ int type;
+{
+
+ switch (type) {
+ case PUC_PORT_TYPE_COM:
+ return "com";
+ case PUC_PORT_TYPE_LPT:
+ return "lpt";
+ default:
+ panic("puc_port_type_name %d", type);
+ }
+}
diff --git a/sys/dev/pci/pucdata.c b/sys/dev/pci/pucdata.c
new file mode 100644
index 00000000000..4f7fd43137b
--- /dev/null
+++ b/sys/dev/pci/pucdata.c
@@ -0,0 +1,519 @@
+/* $OpenBSD: pucdata.c,v 1.1 1999/10/26 13:06:14 downsj Exp $ */
+/* $NetBSD: pucdata.c,v 1.6 1999/07/03 05:55:23 cgd Exp $ */
+
+/*
+ * Copyright (c) 1998, 1999 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
+ * for the NetBSD Project.
+ * 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.
+ */
+
+/*
+ * PCI "universal" communications card driver configuration data (used to
+ * match/attach the cards).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pucvar.h>
+
+const struct puc_device_description puc_devices[] = {
+ /*
+ * XXX no entry because I have no data:
+ * XXX Dolphin Peripherals 4006 (single parallel)
+ */
+
+ /*
+ * Dolphin Peripherals 4014 (dual parallel port) card. PLX 9050, with
+ * a seemingly-lame EEPROM setup that puts the Dolphin IDs
+ * into the subsystem fields, and claims that it's a
+ * network/misc (0x02/0x80) device.
+ */
+ { "Dolphin Peripherals 4014",
+ { 0x10b5, 0x9050, 0xd84d, 0x6810 },
+ { 0xffff, 0xffff, 0xffff, 0xffff },
+ {
+ { PUC_PORT_TYPE_LPT, 0x20, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x24, 0x00 },
+ },
+ },
+
+ /*
+ * XXX no entry because I have no data:
+ * XXX Dolphin Peripherals 4025 (single serial)
+ */
+
+ /*
+ * Dolphin Peripherals 4035 (dual serial port) card. PLX 9050, with
+ * a seemingly-lame EEPROM setup that puts the Dolphin IDs
+ * into the subsystem fields, and claims that it's a
+ * network/misc (0x02/0x80) device.
+ */
+ { "Dolphin Peripherals 4035",
+ { 0x10b5, 0x9050, 0xd84d, 0x6808 },
+ { 0xffff, 0xffff, 0xffff, 0xffff },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+ /*
+ * XXX no entry because I have no data:
+ * XXX Dolphin Peripherals 4078 (dual serial and single parallel)
+ */
+
+
+ /*
+ * SIIG Boards.
+ *
+ * SIIG provides documentation for their boards at:
+ * <URL:http://www.siig.com/driver.htm>
+ *
+ * Please excuse the weird ordering, it's the order they
+ * use in their documentation.
+ */
+
+ /*
+ * SIIG "10x" family boards.
+ */
+
+ /* SIIG Cyber Serial PCI 16C550 (10x family): 1S */
+ { "SIIG Cyber Serial PCI 16C550 (10x family)",
+ { 0x131f, 0x1000, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial PCI 16C650 (10x family): 1S */
+ { "SIIG Cyber Serial PCI 16C650 (10x family)",
+ { 0x131f, 0x1001, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial PCI 16C850 (10x family): 1S */
+ { "SIIG Cyber Serial PCI 16C850 (10x family)",
+ { 0x131f, 0x1002, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber I/O PCI 16C550 (10x family): 1S, 1P */
+ { "SIIG Cyber I/O PCI 16C550 (10x family)",
+ { 0x131f, 0x1010, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber I/O PCI 16C650 (10x family): 1S, 1P */
+ { "SIIG Cyber I/O PCI 16C650 (10x family)",
+ { 0x131f, 0x1011, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber I/O PCI 16C850 (10x family): 1S, 1P */
+ { "SIIG Cyber I/O PCI 16C850 (10x family)",
+ { 0x131f, 0x1012, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Parallel PCI (10x family): 1P */
+ { "SIIG Cyber Parallel PCI (10x family)",
+ { 0x131f, 0x1020, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_LPT, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Parallel Dual PCI (10x family): 2P */
+ { "SIIG Cyber Parallel Dual PCI (10x family)",
+ { 0x131f, 0x1021, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_LPT, 0x18, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x20, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial Dual PCI 16C550 (10x family): 2S */
+ { "SIIG Cyber Serial Dual PCI 16C550 (10x family)",
+ { 0x131f, 0x1030, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial Dual PCI 16C650 (10x family): 2S */
+ { "SIIG Cyber Serial Dual PCI 16C650 (10x family)",
+ { 0x131f, 0x1031, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial Dual PCI 16C850 (10x family): 2S */
+ { "SIIG Cyber Serial Dual PCI 16C850 (10x family)",
+ { 0x131f, 0x1032, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2S1P PCI 16C550 (10x family): 2S, 1P */
+ { "SIIG Cyber 2S1P PCI 16C550 (10x family)",
+ { 0x131f, 0x1034, 0, 0 }, /* XXX really? */
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x20, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2S1P PCI 16C650 (10x family): 2S, 1P */
+ { "SIIG Cyber 2S1P PCI 16C650 (10x family)",
+ { 0x131f, 0x1035, 0, 0 }, /* XXX really? */
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x20, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2S1P PCI 16C850 (10x family): 2S, 1P */
+ { "SIIG Cyber 2S1P PCI 16C850 (10x family)",
+ { 0x131f, 0x1036, 0, 0 }, /* XXX really? */
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x20, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 4S PCI 16C550 (10x family): 4S */
+ { "SIIG Cyber 4S PCI 16C550 (10x family)",
+ { 0x131f, 0x1050, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x20, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x24, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 4S PCI 16C650 (10x family): 4S */
+ { "SIIG Cyber 4S PCI 16C650 (10x family)",
+ { 0x131f, 0x1051, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x20, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x24, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 4S PCI 16C850 (10x family): 4S */
+ { "SIIG Cyber 4S PCI 16C850 (10x family)",
+ { 0x131f, 0x1052, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x20, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x24, 0x00 },
+ },
+ },
+
+ /*
+ * SIIG "20x" family boards.
+ */
+
+ /* SIIG Cyber Parallel PCI (20x family): 1P */
+ { "SIIG Cyber Parallel PCI (20x family)",
+ { 0x131f, 0x2020, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_LPT, 0x10, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Parallel Dual PCI (20x family): 2P */
+ { "SIIG Cyber Parallel Dual PCI (20x family)",
+ { 0x131f, 0x2021, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_LPT, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2P1S PCI 16C550 (20x family): 1S, 2P */
+ { "SIIG Cyber 2P1S PCI 16C550 (20x family)",
+ { 0x131f, 0x2040, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x14, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2P1S PCI 16C650 (20x family): 1S, 2P */
+ { "SIIG Cyber 2P1S PCI 16C650 (20x family)",
+ { 0x131f, 0x2041, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x14, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2P1S PCI 16C850 (20x family): 1S, 2P */
+ { "SIIG Cyber 2P1S PCI 16C850 (20x family)",
+ { 0x131f, 0x2042, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x14, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial PCI 16C550 (20x family): 1S */
+ { "SIIG Cyber Serial PCI 16C550 (20x family)",
+ { 0x131f, 0x2000, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial PCI 16C650 (20x family): 1S */
+ { "SIIG Cyber Serial PCI 16C650 (20x family)",
+ { 0x131f, 0x2001, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial PCI 16C850 (20x family): 1S */
+ { "SIIG Cyber Serial PCI 16C850 (20x family)",
+ { 0x131f, 0x2002, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber I/O PCI 16C550 (20x family): 1S, 1P */
+ { "SIIG Cyber I/O PCI 16C550 (20x family)",
+ { 0x131f, 0x2010, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x14, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber I/O PCI 16C650 (20x family): 1S, 1P */
+ { "SIIG Cyber I/O PCI 16C650 (20x family)",
+ { 0x131f, 0x2011, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x14, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber I/O PCI 16C850 (20x family): 1S, 1P */
+ { "SIIG Cyber I/O PCI 16C850 (20x family)",
+ { 0x131f, 0x2012, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x14, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial Dual PCI 16C550 (20x family): 2S */
+ { "SIIG Cyber Serial Dual PCI 16C550 (20x family)",
+ { 0x131f, 0x2030, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial Dual PCI 16C650 (20x family): 2S */
+ { "SIIG Cyber Serial Dual PCI 16C650 (20x family)",
+ { 0x131f, 0x2031, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber Serial Dual PCI 16C850 (20x family): 2S */
+ { "SIIG Cyber Serial Dual PCI 16C850 (20x family)",
+ { 0x131f, 0x2032, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2S1P PCI 16C550 (20x family): 2S, 1P */
+ { "SIIG Cyber 2S1P PCI 16C550 (20x family)",
+ { 0x131f, 0x2060, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2S1P PCI 16C650 (20x family): 2S, 1P */
+ { "SIIG Cyber 2S1P PCI 16C650 (20x family)",
+ { 0x131f, 0x2061, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 2S1P PCI 16C850 (20x family): 2S, 1P */
+ { "SIIG Cyber 2S1P PCI 16C850 (20x family)",
+ { 0x131f, 0x2062, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ { PUC_PORT_TYPE_LPT, 0x18, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 4S PCI 16C550 (20x family): 4S */
+ { "SIIG Cyber 4S PCI 16C550 (20x family)",
+ { 0x131f, 0x2050, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 4S PCI 16C650 (20x family): 4S */
+ { "SIIG Cyber 4S PCI 16C650 (20x family)",
+ { 0x131f, 0x2051, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+ /* SIIG Cyber 4S PCI 16C850 (20x family): 4S */
+ { "SIIG Cyber 4S PCI 16C850 (20x family)",
+ { 0x131f, 0x2052, 0, 0 },
+ { 0xffff, 0xffff, 0, 0 },
+ {
+ { PUC_PORT_TYPE_COM, 0x10, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x14, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x1c, 0x00 },
+ },
+ },
+
+
+ /*
+ * VScom PCI-800, as sold on http://www.swann.com.au/isp/titan.html.
+ * Some PLX chip. Note: This board has a software selectable(?)
+ * clock multiplier which this driver doesn't support, so you'll
+ * have to use an appropriately scaled baud rate when talking to
+ * the card.
+ */
+ { "VScom PCI-800",
+ { 0x10b5, 0x1076, 0x10b5, 0x1076 },
+ { 0xffff, 0xffff, 0xffff, 0xffff },
+ {
+ { PUC_PORT_TYPE_COM, 0x18, 0x00 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x08 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x10 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x18 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x20 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x28 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x30 },
+ { PUC_PORT_TYPE_COM, 0x18, 0x38 },
+ },
+ },
+
+ { 0 }
+};
diff --git a/sys/dev/pci/pucvar.h b/sys/dev/pci/pucvar.h
new file mode 100644
index 00000000000..06fb028a9de
--- /dev/null
+++ b/sys/dev/pci/pucvar.h
@@ -0,0 +1,79 @@
+/* $OpenBSD: pucvar.h,v 1.1 1999/10/26 13:06:14 downsj Exp $ */
+/* $NetBSD: pucvar.h,v 1.2 1999/02/06 06:29:54 cgd Exp $ */
+
+/*
+ * Copyright (c) 1998, 1999 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
+ * for the NetBSD Project.
+ * 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.
+ */
+
+/*
+ * Exported (or conveniently located) PCI "universal" communications card
+ * software structures.
+ *
+ * Author: Christopher G. Demetriou, May 14, 1998.
+ */
+
+#define PUC_MAX_PORTS 8
+
+struct puc_device_description {
+ const char *name;
+ pcireg_t rval[4];
+ pcireg_t rmask[4];
+ struct {
+ int type;
+ int bar;
+ int offset;
+ } ports[PUC_MAX_PORTS];
+};
+
+#define PUC_REG_VEND 0
+#define PUC_REG_PROD 1
+#define PUC_REG_SVEND 2
+#define PUC_REG_SPROD 3
+
+#define PUC_PORT_TYPE_NONE 0
+#define PUC_PORT_TYPE_COM 1
+#define PUC_PORT_TYPE_LPT 2
+
+#define PUC_PORT_VALID(desc, port) \
+ ((port) < PUC_MAX_PORTS && (desc)->ports[(port)].type != PUC_PORT_TYPE_NONE)
+#define PUC_PORT_BAR_INDEX(bar) (((bar) - PCI_MAPREG_START) / 4)
+
+struct puc_attach_args {
+ int port;
+ int type;
+
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t intrhandle;
+
+ bus_addr_t a;
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+};
+
+extern const struct puc_device_description puc_devices[];