diff options
author | marcel <marcel@FreeBSD.org> | 2006-04-28 21:21:53 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2006-04-28 21:21:53 +0000 |
commit | 193a6144b9612bafde9b4382a221e917496b8601 (patch) | |
tree | 5e43b7350101e478e59289d09768df4e1a830e0d | |
parent | ca65c8d400f4a855b84394629b8695274cf7bfb4 (diff) | |
download | FreeBSD-src-193a6144b9612bafde9b4382a221e917496b8601.zip FreeBSD-src-193a6144b9612bafde9b4382a221e917496b8601.tar.gz |
Rewrite of puc(4). Significant changes are:
o Properly use rman(9) to manage resources. This eliminates the
need to puc-specific hacks to rman. It also allows devinfo(8)
to be used to find out the specific assignment of resources to
serial/parallel ports.
o Compress the PCI device "database" by optimizing for the common
case and to use a procedural interface to handle the exceptions.
The procedural interface also generalizes the need to setup the
hardware (program chipsets, program clock frequencies).
o Eliminate the need for PUC_FASTINTR. Serdev devices are fast by
default and non-serdev devices are handled by the bus.
o Use the serdev I/F to collect interrupt status and to handle
interrupts across ports in priority order.
o Sync the PCI device configuration to include devices found in
NetBSD and not yet merged to FreeBSD.
o Add support for Quatech 2, 4 and 8 port UARTs.
o Add support for a couple dozen Timedia serial cards as found
in Linux.
-rw-r--r-- | sys/alpha/conf/DEFAULTS | 2 | ||||
-rw-r--r-- | sys/amd64/conf/DEFAULTS | 2 | ||||
-rw-r--r-- | sys/conf/NOTES | 9 | ||||
-rw-r--r-- | sys/conf/files | 7 | ||||
-rw-r--r-- | sys/conf/kmod.mk | 4 | ||||
-rw-r--r-- | sys/conf/options | 1 | ||||
-rw-r--r-- | sys/dev/ppc/ppc_puc.c | 13 | ||||
-rw-r--r-- | sys/dev/puc/puc.c | 1069 | ||||
-rw-r--r-- | sys/dev/puc/puc_bfe.h | 94 | ||||
-rw-r--r-- | sys/dev/puc/puc_bus.h | 42 | ||||
-rw-r--r-- | sys/dev/puc/puc_cfg.c | 175 | ||||
-rw-r--r-- | sys/dev/puc/puc_cfg.h | 88 | ||||
-rw-r--r-- | sys/dev/puc/puc_ebus.c | 104 | ||||
-rw-r--r-- | sys/dev/puc/puc_pccard.c | 54 | ||||
-rw-r--r-- | sys/dev/puc/puc_pci.c | 219 | ||||
-rw-r--r-- | sys/dev/puc/puc_sbus.c | 105 | ||||
-rw-r--r-- | sys/dev/puc/pucdata.c | 2225 | ||||
-rw-r--r-- | sys/dev/puc/pucvar.h | 165 | ||||
-rw-r--r-- | sys/dev/sio/sio_puc.c | 29 | ||||
-rw-r--r-- | sys/dev/uart/uart_bus_puc.c | 38 | ||||
-rw-r--r-- | sys/i386/conf/DEFAULTS | 2 | ||||
-rw-r--r-- | sys/ia64/conf/DEFAULTS | 2 | ||||
-rw-r--r-- | sys/modules/puc/Makefile | 10 | ||||
-rw-r--r-- | sys/modules/sio/Makefile | 2 | ||||
-rw-r--r-- | sys/pc98/conf/DEFAULTS | 2 |
25 files changed, 2129 insertions, 2334 deletions
diff --git a/sys/alpha/conf/DEFAULTS b/sys/alpha/conf/DEFAULTS index d1b622b..4a37c5f 100644 --- a/sys/alpha/conf/DEFAULTS +++ b/sys/alpha/conf/DEFAULTS @@ -7,5 +7,3 @@ machine alpha # Pseudo devices. device mem # Memory and kernel memory devices - -options PUC_FASTINTR diff --git a/sys/amd64/conf/DEFAULTS b/sys/amd64/conf/DEFAULTS index 3321e97..2df00a7 100644 --- a/sys/amd64/conf/DEFAULTS +++ b/sys/amd64/conf/DEFAULTS @@ -11,5 +11,3 @@ device isa # Pseudo devices. device mem # Memory and kernel memory devices device io # I/O device - -options PUC_FASTINTR diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 1e4c64c..7ef2e6f 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1689,15 +1689,8 @@ options ALT_BREAK_TO_DEBUGGER device scc # PCI Universal Communications driver -# Supports various single and multi port PCI serial cards. Maybe later -# also the parallel ports on combination serial/parallel cards. New cards -# can be added in src/sys/dev/puc/pucdata.c. -# -# If the PUC_FASTINTR option is used the driver will try to use fast -# interrupts. The card must then be the only user of that interrupt. -# Interrupts cannot be shared when using PUC_FASTINTR. +# Supports various multi port PCI I/O cards. device puc -options PUC_FASTINTR # # Network interfaces: diff --git a/sys/conf/files b/sys/conf/files index 71e475b..922a84c 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -805,10 +805,9 @@ dev/pst/pst-iop.c optional pst dev/pst/pst-pci.c optional pst pci dev/pst/pst-raid.c optional pst dev/puc/puc.c optional puc -dev/puc/puc_ebus.c optional puc ebus +dev/puc/puc_cfg.c optional puc dev/puc/puc_pccard.c optional puc pccard dev/puc/puc_pci.c optional puc pci -dev/puc/puc_sbus.c optional puc fhc | puc sbus dev/puc/pucdata.c optional puc pci dev/ral/rt2560.c optional ral dev/ral/rt2661.c optional ral @@ -845,7 +844,7 @@ dev/si/si_isa.c optional si isa dev/si/si_pci.c optional si pci dev/sio/sio_pccard.c optional sio pccard dev/sio/sio_pci.c optional sio pci -dev/sio/sio_puc.c optional sio puc pci +dev/sio/sio_puc.c optional sio puc dev/sk/if_sk.c optional sk pci dev/smbus/smb.c optional smb dev/smbus/smbconf.c optional smbus @@ -1321,7 +1320,7 @@ kern/md4c.c optional netsmb kern/md5c.c standard kern/sched_4bsd.c optional sched_4bsd kern/sched_ule.c optional sched_ule -kern/serdev_if.m optional scc +kern/serdev_if.m optional puc | scc kern/subr_autoconf.c standard kern/subr_blist.c standard kern/subr_bus.c standard diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index b4d7a70..506a73d 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -321,8 +321,8 @@ MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ dev/pci/pcib_if.m dev/ppbus/ppbus_if.m dev/smbus/smbus_if.m \ dev/sound/pcm/ac97_if.m dev/sound/pcm/channel_if.m \ dev/sound/pcm/feeder_if.m dev/sound/pcm/mixer_if.m \ - dev/usb/usb_if.m isa/isa_if.m \ - kern/bus_if.m kern/cpufreq_if.m kern/device_if.m \ + dev/usb/usb_if.m isa/isa_if.m kern/bus_if.m kern/cpufreq_if.m \ + kern/device_if.m kern/serdev_if.m \ libkern/iconv_converter_if.m opencrypto/crypto_if.m \ pc98/pc98/canbus_if.m pci/agp_if.m diff --git a/sys/conf/options b/sys/conf/options index 0833390..33b5661 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -125,7 +125,6 @@ PPC_DEBUG opt_ppc.h PPC_PROBE_CHIPSET opt_ppc.h PPS_SYNC opt_ntp.h PREEMPTION opt_sched.h -PUC_FASTINTR opt_puc.h QUOTA SCHED_4BSD opt_sched.h SCHED_ULE opt_sched.h diff --git a/sys/dev/ppc/ppc_puc.c b/sys/dev/ppc/ppc_puc.c index b99e162..adcc058 100644 --- a/sys/dev/ppc/ppc_puc.c +++ b/sys/dev/ppc/ppc_puc.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2006 Marcel Moolenaar * Copyright (c) 1997-2000 Nicolas Souchu * Copyright (c) 2001 Alcove - Nicolas Souchu * All rights reserved. @@ -35,6 +36,8 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> +#include <dev/puc/puc_bus.h> + #include <dev/ppbus/ppbconf.h> #include <dev/ppbus/ppb_msq.h> #include <dev/ppc/ppcvar.h> @@ -48,6 +51,7 @@ static device_method_t ppc_puc_methods[] = { /* device interface */ DEVMETHOD(device_probe, ppc_puc_probe), DEVMETHOD(device_attach, ppc_attach), + DEVMETHOD(device_detach, ppc_detach), /* bus interface */ DEVMETHOD(bus_read_ivar, ppc_read_ivar), @@ -76,6 +80,15 @@ static driver_t ppc_puc_driver = { static int ppc_puc_probe(device_t dev) { + device_t parent; + uintptr_t type; + + parent = device_get_parent(dev); + if (BUS_READ_IVAR(parent, dev, PUC_IVAR_TYPE, &type)) + return (ENXIO); + if (type != PUC_TYPE_PARALLEL) + return (ENXIO); + device_set_desc(dev, "Parallel port"); return (ppc_probe(dev, 0)); } diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c index 3215003..3fd48f0 100644 --- a/sys/dev/puc/puc.c +++ b/sys/dev/puc/puc.c @@ -1,49 +1,16 @@ -/* $NetBSD: puc.c,v 1.7 2000/07/29 17:43:38 jlam Exp $ */ - /*- - * Copyright (c) 2002 JF Hay. All rights reserved. - * Copyright (c) 2000 M. Warner Losh. All rights reserved. + * Copyright (c) 2006 Marcel Moolenaar + * 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. - */ - -/*- - * 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 @@ -60,35 +27,13 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -/* - * 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 "opt_puc.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/bus.h> #include <sys/conf.h> #include <sys/malloc.h> +#include <sys/mutex.h> #include <machine/bus.h> #include <machine/resource.h> @@ -97,518 +42,670 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#define PUC_ENTRAILS 1 -#include <dev/puc/pucvar.h> +#include <dev/puc/puc_bfe.h> +#include <dev/puc/puc_bus.h> +#include <dev/puc/puc_cfg.h> -struct puc_device { - struct resource_list resources; - int port; - int regshft; - u_int serialfreq; - u_int subtype; -}; +#define PUC_ISRCCNT 5 + +struct puc_port { + struct puc_bar *p_bar; + struct resource *p_rres; + struct resource *p_ires; + device_t p_dev; + int p_nr; + int p_type; + int p_rclk; -static void puc_intr(void *arg); + int p_hasintr:1; -static int puc_find_free_unit(char *); -#ifdef PUC_DEBUG -static void puc_print_resource_list(struct resource_list *); -#endif + driver_intr_t *p_ih; + serdev_intr_t *p_ihsrc[PUC_ISRCCNT]; + void *p_iharg; + + int p_ipend; +}; devclass_t puc_devclass; +const char puc_driver_name[] = "puc"; -static int -puc_port_bar_index(struct puc_softc *sc, int bar) -{ - int i; +MALLOC_DEFINE(M_PUC, "PUC", "PUC driver"); - for (i = 0; i < PUC_MAX_BAR; i += 1) { - if (!sc->sc_bar_mappings[i].used) - break; - if (sc->sc_bar_mappings[i].bar == bar) - return (i); +struct puc_bar * +puc_get_bar(struct puc_softc *sc, int rid) +{ + struct puc_bar *bar; + struct rman *rm; + u_long end, start; + int error, i; + + /* Find the BAR entry with the given RID. */ + i = 0; + while (i < PUC_PCI_BARS && sc->sc_bar[i].b_rid != rid) + i++; + if (i < PUC_PCI_BARS) + return (&sc->sc_bar[i]); + + /* Not found. If we're looking for an unused entry, return NULL. */ + if (rid == -1) + return (NULL); + + /* Get an unused entry for us to fill. */ + bar = puc_get_bar(sc, -1); + if (bar == NULL) + return (NULL); + bar->b_rid = rid; + bar->b_type = SYS_RES_IOPORT; + bar->b_res = bus_alloc_resource_any(sc->sc_dev, bar->b_type, + &bar->b_rid, RF_ACTIVE); + if (bar->b_res == NULL) { + bar->b_rid = rid; + bar->b_type = SYS_RES_MEMORY; + bar->b_res = bus_alloc_resource_any(sc->sc_dev, bar->b_type, + &bar->b_rid, RF_ACTIVE); + if (bar->b_res == NULL) { + bar->b_rid = -1; + return (NULL); + } } - if (i == PUC_MAX_BAR) { - printf("%s: out of bars!\n", __func__); - return (-1); + + /* Update our managed space. */ + rm = (bar->b_type == SYS_RES_IOPORT) ? &sc->sc_ioport : &sc->sc_iomem; + start = rman_get_start(bar->b_res); + end = rman_get_end(bar->b_res); + error = rman_manage_region(rm, start, end); + if (error) { + bus_release_resource(sc->sc_dev, bar->b_type, bar->b_rid, + bar->b_res); + bar->b_res = NULL; + bar->b_rid = -1; + bar = NULL; } - sc->sc_bar_mappings[i].bar = bar; - sc->sc_bar_mappings[i].used = 1; - return (i); + + return (bar); } -static int -puc_probe_ilr(struct puc_softc *sc, struct resource *res) +static void +puc_intr(void *arg) { - u_char t1, t2; - int i; - - switch (sc->sc_desc.ilr_type) { - case PUC_ILR_TYPE_DIGI: - sc->ilr_st = rman_get_bustag(res); - sc->ilr_sh = rman_get_bushandle(res); - for (i = 0; i < 2 && sc->sc_desc.ilr_offset[i] != 0; i++) { - t1 = bus_space_read_1(sc->ilr_st, sc->ilr_sh, - sc->sc_desc.ilr_offset[i]); - t1 = ~t1; - bus_space_write_1(sc->ilr_st, sc->ilr_sh, - sc->sc_desc.ilr_offset[i], t1); - t2 = bus_space_read_1(sc->ilr_st, sc->ilr_sh, - sc->sc_desc.ilr_offset[i]); - if (t2 == t1) - return (0); + struct puc_port *port; + struct puc_softc *sc = arg; + u_long dev, devs; + int i, idx, ipend, isrc; + uint8_t ilr; + + devs = sc->sc_serdevs; + if (sc->sc_ilr == PUC_ILR_DIGI) { + idx = 0; + while (devs & (0xfful << idx)) { + ilr = ~bus_read_1(sc->sc_port[idx].p_rres, 7); + devs &= ~0ul ^ ((u_long)ilr << idx); + idx += 8; } - return (1); + } else if (sc->sc_ilr == PUC_ILR_QUATECH) { + /* + * Don't trust the value if it's the same as the option + * register. It may mean that the ILR is not active and + * we're reading the option register instead. This may + * lead to false positives on 8-port boards. + */ + ilr = bus_read_1(sc->sc_port[0].p_rres, 7); + if (ilr != (sc->sc_cfg_data & 0xff)) + devs &= (u_long)ilr; + } - default: - break; + ipend = 0; + idx = 0, dev = 1UL; + while (devs != 0UL) { + while ((devs & dev) == 0UL) + idx++, dev <<= 1; + devs &= ~dev; + port = &sc->sc_port[idx]; + port->p_ipend = SERDEV_IPEND(port->p_dev); + ipend |= port->p_ipend; + } + + i = 0, isrc = SER_INT_OVERRUN; + while (ipend) { + while (i < PUC_ISRCCNT && !(ipend & isrc)) + i++, isrc <<= 1; + KASSERT(i < PUC_ISRCCNT, ("%s", __func__)); + ipend &= ~isrc; + idx = 0, dev = 1UL; + devs = sc->sc_serdevs; + while (devs != 0UL) { + while ((devs & dev) == 0UL) + idx++, dev <<= 1; + devs &= ~dev; + port = &sc->sc_port[idx]; + if (!(port->p_ipend & isrc)) + continue; + if (port->p_ihsrc[i] != NULL) + (*port->p_ihsrc[i])(port->p_iharg); + } } - return (0); } int -puc_attach(device_t dev, const struct puc_device_description *desc) +puc_bfe_attach(device_t dev) { - char *typestr; - int bidx, childunit, i, irq_setup, ressz, rid, type; + char buffer[64]; + struct puc_bar *bar; + struct puc_port *port; struct puc_softc *sc; - struct puc_device *pdev; - struct resource *res; - struct resource_list_entry *rle; - bus_space_handle_t bh; - - if (desc == NULL) - return (ENXIO); - - sc = (struct puc_softc *)device_get_softc(dev); - bzero(sc, sizeof(*sc)); - sc->sc_desc = *desc; - -#ifdef PUC_DEBUG - bootverbose = 1; - - printf("puc: name: %s\n", sc->sc_desc.name); -#endif - rid = 0; - res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (!res) - return (ENXIO); - - sc->irqres = res; - sc->irqrid = rid; -#ifdef PUC_FASTINTR - irq_setup = bus_setup_intr(dev, res, - INTR_TYPE_TTY | INTR_FAST, puc_intr, sc, &sc->intr_cookie); - if (irq_setup == 0) - sc->fastintr = INTR_FAST; - else -#else - irq_setup = bus_setup_intr(dev, res, - INTR_TYPE_TTY, puc_intr, sc, &sc->intr_cookie); -#endif - if (irq_setup != 0) - return (ENXIO); - - rid = 0; - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (i > 0 && rid == sc->sc_desc.ports[i].bar) - sc->barmuxed = 1; - rid = sc->sc_desc.ports[i].bar; - bidx = puc_port_bar_index(sc, rid); - - if (bidx < 0 || sc->sc_bar_mappings[bidx].res != NULL) - continue; - - type = (sc->sc_desc.ports[i].flags & PUC_FLAGS_MEMORY) - ? SYS_RES_MEMORY : SYS_RES_IOPORT; - - res = bus_alloc_resource_any(dev, type, &rid, - RF_ACTIVE); - if (res == NULL && - sc->sc_desc.ports[i].flags & PUC_FLAGS_ALTRES) { - type = (type == SYS_RES_IOPORT) - ? SYS_RES_MEMORY : SYS_RES_IOPORT; - res = bus_alloc_resource_any(dev, type, &rid, - RF_ACTIVE); + struct rman *rm; + intptr_t res; + bus_addr_t ofs, start; + bus_size_t size; + bus_space_handle_t bsh; + bus_space_tag_t bst; + int error, idx; + + sc = device_get_softc(dev); + + for (idx = 0; idx < PUC_PCI_BARS; idx++) + sc->sc_bar[idx].b_rid = -1; + + do { + sc->sc_ioport.rm_type = RMAN_ARRAY; + error = rman_init(&sc->sc_ioport); + if (!error) { + sc->sc_iomem.rm_type = RMAN_ARRAY; + error = rman_init(&sc->sc_iomem); + if (!error) { + sc->sc_irq.rm_type = RMAN_ARRAY; + error = rman_init(&sc->sc_irq); + if (!error) + break; + rman_fini(&sc->sc_iomem); + } + rman_fini(&sc->sc_ioport); } - if (res == NULL) { - device_printf(dev, "could not get resource\n"); - continue; + return (error); + } while (0); + + snprintf(buffer, sizeof(buffer), "%s I/O port mapping", + device_get_nameunit(dev)); + sc->sc_ioport.rm_descr = strdup(buffer, M_PUC); + snprintf(buffer, sizeof(buffer), "%s I/O memory mapping", + device_get_nameunit(dev)); + sc->sc_iomem.rm_descr = strdup(buffer, M_PUC); + snprintf(buffer, sizeof(buffer), "%s port numbers", + device_get_nameunit(dev)); + sc->sc_irq.rm_descr = strdup(buffer, M_PUC); + + error = puc_config(sc, PUC_CFG_GET_NPORTS, 0, &res); + KASSERT(error == 0, ("%s %d", __func__, __LINE__)); + sc->sc_nports = (int)res; + sc->sc_port = malloc(sc->sc_nports * sizeof(struct puc_port), + M_PUC, M_WAITOK|M_ZERO); + + error = rman_manage_region(&sc->sc_irq, 1, sc->sc_nports); + if (error) + goto fail; + + error = puc_config(sc, PUC_CFG_SETUP, 0, &res); + if (error) + goto fail; + + for (idx = 0; idx < sc->sc_nports; idx++) { + port = &sc->sc_port[idx]; + port->p_nr = idx + 1; + error = puc_config(sc, PUC_CFG_GET_TYPE, idx, &res); + if (error) + goto fail; + port->p_type = res; + error = puc_config(sc, PUC_CFG_GET_RID, idx, &res); + if (error) + goto fail; + bar = puc_get_bar(sc, res); + if (bar == NULL) { + error = ENXIO; + goto fail; } - sc->sc_bar_mappings[bidx].type = type; - sc->sc_bar_mappings[bidx].res = res; - - if (sc->sc_desc.ilr_type != PUC_ILR_TYPE_NONE) { - sc->ilr_enabled = puc_probe_ilr(sc, res); - if (sc->ilr_enabled) - device_printf(dev, "ILR enabled\n"); - else - device_printf(dev, "ILR disabled\n"); + port->p_bar = bar; + start = rman_get_start(bar->b_res); + error = puc_config(sc, PUC_CFG_GET_OFS, idx, &res); + if (error) + goto fail; + ofs = res; + error = puc_config(sc, PUC_CFG_GET_LEN, idx, &res); + if (error) + goto fail; + size = res; + rm = (bar->b_type == SYS_RES_IOPORT) + ? &sc->sc_ioport: &sc->sc_iomem; + port->p_rres = rman_reserve_resource(rm, start + ofs, + start + ofs + size - 1, size, 0, NULL); + if (port->p_rres != NULL) { + bsh = rman_get_bushandle(bar->b_res); + bst = rman_get_bustag(bar->b_res); + bus_space_subregion(bst, bsh, ofs, size, &bsh); + rman_set_bushandle(port->p_rres, bsh); + rman_set_bustag(port->p_rres, bst); } -#ifdef PUC_DEBUG - printf("%s rid %d bst %lx, start %lx, end %lx\n", - (type == SYS_RES_MEMORY) ? "memory" : "port", rid, - (u_long)rman_get_bustag(res), (u_long)rman_get_start(res), - (u_long)rman_get_end(res)); -#endif - } - - if (desc->init != NULL) { - i = desc->init(sc); - if (i != 0) - return (i); - } - - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - rid = sc->sc_desc.ports[i].bar; - bidx = puc_port_bar_index(sc, rid); - if (bidx < 0 || sc->sc_bar_mappings[bidx].res == NULL) - continue; - - switch (sc->sc_desc.ports[i].type & ~PUC_PORT_SUBTYPE_MASK) { - case PUC_PORT_TYPE_COM: - typestr = "sio"; - break; - case PUC_PORT_TYPE_LPT: - typestr = "ppc"; - break; - case PUC_PORT_TYPE_UART: - typestr = "uart"; - break; - default: - continue; - } - switch (sc->sc_desc.ports[i].type & PUC_PORT_SUBTYPE_MASK) { - case PUC_PORT_UART_SAB82532: - ressz = 64; - break; - case PUC_PORT_UART_Z8530: - ressz = 2; - break; - default: - ressz = 8; - break; + port->p_ires = rman_reserve_resource(&sc->sc_irq, port->p_nr, + port->p_nr, 1, 0, NULL); + if (port->p_ires == NULL) { + error = ENXIO; + goto fail; } - pdev = malloc(sizeof(struct puc_device), M_DEVBUF, - M_NOWAIT | M_ZERO); - if (!pdev) - continue; - resource_list_init(&pdev->resources); - - /* First fake up an IRQ resource. */ - resource_list_add(&pdev->resources, SYS_RES_IRQ, 0, - rman_get_start(sc->irqres), rman_get_end(sc->irqres), - rman_get_end(sc->irqres) - rman_get_start(sc->irqres) + 1); - rle = resource_list_find(&pdev->resources, SYS_RES_IRQ, 0); - rle->res = sc->irqres; - - /* Now fake an IOPORT or MEMORY resource */ - res = sc->sc_bar_mappings[bidx].res; - type = sc->sc_bar_mappings[bidx].type; - resource_list_add(&pdev->resources, type, 0, - rman_get_start(res) + sc->sc_desc.ports[i].offset, - rman_get_start(res) + sc->sc_desc.ports[i].offset - + ressz - 1, ressz); - rle = resource_list_find(&pdev->resources, type, 0); - - if (sc->barmuxed == 0) { - rle->res = sc->sc_bar_mappings[bidx].res; - } else { - rle->res = rman_secret_puc_alloc_resource(M_WAITOK); - if (rle->res == NULL) { - free(pdev, M_DEVBUF); - return (ENOMEM); - } + error = puc_config(sc, PUC_CFG_GET_CLOCK, idx, &res); + if (error) + goto fail; + port->p_rclk = res; + + port->p_dev = device_add_child(dev, NULL, -1); + if (port->p_dev != NULL) + device_set_ivars(port->p_dev, (void *)port); + } - rman_set_start(rle->res, rman_get_start(res) + - sc->sc_desc.ports[i].offset); - rman_set_end(rle->res, rman_get_start(rle->res) + - ressz - 1); - rman_set_bustag(rle->res, rman_get_bustag(res)); - bus_space_subregion(rman_get_bustag(rle->res), - rman_get_bushandle(res), - sc->sc_desc.ports[i].offset, ressz, - &bh); - rman_set_bushandle(rle->res, bh); + error = puc_config(sc, PUC_CFG_GET_ILR, 0, &res); + if (error) + goto fail; + sc->sc_ilr = res; + if (bootverbose && sc->sc_ilr != 0) + device_printf(dev, "using interrupt latch register\n"); + + sc->sc_irid = 0; + sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, + RF_ACTIVE|RF_SHAREABLE); + if (sc->sc_ires != NULL) { + error = bus_setup_intr(dev, sc->sc_ires, + INTR_TYPE_TTY | INTR_FAST, puc_intr, sc, &sc->sc_icookie); + if (error) + error = bus_setup_intr(dev, sc->sc_ires, + INTR_TYPE_TTY | INTR_MPSAFE, puc_intr, sc, + &sc->sc_icookie); + else + sc->sc_fastintr = 1; + + if (error) { + device_printf(dev, "could not activate interrupt\n"); + bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, + sc->sc_ires); + sc->sc_ires = NULL; } + } + if (sc->sc_ires == NULL) { + /* XXX no interrupt resource. Force polled mode. */ + sc->sc_polled = 1; + } - pdev->port = i + 1; - pdev->serialfreq = sc->sc_desc.ports[i].serialfreq; - pdev->subtype = sc->sc_desc.ports[i].type & - PUC_PORT_SUBTYPE_MASK; - pdev->regshft = sc->sc_desc.ports[i].regshft; - - childunit = puc_find_free_unit(typestr); - if (childunit < 0 && strcmp(typestr, "uart") != 0) { - typestr = "uart"; - childunit = puc_find_free_unit(typestr); - } - sc->sc_ports[i].dev = device_add_child(dev, typestr, - childunit); - if (sc->sc_ports[i].dev == NULL) { - if (sc->barmuxed) { - bus_space_unmap(rman_get_bustag(rle->res), - rman_get_bushandle(rle->res), ressz); - rman_secret_puc_free_resource(rle->res); - free(pdev, M_DEVBUF); - } + /* Probe and attach our children. */ + for (idx = 0; idx < sc->sc_nports; idx++) { + port = &sc->sc_port[idx]; + if (port->p_dev == NULL) continue; - } - device_set_ivars(sc->sc_ports[i].dev, pdev); - device_set_desc(sc->sc_ports[i].dev, sc->sc_desc.name); -#ifdef PUC_DEBUG - printf("puc: type %d, bar %x, offset %x\n", - sc->sc_desc.ports[i].type, - sc->sc_desc.ports[i].bar, - sc->sc_desc.ports[i].offset); - puc_print_resource_list(&pdev->resources); -#endif - device_set_flags(sc->sc_ports[i].dev, - sc->sc_desc.ports[i].flags); - if (device_probe_and_attach(sc->sc_ports[i].dev) != 0) { - if (sc->barmuxed) { - bus_space_unmap(rman_get_bustag(rle->res), - rman_get_bushandle(rle->res), ressz); - rman_secret_puc_free_resource(rle->res); - free(pdev, M_DEVBUF); - } + error = device_probe_and_attach(port->p_dev); + if (error) { + device_delete_child(dev, port->p_dev); + port->p_dev = NULL; } } -#ifdef PUC_DEBUG - bootverbose = 0; -#endif - return (0); -} - -static u_int32_t -puc_ilr_read(struct puc_softc *sc) -{ - u_int32_t mask; - int i; + /* + * If there are no serdev devices, then our interrupt handler + * will do nothing. Tear it down. + */ + if (sc->sc_serdevs == 0UL) + bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); - mask = 0; - switch (sc->sc_desc.ilr_type) { - case PUC_ILR_TYPE_DIGI: - for (i = 1; i >= 0 && sc->sc_desc.ilr_offset[i] != 0; i--) { - mask = (mask << 8) | (bus_space_read_1(sc->ilr_st, - sc->ilr_sh, sc->sc_desc.ilr_offset[i]) & 0xff); - } - break; + return (0); - default: - mask = 0xffffffff; - break; +fail: + for (idx = 0; idx < sc->sc_nports; idx++) { + port = &sc->sc_port[idx]; + if (port->p_dev != NULL) + device_delete_child(dev, port->p_dev); + if (port->p_rres != NULL) + rman_release_resource(port->p_rres); + if (port->p_ires != NULL) + rman_release_resource(port->p_ires); } - return (mask); + for (idx = 0; idx < PUC_PCI_BARS; idx++) { + bar = &sc->sc_bar[idx]; + if (bar->b_res != NULL) + bus_release_resource(sc->sc_dev, bar->b_type, + bar->b_rid, bar->b_res); + } + rman_fini(&sc->sc_irq); + free(__DECONST(void *, sc->sc_irq.rm_descr), M_PUC); + rman_fini(&sc->sc_iomem); + free(__DECONST(void *, sc->sc_iomem.rm_descr), M_PUC); + rman_fini(&sc->sc_ioport); + free(__DECONST(void *, sc->sc_ioport.rm_descr), M_PUC); + free(sc->sc_port, M_PUC); + return (error); } -/* - * This is an interrupt handler. For boards that can't tell us which - * device generated the interrupt it just calls all the registered - * handlers sequencially, but for boards that can tell us which - * device(s) generated the interrupt it calls only handlers for devices - * that actually generated the interrupt. - */ -static void -puc_intr(void *arg) +int +puc_bfe_detach(device_t dev) { - int i; - u_int32_t ilr_mask; + struct puc_bar *bar; + struct puc_port *port; struct puc_softc *sc; + int error, idx; - sc = (struct puc_softc *)arg; - ilr_mask = sc->ilr_enabled ? puc_ilr_read(sc) : 0xffffffff; - for (i = 0; i < PUC_MAX_PORTS; i++) - if (sc->sc_ports[i].ihand != NULL && - ((ilr_mask >> i) & 0x00000001)) - (sc->sc_ports[i].ihand)(sc->sc_ports[i].ihandarg); -} + sc = device_get_softc(dev); -static int -puc_find_free_unit(char *name) -{ - devclass_t dc; - int start; - int unit; - - unit = 0; - start = 0; - while (resource_int_value(name, unit, "port", &start) == 0 && - start > 0) - unit++; - dc = devclass_find(name); - if (dc == NULL) - return (-1); - while (devclass_get_device(dc, unit)) - unit++; -#ifdef PUC_DEBUG - printf("puc: Using %s%d\n", name, unit); -#endif - return (unit); + /* Detach our children. */ + error = 0; + for (idx = 0; idx < sc->sc_nports; idx++) { + port = &sc->sc_port[idx]; + if (port->p_dev == NULL) + continue; + if (device_detach(port->p_dev) == 0) { + device_delete_child(dev, port->p_dev); + if (port->p_rres != NULL) + rman_release_resource(port->p_rres); + if (port->p_ires != NULL) + rman_release_resource(port->p_ires); + } else + error = ENXIO; + } + if (error) + return (error); + + if (sc->sc_serdevs != 0UL) + bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); + bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, sc->sc_ires); + + for (idx = 0; idx < PUC_PCI_BARS; idx++) { + bar = &sc->sc_bar[idx]; + if (bar->b_res != NULL) + bus_release_resource(sc->sc_dev, bar->b_type, + bar->b_rid, bar->b_res); + } + + rman_fini(&sc->sc_irq); + free(__DECONST(void *, sc->sc_irq.rm_descr), M_PUC); + rman_fini(&sc->sc_iomem); + free(__DECONST(void *, sc->sc_iomem.rm_descr), M_PUC); + rman_fini(&sc->sc_ioport); + free(__DECONST(void *, sc->sc_ioport.rm_descr), M_PUC); + free(sc->sc_port, M_PUC); + return (0); } -#ifdef PUC_DEBUG -static void -puc_print_resource_list(struct resource_list *rl) +int +puc_bfe_probe(device_t dev, const struct puc_cfg *cfg) { -#if 0 - struct resource_list_entry *rle; - - printf("print_resource_list: rl %p\n", rl); - SLIST_FOREACH(rle, rl, link) - printf(" type %x, rid %x start %lx end %lx count %lx\n", - rle->type, rle->rid, rle->start, rle->end, rle->count); - printf("print_resource_list: end.\n"); -#endif + struct puc_softc *sc; + intptr_t res; + int error; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + sc->sc_cfg = cfg; + + /* We don't attach to single-port serial cards. */ + if (cfg->ports == PUC_PORT_1S || cfg->ports == PUC_PORT_1P) + return (EDOOFUS); + error = puc_config(sc, PUC_CFG_GET_NPORTS, 0, &res); + if (error) + return (error); + error = puc_config(sc, PUC_CFG_GET_DESC, 0, &res); + if (error) + return (error); + if (res != 0) + device_set_desc(dev, (const char *)res); + return (BUS_PROBE_DEFAULT); } -#endif struct resource * -puc_alloc_resource(device_t dev, device_t child, int type, int *rid, +puc_bus_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 puc_device *pdev; - struct resource *retval; - struct resource_list *rl; - struct resource_list_entry *rle; - device_t my_child; - - /* - * in the case of a child of child we need to find our immediate child - */ - for (my_child = child; device_get_parent(my_child) != dev; - my_child = device_get_parent(my_child)); - - pdev = device_get_ivars(my_child); - rl = &pdev->resources; - -#ifdef PUC_DEBUG - printf("puc_alloc_resource: pdev %p, looking for t %x, r %x\n", - pdev, type, *rid); - puc_print_resource_list(rl); -#endif - retval = NULL; - rle = resource_list_find(rl, type, *rid); - if (rle) { -#ifdef PUC_DEBUG - printf("found rle, %lx, %lx, %lx\n", rle->start, rle->end, - rle->count); -#endif - retval = rle->res; - } -#ifdef PUC_DEBUG + struct puc_port *port; + struct resource *res; + device_t assigned, originator; + int error; + + /* Get our immediate child. */ + originator = child; + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (NULL); + + port = device_get_ivars(child); + KASSERT(port != NULL, ("%s %d", __func__, __LINE__)); + + if (rid == NULL || *rid != 0) + return (NULL); + + /* We only support default allocations. */ + if (start != 0UL || end != ~0UL) + return (NULL); + + if (type == port->p_bar->b_type) + res = port->p_rres; + else if (type == SYS_RES_IRQ) + res = port->p_ires; else - printf("oops rle is gone\n"); -#endif + return (NULL); + + if (res == NULL) + return (NULL); + + assigned = rman_get_device(res); + if (assigned == NULL) /* Not allocated */ + rman_set_device(res, originator); + else if (assigned != originator) + return (NULL); + + if (flags & RF_ACTIVE) { + error = rman_activate_resource(res); + if (error) { + if (assigned == NULL) + rman_set_device(res, NULL); + return (NULL); + } + } - return (retval); + return (res); } int -puc_release_resource(device_t dev, device_t child, int type, int rid, +puc_bus_release_resource(device_t dev, device_t child, int type, int rid, struct resource *res) { + struct puc_port *port; + device_t originator; + + /* Get our immediate child. */ + originator = child; + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); + + port = device_get_ivars(child); + KASSERT(port != NULL, ("%s %d", __func__, __LINE__)); + + if (rid != 0 || res == NULL) + return (EINVAL); + + if (type == port->p_bar->b_type) { + if (res != port->p_rres) + return (EINVAL); + } else if (type == SYS_RES_IRQ) { + if (res != port->p_ires) + return (EINVAL); + if (port->p_hasintr) + return (EBUSY); + } else + return (EINVAL); + + if (rman_get_device(res) != originator) + return (ENXIO); + if (rman_get_flags(res) & RF_ACTIVE) + rman_deactivate_resource(res); + rman_set_device(res, NULL); return (0); } int -puc_get_resource(device_t dev, device_t child, int type, int rid, +puc_bus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) { - struct puc_device *pdev; - struct resource_list *rl; - struct resource_list_entry *rle; - - pdev = device_get_ivars(child); - rl = &pdev->resources; - -#ifdef PUC_DEBUG - printf("puc_get_resource: pdev %p, looking for t %x, r %x\n", pdev, - type, rid); - puc_print_resource_list(rl); -#endif - rle = resource_list_find(rl, type, rid); - if (rle) { -#ifdef PUC_DEBUG - printf("found rle %p,", rle); -#endif - if (startp != NULL) - *startp = rle->start; - if (countp != NULL) - *countp = rle->count; -#ifdef PUC_DEBUG - printf(" %lx, %lx\n", rle->start, rle->count); -#endif - return (0); - } else - printf("oops rle is gone\n"); - return (ENXIO); + struct puc_port *port; + struct resource *res; + u_long start; + + /* Get our immediate child. */ + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); + + port = device_get_ivars(child); + KASSERT(port != NULL, ("%s %d", __func__, __LINE__)); + + if (type == port->p_bar->b_type) + res = port->p_rres; + else if (type == SYS_RES_IRQ) + res = port->p_ires; + else + return (ENXIO); + + if (rid != 0 || res == NULL) + return (ENXIO); + + start = rman_get_start(res); + if (startp != NULL) + *startp = start; + if (countp != NULL) + *countp = rman_get_end(res) - start + 1; + return (0); } int -puc_setup_intr(device_t dev, device_t child, struct resource *r, int flags, - void (*ihand)(void *), void *arg, void **cookiep) +puc_bus_setup_intr(device_t dev, device_t child, struct resource *res, + int flags, void (*ihand)(void *), void *arg, void **cookiep) { - int i; + struct puc_port *port; struct puc_softc *sc; + device_t originator; + int i, isrc, serdev; + + sc = device_get_softc(dev); + + /* Get our immediate child. */ + originator = child; + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); + + port = device_get_ivars(child); + KASSERT(port != NULL, ("%s %d", __func__, __LINE__)); - sc = (struct puc_softc *)device_get_softc(dev); - if ((flags & INTR_FAST) != sc->fastintr) + if (ihand == NULL || cookiep == NULL || res != port->p_ires) + return (EINVAL); + if (rman_get_device(port->p_ires) != originator) return (ENXIO); - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (sc->sc_ports[i].dev == child) { - if (sc->sc_ports[i].ihand != 0) - return (ENXIO); - sc->sc_ports[i].ihand = ihand; - sc->sc_ports[i].ihandarg = arg; - *cookiep = arg; - return (0); + + /* + * Have non-serdev ports handled by the bus implementation. It + * supports multiple handlers for a single interrupt as it is, + * so we wouldn't add value if we did it ourselves. + */ + serdev = 0; + if (port->p_type == PUC_TYPE_SERIAL) { + i = 0, isrc = SER_INT_OVERRUN; + while (i < PUC_ISRCCNT) { + port->p_ihsrc[i] = SERDEV_IHAND(originator, isrc); + if (port->p_ihsrc[i] != NULL) + serdev = 1; + i++, isrc <<= 1; } } - return (ENXIO); + if (!serdev) + return (BUS_SETUP_INTR(device_get_parent(dev), originator, + sc->sc_ires, flags, ihand, arg, cookiep)); + + /* We demand that serdev devices use fast interrupts. */ + if (!(flags & INTR_FAST)) + return (ENXIO); + + sc->sc_serdevs |= 1UL << (port->p_nr - 1); + + port->p_hasintr = 1; + port->p_ih = ihand; + port->p_iharg = arg; + + *cookiep = port; + return (0); } int -puc_teardown_intr(device_t dev, device_t child, struct resource *r, - void *cookie) +puc_bus_teardown_intr(device_t dev, device_t child, struct resource *res, + void *cookie) { - int i; + struct puc_port *port; struct puc_softc *sc; + device_t originator; + int i; - sc = (struct puc_softc *)device_get_softc(dev); - for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) { - if (sc->sc_ports[i].dev == child) { - sc->sc_ports[i].ihand = NULL; - sc->sc_ports[i].ihandarg = NULL; - return (0); - } - } - return (ENXIO); + sc = device_get_softc(dev); + + /* Get our immediate child. */ + originator = child; + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); + + port = device_get_ivars(child); + KASSERT(port != NULL, ("%s %d", __func__, __LINE__)); + + if (res != port->p_ires) + return (EINVAL); + if (rman_get_device(port->p_ires) != originator) + return (ENXIO); + + if (!port->p_hasintr) + return (BUS_TEARDOWN_INTR(device_get_parent(dev), originator, + sc->sc_ires, cookie)); + + if (cookie != port) + return (EINVAL); + + port->p_hasintr = 0; + port->p_ih = NULL; + port->p_iharg = NULL; + + for (i = 0; i < PUC_ISRCCNT; i++) + port->p_ihsrc[i] = NULL; + + return (0); } int -puc_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) +puc_bus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) { - struct puc_device *pdev; + struct puc_port *port; - pdev = device_get_ivars(child); - if (pdev == NULL) - return (ENOENT); + /* Get our immediate child. */ + while (child != NULL && device_get_parent(child) != dev) + child = device_get_parent(child); + if (child == NULL) + return (EINVAL); + + port = device_get_ivars(child); + KASSERT(port != NULL, ("%s %d", __func__, __LINE__)); + + if (result == NULL) + return (EINVAL); switch(index) { - case PUC_IVAR_FREQ: - *result = pdev->serialfreq; - break; - case PUC_IVAR_PORT: - *result = pdev->port; - break; - case PUC_IVAR_REGSHFT: - *result = pdev->regshft; + case PUC_IVAR_CLOCK: + *result = port->p_rclk; break; - case PUC_IVAR_SUBTYPE: - *result = pdev->subtype; + case PUC_IVAR_TYPE: + *result = port->p_type; break; default: return (ENOENT); diff --git a/sys/dev/puc/puc_bfe.h b/sys/dev/puc/puc_bfe.h new file mode 100644 index 0000000..199ba53 --- /dev/null +++ b/sys/dev/puc/puc_bfe.h @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2006 Marcel Moolenaar + * 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 ``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. + * + * $FreeBSD$ + */ + +#ifndef _DEV_PUC_BFE_H_ +#define _DEV_PUC_BFE_H + +#define PUC_PCI_BARS 6 + +struct puc_cfg; +struct puc_port; + +extern const struct puc_cfg puc_pci_devices[]; + +extern devclass_t puc_devclass; +extern const char puc_driver_name[]; + +struct puc_bar { + struct resource *b_res; + int b_rid; + int b_type; +}; + +struct puc_softc { + device_t sc_dev; + + const struct puc_cfg *sc_cfg; + intptr_t sc_cfg_data; + + struct puc_bar sc_bar[PUC_PCI_BARS]; + struct rman sc_ioport; + struct rman sc_iomem; + struct rman sc_irq; + + struct resource *sc_ires; + void *sc_icookie; + int sc_irid; + + int sc_nports; + struct puc_port *sc_port; + + int sc_fastintr:1; + int sc_leaving:1; + int sc_polled:1; + + int sc_ilr; + + /* + * Bitmask of ports that use the serdev I/F. This allows for + * 32 ports on ILP32 machines and 64 ports on LP64 machines. + */ + u_long sc_serdevs; +}; + +struct puc_bar *puc_get_bar(struct puc_softc *sc, int rid); + +int puc_bfe_attach(device_t); +int puc_bfe_detach(device_t); +int puc_bfe_probe(device_t, const struct puc_cfg *); + +struct resource *puc_bus_alloc_resource(device_t, device_t, int, int *, u_long, + u_long, u_long, u_int); +int puc_bus_get_resource(device_t, device_t, int, int, u_long *, u_long *); +int puc_bus_read_ivar(device_t, device_t, int, uintptr_t *); +int puc_bus_release_resource(device_t, device_t, int, int, struct resource *); +int puc_bus_setup_intr(device_t, device_t, struct resource *, int, + driver_intr_t *, void *, void **); +int puc_bus_teardown_intr(device_t, device_t, struct resource *, void *); + +#endif /* _DEV_PUC_BFE_H_ */ diff --git a/sys/dev/puc/puc_bus.h b/sys/dev/puc/puc_bus.h new file mode 100644 index 0000000..59da93d --- /dev/null +++ b/sys/dev/puc/puc_bus.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2006 Marcel Moolenaar + * 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 ``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. + * + * $FreeBSD$ + */ + +#ifndef _DEV_PUC_BUS_H_ +#define _DEV_PUC_BUS_H_ + +#include <sys/serial.h> +#include <serdev_if.h> + +#define PUC_IVAR_CLOCK 0 +#define PUC_IVAR_TYPE 1 + +/* Port types. */ +#define PUC_TYPE_SERIAL 1 +#define PUC_TYPE_PARALLEL 2 + +#endif /* _DEV_PUC_BUS_H_ */ diff --git a/sys/dev/puc/puc_cfg.c b/sys/dev/puc/puc_cfg.c new file mode 100644 index 0000000..13db186 --- /dev/null +++ b/sys/dev/puc/puc_cfg.c @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2006 Marcel Moolenaar + * 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 ``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/bus.h> +#include <sys/rman.h> + +#include <dev/puc/puc_bfe.h> +#include <dev/puc/puc_bus.h> +#include <dev/puc/puc_cfg.h> + +int +puc_config(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *r) +{ + const struct puc_cfg *cfg = sc->sc_cfg; + int error; + + if (cfg->config_function != NULL) { + error = cfg->config_function(sc, cmd, port, r); + if (!error) + return (0); + } else + error = EDOOFUS; + + switch (cmd) { + case PUC_CFG_GET_CLOCK: + if (cfg->clock < 0) + return (error); + *r = cfg->clock; + return (0); + case PUC_CFG_GET_DESC: + if (cfg->desc == NULL) + return (error); + *r = (intptr_t)cfg->desc; + return (0); + case PUC_CFG_GET_ILR: + *r = PUC_ILR_NONE; + return (0); + case PUC_CFG_GET_LEN: + /* The length of bus space needed by the port. */ + *r = 8; + return (0); + case PUC_CFG_GET_NPORTS: + /* The number of ports on this card. */ + switch (cfg->ports) { + case PUC_PORT_NONSTANDARD: + return (error); + case PUC_PORT_1P: + case PUC_PORT_1S: + *r = 1; + return (0); + case PUC_PORT_1S1P: + case PUC_PORT_2P: + case PUC_PORT_2S: + *r = 2; + return (0); + case PUC_PORT_1S2P: + case PUC_PORT_2S1P: + case PUC_PORT_3S: + *r = 3; + return (0); + case PUC_PORT_4S: + *r = 4; + return (0); + case PUC_PORT_4S1P: + *r = 5; + return (0); + case PUC_PORT_6S: + *r = 6; + return (0); + case PUC_PORT_8S: + *r = 8; + return (0); + case PUC_PORT_12S: + *r = 12; + return (0); + case PUC_PORT_16S: + *r = 16; + return (0); + } + break; + case PUC_CFG_GET_OFS: + /* The offset relative to the RID. */ + if (cfg->d_ofs < 0) + return (error); + *r = port * cfg->d_ofs; + return (0); + case PUC_CFG_GET_RID: + /* The RID for this port. */ + if (port == 0) { + if (cfg->rid < 0) + return (error); + *r = cfg->rid; + return (0); + } + if (cfg->d_rid < 0) + return (error); + if (cfg->rid < 0) { + error = puc_config(sc, PUC_CFG_GET_RID, 0, r); + if (error) + return (error); + } else + *r = cfg->rid; + *r += port * cfg->d_rid; + return (0); + case PUC_CFG_GET_TYPE: + /* The type of this port. */ + if (cfg->ports == PUC_PORT_NONSTANDARD) + return (error); + switch (port) { + case 0: + if (cfg->ports == PUC_PORT_1P || + cfg->ports == PUC_PORT_2P) + *r = PUC_TYPE_PARALLEL; + else + *r = PUC_TYPE_SERIAL; + return (0); + case 1: + if (cfg->ports == PUC_PORT_1S1P || + cfg->ports == PUC_PORT_1S2P || + cfg->ports == PUC_PORT_2P) + *r = PUC_TYPE_PARALLEL; + else + *r = PUC_TYPE_SERIAL; + return (0); + case 2: + if (cfg->ports == PUC_PORT_1S2P || + cfg->ports == PUC_PORT_2S1P) + *r = PUC_TYPE_PARALLEL; + else + *r = PUC_TYPE_SERIAL; + return (0); + case 4: + if (cfg->ports == PUC_PORT_4S1P) + *r = PUC_TYPE_PARALLEL; + else + *r = PUC_TYPE_SERIAL; + return (0); + } + *r = PUC_TYPE_SERIAL; + return (0); + case PUC_CFG_SETUP: + *r = ENXIO; + return (0); + } + + return (ENXIO); +} diff --git a/sys/dev/puc/puc_cfg.h b/sys/dev/puc/puc_cfg.h new file mode 100644 index 0000000..4c2c65e --- /dev/null +++ b/sys/dev/puc/puc_cfg.h @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2006 Marcel Moolenaar + * 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 ``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. + * + * $FreeBSD$ + */ + +#ifndef _DEV_PUC_CFG_H_ +#define _DEV_PUC_CFG_H + +#define DEFAULT_RCLK 1843200 + +#define PUC_PORT_NONSTANDARD 0 +#define PUC_PORT_1P 1 /* 1 parallel port */ +#define PUC_PORT_1S 2 /* 1 serial port */ +#define PUC_PORT_1S1P 3 /* 1 serial + 1 parallel ports */ +#define PUC_PORT_1S2P 4 /* 1 serial + 2 parallel ports */ +#define PUC_PORT_2P 5 /* 2 parallel ports */ +#define PUC_PORT_2S 6 /* 2 serial ports */ +#define PUC_PORT_2S1P 7 /* 2 serial + 1 parallel ports */ +#define PUC_PORT_3S 8 /* 3 serial ports */ +#define PUC_PORT_4S 9 /* 4 serial ports */ +#define PUC_PORT_4S1P 10 /* 4 serial + 1 parallel ports */ +#define PUC_PORT_6S 11 /* 6 serial ports */ +#define PUC_PORT_8S 12 /* 8 serial ports */ +#define PUC_PORT_12S 13 /* 12 serial ports */ +#define PUC_PORT_16S 14 /* 16 serial ports */ + +/* Interrupt Latch Register (ILR) types */ +#define PUC_ILR_NONE 0 +#define PUC_ILR_DIGI 1 +#define PUC_ILR_QUATECH 2 + +/* Configuration queries. */ +enum puc_cfg_cmd { + PUC_CFG_GET_CLOCK, + PUC_CFG_GET_DESC, + PUC_CFG_GET_ILR, + PUC_CFG_GET_LEN, + PUC_CFG_GET_NPORTS, + PUC_CFG_GET_OFS, + PUC_CFG_GET_RID, + PUC_CFG_GET_TYPE, + PUC_CFG_SETUP +}; + +struct puc_softc; + +typedef int puc_config_f(struct puc_softc *, enum puc_cfg_cmd, int, intptr_t *); + +struct puc_cfg { + uint16_t vendor; + uint16_t device; + uint16_t subvendor; + uint16_t subdevice; + const char *desc; + int clock; + int8_t ports; + int8_t rid; /* Rid of first port */ + int8_t d_rid; /* Delta rid of next ports */ + int8_t d_ofs; /* Delta offset of next ports */ + puc_config_f *config_function; +}; + +puc_config_f puc_config; + +#endif /* _DEV_PUC_CFG_H_ */ diff --git a/sys/dev/puc/puc_ebus.c b/sys/dev/puc/puc_ebus.c deleted file mode 100644 index 449712a..0000000 --- a/sys/dev/puc/puc_ebus.c +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 "opt_puc.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/conf.h> - -#include <dev/ofw/ofw_bus.h> - -#include <machine/bus.h> -#include <sys/rman.h> -#include <machine/resource.h> - -#define PUC_ENTRAILS 1 -#include <dev/puc/pucvar.h> - -static int -puc_ebus_probe(device_t dev) -{ - const char *nm, *cmpt; - - nm = ofw_bus_get_name(dev); - cmpt = ofw_bus_get_compat(dev); - if (!strcmp(nm, "se") || (cmpt != NULL && !strcmp(cmpt, "sab82532"))) { - device_set_desc(dev, "Siemens SAB 82532 dual channel SCC"); - return (BUS_PROBE_LOW_PRIORITY); - } - return (ENXIO); -} - -static int -puc_ebus_attach(device_t dev) -{ - struct puc_device_description dd; - int i; - - printf("NOTICE: Please configure device scc(1) into the kernel.\n"); - - bzero(&dd, sizeof(dd)); - dd.name = device_get_desc(dev); - for (i = 0; i < 2; i++) { - dd.ports[i].type = PUC_PORT_TYPE_UART | PUC_PORT_UART_SAB82532; - dd.ports[i].bar = 0; - dd.ports[i].offset = 0x40 * i; - dd.ports[i].serialfreq = 0; - dd.ports[i].flags = PUC_FLAGS_MEMORY; - } - return (puc_attach(dev, &dd)); -} - -static device_method_t puc_ebus_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, puc_ebus_probe), - DEVMETHOD(device_attach, puc_ebus_attach), - - DEVMETHOD(bus_alloc_resource, puc_alloc_resource), - DEVMETHOD(bus_release_resource, puc_release_resource), - DEVMETHOD(bus_get_resource, puc_get_resource), - DEVMETHOD(bus_read_ivar, puc_read_ivar), - DEVMETHOD(bus_setup_intr, puc_setup_intr), - DEVMETHOD(bus_teardown_intr, puc_teardown_intr), - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - { 0, 0 } -}; - -static driver_t puc_ebus_driver = { - "puc", - puc_ebus_methods, - sizeof(struct puc_softc), -}; - -DRIVER_MODULE(puc, ebus, puc_ebus_driver, puc_devclass, 0, 0); diff --git a/sys/dev/puc/puc_pccard.c b/sys/dev/puc/puc_pccard.c index c01db42..e250169 100644 --- a/sys/dev/puc/puc_pccard.c +++ b/sys/dev/puc/puc_pccard.c @@ -27,8 +27,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include "opt_puc.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -41,25 +39,19 @@ __FBSDID("$FreeBSD$"); #include <machine/resource.h> #include <sys/rman.h> -#define PUC_ENTRAILS 1 -#include <dev/puc/pucvar.h> - -#include <dev/sio/sioreg.h> #include <dev/pccard/pccardvar.h> -const struct puc_device_description rscom_devices = { +#include <dev/puc/puc_bfe.h> +#include <dev/puc/puc_cfg.h> +/* http://www.argosy.com.tw/product/sp320.htm */ +const struct puc_cfg puc_pccard_rscom = { + 0, 0, 0, 0, "ARGOSY SP320 Dual port serial PCMCIA", - /* http://www.argosy.com.tw/product/sp320.htm */ - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x0, 0x00, DEFAULT_RCLK, 0x100000 }, - { PUC_PORT_TYPE_COM, 0x1, 0x00, DEFAULT_RCLK, 0 }, - } + DEFAULT_RCLK, + PUC_PORT_2S, 0, 1, 0, }; - static int puc_pccard_probe(device_t dev) { @@ -72,39 +64,31 @@ puc_pccard_probe(device_t dev) error = pccard_get_product_str(dev, &product); if (error) return(error); - if (!strcmp(vendor, "PCMCIA") && !strcmp(product, "RS-COM 2P")) { - device_set_desc(dev, rscom_devices.name); - return (0); - } + if (!strcmp(vendor, "PCMCIA") && !strcmp(product, "RS-COM 2P")) + return (puc_bfe_probe(dev, &puc_pccard_rscom)); return (ENXIO); } -static int -puc_pccard_attach(device_t dev) -{ - - return (puc_attach(dev, &rscom_devices)); -} - static device_method_t puc_pccard_methods[] = { /* Device interface */ DEVMETHOD(device_probe, puc_pccard_probe), - DEVMETHOD(device_attach, puc_pccard_attach), - - DEVMETHOD(bus_alloc_resource, puc_alloc_resource), - DEVMETHOD(bus_release_resource, puc_release_resource), - DEVMETHOD(bus_get_resource, puc_get_resource), - DEVMETHOD(bus_read_ivar, puc_read_ivar), - DEVMETHOD(bus_setup_intr, puc_setup_intr), - DEVMETHOD(bus_teardown_intr, puc_teardown_intr), + DEVMETHOD(device_attach, puc_bfe_attach), + DEVMETHOD(device_detach, puc_bfe_detach), + + DEVMETHOD(bus_alloc_resource, puc_bus_alloc_resource), + DEVMETHOD(bus_release_resource, puc_bus_release_resource), + DEVMETHOD(bus_get_resource, puc_bus_get_resource), + DEVMETHOD(bus_read_ivar, puc_bus_read_ivar), + DEVMETHOD(bus_setup_intr, puc_bus_setup_intr), + DEVMETHOD(bus_teardown_intr, puc_bus_teardown_intr), DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_driver_added, bus_generic_driver_added), { 0, 0 } }; static driver_t puc_pccard_driver = { - "puc", + puc_driver_name, puc_pccard_methods, sizeof(struct puc_softc), }; diff --git a/sys/dev/puc/puc_pci.c b/sys/dev/puc/puc_pci.c index 2be23cf..5a458cc 100644 --- a/sys/dev/puc/puc_pci.c +++ b/sys/dev/puc/puc_pci.c @@ -60,8 +60,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include "opt_puc.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -77,215 +75,68 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#define PUC_ENTRAILS 1 -#include <dev/puc/pucvar.h> - -extern const struct puc_device_description puc_devices[]; - -int puc_config_win877(struct puc_softc *); +#include <dev/puc/puc_bfe.h> +#include <dev/puc/puc_cfg.h> -static const struct puc_device_description * -puc_find_description(uint32_t vend, uint32_t prod, uint32_t svend, - uint32_t sprod) +static const struct puc_cfg * +puc_pci_match(device_t dev, const struct puc_cfg *desc) { - 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); + uint16_t device, subdev, subven, vendor; + + vendor = pci_get_vendor(dev); + device = pci_get_device(dev); + while (desc->vendor != 0xffff && + (desc->vendor != vendor || desc->device != device)) + desc++; + if (desc->vendor == 0xffff) + return (NULL); + if (desc->subvendor == 0xffff) + return (desc); + subven = pci_get_subvendor(dev); + subdev = pci_get_subdevice(dev); + while (desc->vendor == vendor && desc->device == device && + (desc->subvendor != subven || desc->subdevice != subdev)) + desc++; + return ((desc->vendor == vendor && desc->device == device) + ? desc : NULL); } static int puc_pci_probe(device_t dev) { - uint32_t v1, v2, d1, d2; - const struct puc_device_description *desc; + const struct puc_cfg *desc; if ((pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) != 0) return (ENXIO); - v1 = pci_read_config(dev, PCIR_VENDOR, 2); - d1 = pci_read_config(dev, PCIR_DEVICE, 2); - v2 = pci_read_config(dev, PCIR_SUBVEND_0, 2); - d2 = pci_read_config(dev, PCIR_SUBDEV_0, 2); - - desc = puc_find_description(v1, d1, v2, d2); + desc = puc_pci_match(dev, puc_pci_devices); if (desc == NULL) return (ENXIO); - device_set_desc(dev, desc->name); - return (BUS_PROBE_DEFAULT); -} - -static int -puc_pci_attach(device_t dev) -{ - uint32_t v1, v2, d1, d2; - - v1 = pci_read_config(dev, PCIR_VENDOR, 2); - d1 = pci_read_config(dev, PCIR_DEVICE, 2); - v2 = pci_read_config(dev, PCIR_SUBVEND_0, 2); - d2 = pci_read_config(dev, PCIR_SUBDEV_0, 2); - return (puc_attach(dev, puc_find_description(v1, d1, v2, d2))); + return (puc_bfe_probe(dev, desc)); } static device_method_t puc_pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, puc_pci_probe), - DEVMETHOD(device_attach, puc_pci_attach), - - DEVMETHOD(bus_alloc_resource, puc_alloc_resource), - DEVMETHOD(bus_release_resource, puc_release_resource), - DEVMETHOD(bus_get_resource, puc_get_resource), - DEVMETHOD(bus_read_ivar, puc_read_ivar), - DEVMETHOD(bus_setup_intr, puc_setup_intr), - DEVMETHOD(bus_teardown_intr, puc_teardown_intr), + DEVMETHOD(device_attach, puc_bfe_attach), + DEVMETHOD(device_detach, puc_bfe_detach), + + DEVMETHOD(bus_alloc_resource, puc_bus_alloc_resource), + DEVMETHOD(bus_release_resource, puc_bus_release_resource), + DEVMETHOD(bus_get_resource, puc_bus_get_resource), + DEVMETHOD(bus_read_ivar, puc_bus_read_ivar), + DEVMETHOD(bus_setup_intr, puc_bus_setup_intr), + DEVMETHOD(bus_teardown_intr, puc_bus_teardown_intr), DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_driver_added, bus_generic_driver_added), { 0, 0 } }; static driver_t puc_pci_driver = { - "puc", + puc_driver_name, puc_pci_methods, sizeof(struct puc_softc), }; DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0); DRIVER_MODULE(puc, cardbus, puc_pci_driver, puc_devclass, 0, 0); - - -#define rdspio(indx) (bus_space_write_1(bst, bsh, efir, indx), \ - bus_space_read_1(bst, bsh, efdr)) -#define wrspio(indx,data) (bus_space_write_1(bst, bsh, efir, indx), \ - bus_space_write_1(bst, bsh, efdr, data)) - -#ifdef PUC_DEBUG -static void -puc_print_win877(bus_space_tag_t bst, bus_space_handle_t bsh, u_int efir, - u_int efdr) -{ - u_char cr00, cr01, cr04, cr09, cr0d, cr14, cr15, cr16, cr17; - u_char cr18, cr19, cr24, cr25, cr28, cr2c, cr31, cr32; - - cr00 = rdspio(0x00); - cr01 = rdspio(0x01); - cr04 = rdspio(0x04); - cr09 = rdspio(0x09); - cr0d = rdspio(0x0d); - cr14 = rdspio(0x14); - cr15 = rdspio(0x15); - cr16 = rdspio(0x16); - cr17 = rdspio(0x17); - cr18 = rdspio(0x18); - cr19 = rdspio(0x19); - cr24 = rdspio(0x24); - cr25 = rdspio(0x25); - cr28 = rdspio(0x28); - cr2c = rdspio(0x2c); - cr31 = rdspio(0x31); - cr32 = rdspio(0x32); - printf("877T: cr00 %x, cr01 %x, cr04 %x, cr09 %x, cr0d %x, cr14 %x, " - "cr15 %x, cr16 %x, cr17 %x, cr18 %x, cr19 %x, cr24 %x, cr25 %x, " - "cr28 %x, cr2c %x, cr31 %x, cr32 %x\n", cr00, cr01, cr04, cr09, - cr0d, cr14, cr15, cr16, cr17, - cr18, cr19, cr24, cr25, cr28, cr2c, cr31, cr32); -} -#endif - -int -puc_config_win877(struct puc_softc *sc) -{ - u_char val; - u_int efir, efdr; - bus_space_tag_t bst; - bus_space_handle_t bsh; - struct resource *res; - - res = sc->sc_bar_mappings[0].res; - - bst = rman_get_bustag(res); - bsh = rman_get_bushandle(res); - - /* configure the first W83877TF */ - bus_space_write_1(bst, bsh, 0x250, 0x89); - efir = 0x251; - efdr = 0x252; - val = rdspio(0x09) & 0x0f; - if (val != 0x0c) { - printf("conf_win877: Oops not a W83877TF\n"); - return (ENXIO); - } - -#ifdef PUC_DEBUG - printf("before: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - val = rdspio(0x16); - val |= 0x04; - wrspio(0x16, val); - val &= ~0x04; - wrspio(0x16, val); - - wrspio(0x24, 0x2e8 >> 2); - wrspio(0x25, 0x2f8 >> 2); - wrspio(0x17, 0x03); - wrspio(0x28, 0x43); - -#ifdef PUC_DEBUG - printf("after: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - bus_space_write_1(bst, bsh, 0x250, 0xaa); - - /* configure the second W83877TF */ - bus_space_write_1(bst, bsh, 0x3f0, 0x87); - bus_space_write_1(bst, bsh, 0x3f0, 0x87); - efir = 0x3f0; - efdr = 0x3f1; - val = rdspio(0x09) & 0x0f; - if (val != 0x0c) { - printf("conf_win877: Oops not a W83877TF\n"); - return(ENXIO); - } - -#ifdef PUC_DEBUG - printf("before: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - val = rdspio(0x16); - val |= 0x04; - wrspio(0x16, val); - val &= ~0x04; - wrspio(0x16, val); - - wrspio(0x24, 0x3e8 >> 2); - wrspio(0x25, 0x3f8 >> 2); - wrspio(0x17, 0x03); - wrspio(0x28, 0x43); - -#ifdef PUC_DEBUG - printf("after: "); - puc_print_win877(bst, bsh, efir, efdr); -#endif - - bus_space_write_1(bst, bsh, 0x3f0, 0xaa); - return (0); -} - -#undef rdspio -#undef wrspio - diff --git a/sys/dev/puc/puc_sbus.c b/sys/dev/puc/puc_sbus.c deleted file mode 100644 index fe5eb3c..0000000 --- a/sys/dev/puc/puc_sbus.c +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * Copyright (c) 2003 Marcel Moolenaar - * 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 ``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 "opt_puc.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/conf.h> - -#include <dev/ofw/ofw_bus.h> - -#include <machine/bus.h> -#include <sys/rman.h> -#include <machine/resource.h> - -#define PUC_ENTRAILS 1 -#include <dev/puc/pucvar.h> - -static int -puc_sbus_probe(device_t dev) -{ - const char *nm; - - nm = ofw_bus_get_name(dev); - if (!strcmp(nm, "zs")) { - device_set_desc(dev, "Zilog Z8530 dual channel SCC"); - return (BUS_PROBE_LOW_PRIORITY); - } - return (ENXIO); -} - -static int -puc_sbus_attach(device_t dev) -{ - struct puc_device_description dd; - int i; - - printf("NOTICE: Please configure device scc(1) into the kernel.\n"); - - bzero(&dd, sizeof(dd)); - dd.name = device_get_desc(dev); - for (i = 0; i < 2; i++) { - dd.ports[i].type = PUC_PORT_TYPE_UART | PUC_PORT_UART_Z8530; - dd.ports[i].bar = 0; - dd.ports[i].offset = 4 - 4 * i; - dd.ports[i].serialfreq = 0; - dd.ports[i].flags = PUC_FLAGS_MEMORY; - dd.ports[i].regshft = 1; - } - return (puc_attach(dev, &dd)); -} - -static device_method_t puc_sbus_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, puc_sbus_probe), - DEVMETHOD(device_attach, puc_sbus_attach), - - DEVMETHOD(bus_alloc_resource, puc_alloc_resource), - DEVMETHOD(bus_release_resource, puc_release_resource), - DEVMETHOD(bus_get_resource, puc_get_resource), - DEVMETHOD(bus_read_ivar, puc_read_ivar), - DEVMETHOD(bus_setup_intr, puc_setup_intr), - DEVMETHOD(bus_teardown_intr, puc_teardown_intr), - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - { 0, 0 } -}; - -static driver_t puc_sbus_driver = { - "puc", - puc_sbus_methods, - sizeof(struct puc_softc), -}; - -DRIVER_MODULE(puc, fhc, puc_sbus_driver, puc_devclass, 0, 0); -DRIVER_MODULE(puc, sbus, puc_sbus_driver, puc_devclass, 0, 0); diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c index ff4c230..a1d1d4d 100644 --- a/sys/dev/puc/pucdata.c +++ b/sys/dev/puc/pucdata.c @@ -1,22 +1,16 @@ -/* $NetBSD: pucdata.c,v 1.25 2001/12/16 22:23:01 thorpej Exp $ */ - /*- - * Copyright (c) 1998, 1999 Christopher G. Demetriou. All rights reserved. + * Copyright (c) 2006 Marcel Moolenaar + * 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 @@ -39,801 +33,550 @@ __FBSDID("$FreeBSD$"); */ #include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/bus.h> + +#include <machine/resource.h> +#include <sys/rman.h> -#include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#include <dev/sio/sioreg.h> -#include <dev/puc/pucvar.h> - -#define COM_FREQ DEFAULT_RCLK - -int puc_config_win877(struct puc_softc *); - -const struct puc_device_description puc_devices[] = { - - { "Sunix SUN1889", - { 0x0009, 0x7168, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 }, - }, - }, - - { "Diva Serial [GSP] Multiport UART", - { 0x103c, 0x1048, 0x103c, 0x1282 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_UART, 0x10, 0x00, 0, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x10, 0x10, 0, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x10, 0x38, 0, PUC_FLAGS_MEMORY }, - }, - }, - - { "Comtrol RocketPort 550/4 RJ45", - { 0x11fe, 0x8014, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - - { "Comtrol RocketPort 550/Quad", - { 0x11fe, 0x8015, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - - { "Comtrol RocketPort 550/8 RJ11 part A", - { 0x11fe, 0x8010, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - { "Comtrol RocketPort 550/8 RJ11 part B", - { 0x11fe, 0x8011, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - - { "Comtrol RocketPort 550/8 Octa part A", - { 0x11fe, 0x8012, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - { "Comtrol RocketPort 550/8 Octa part B", - { 0x11fe, 0x8013, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - - { "Comtrol RocketPort 550/8 part A", - { 0x11fe, 0x8018, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - { "Comtrol RocketPort 550/8 part B", - { 0x11fe, 0x8019, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - - { "Comtrol RocketPort 550/16 part A", - { 0x11fe, 0x8016, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - }, - }, - { "Comtrol RocketPort 550/16 part B", - { 0x11fe, 0x8017, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 4 }, - }, + +#include <dev/puc/puc_bfe.h> +#include <dev/puc/puc_bus.h> +#include <dev/puc/puc_cfg.h> + +static puc_config_f puc_config_amc; +static puc_config_f puc_config_cronyx; +static puc_config_f puc_config_diva; +static puc_config_f puc_config_icbook; +static puc_config_f puc_config_quatech; +static puc_config_f puc_config_syba; +static puc_config_f puc_config_siig; +static puc_config_f puc_config_timedia; +static puc_config_f puc_config_titan; + +const struct puc_cfg puc_pci_devices[] = { + + { 0x0009, 0x7168, 0xffff, 0, + "Sunix SUN1889", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x10, 0, 8, + }, + + { 0x103c, 0x1048, 0x103c, 0x1049, + "HP Diva Serial [GSP] Multiport UART - Tosca Console", + DEFAULT_RCLK, + PUC_PORT_3S, 0x10, 0, -1, + .config_function = puc_config_diva + }, + + { 0x103c, 0x1048, 0x103c, 0x104a, + "HP Diva Serial [GSP] Multiport UART - Tosca Secondary", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 0, -1, + .config_function = puc_config_diva + }, + + { 0x103c, 0x1048, 0x103c, 0x104b, + "HP Diva Serial [GSP] Multiport UART - Maestro SP2", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, -1, + .config_function = puc_config_diva + }, + + { 0x103c, 0x1048, 0x103c, 0x1223, + "HP Diva Serial [GSP] Multiport UART - Superdome Console", + DEFAULT_RCLK, + PUC_PORT_3S, 0x10, 0, -1, + .config_function = puc_config_diva + }, + + { 0x103c, 0x1048, 0x103c, 0x1226, + "HP Diva Serial [GSP] Multiport UART - Keystone SP2", + DEFAULT_RCLK, + PUC_PORT_3S, 0x10, 0, -1, + .config_function = puc_config_diva + }, + + { 0x103c, 0x1048, 0x103c, 0x1282, + "HP Diva Serial [GSP] Multiport UART - Everest SP2", + DEFAULT_RCLK, + PUC_PORT_3S, 0x10, 0, -1, + .config_function = puc_config_diva + }, + + { 0x10b5, 0x1076, 0x10b5, 0x1076, + "VScom PCI-800", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x18, 0, 8, + }, + + { 0x10b5, 0x1077, 0x10b5, 0x1077, + "VScom PCI-400", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x18, 0, 8, + }, + + { 0x10b5, 0x1103, 0x10b5, 0x1103, + "VScom PCI-200", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x18, 4, 0, }, /* - * XXX no entry because I have no data: - * XXX Dolphin Peripherals 4006 (single parallel) + * Boca Research Turbo Serial 658 (8 serial port) card. + * Appears to be the same as Chase Research PLC PCI-FAST8 + * and Perle PCI-FAST8 Multi-Port serial cards. */ + { 0x10b5, 0x9050, 0x12e0, 0x0021, + "Boca Research Turbo Serial 658", + DEFAULT_RCLK * 4, + PUC_PORT_8S, 0x18, 0, 8, + }, + + { 0x10b5, 0x9050, 0x12e0, 0x0031, + "Boca Research Turbo Serial 654", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x18, 0, 8, + }, /* - * Dolphin Peripherals 4014 (dual parallel port) card. PLX 9050, with + * 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 4014", - { 0x10b5, 0x9050, 0xd84d, 0x6810 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_LPT, 0x20, 0x00, 0x00 }, - { PUC_PORT_TYPE_LPT, 0x24, 0x00, 0x00 }, - }, + { 0x10b5, 0x9050, 0xd84d, 0x6808, + "Dolphin Peripherals 4035", + DEFAULT_RCLK, + PUC_PORT_2S, 0x18, 4, 0, }, /* - * XXX Dolphin Peripherals 4025 (single serial) - * (clashes with Dolphin Peripherals 4036 (2s variant) - */ - - /* - * Dolphin Peripherals 4035 (dual serial port) card. PLX 9050, with + * 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 4035", - { 0x10b5, 0x9050, 0xd84d, 0x6808 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, + { 0x10b5, 0x9050, 0xd84d, 0x6810, + "Dolphin Peripherals 4014", + 0, + PUC_PORT_2P, 0x20, 4, 0, }, - /* - * Dolphin Peripherals 4036 (dual serial port) card. - * (Dolpin 4025 has the same ID but only one port) - */ - { "Dolphin Peripherals 4036", - { 0x1409, 0x7168, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 }, - }, + { 0x10e8, 0x818e, 0xffff, 0, + "Applied Micro Circuits 8 Port UART", + DEFAULT_RCLK, + PUC_PORT_8S, 0x14, -1, -1, + .config_function = puc_config_amc + }, + + { 0x11fe, 0x8010, 0xffff, 0, + "Comtrol RocketPort 550/8 RJ11 part A", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, }, - /* - * XXX no entry because I have no data: - * XXX Dolphin Peripherals 4078 (dual serial and single parallel) - */ + { 0x11fe, 0x8011, 0xffff, 0, + "Comtrol RocketPort 550/8 RJ11 part B", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8012, 0xffff, 0, + "Comtrol RocketPort 550/8 Octa part A", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + { 0x11fe, 0x8013, 0xffff, 0, + "Comtrol RocketPort 550/8 Octa part B", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8014, 0xffff, 0, + "Comtrol RocketPort 550/4 RJ45", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8015, 0xffff, 0, + "Comtrol RocketPort 550/Quad", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8016, 0xffff, 0, + "Comtrol RocketPort 550/16 part A", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8017, 0xffff, 0, + "Comtrol RocketPort 550/16 part B", + DEFAULT_RCLK * 4, + PUC_PORT_12S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8018, 0xffff, 0, + "Comtrol RocketPort 550/8 part A", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x11fe, 0x8019, 0xffff, 0, + "Comtrol RocketPort 550/8 part B", + DEFAULT_RCLK * 4, + PUC_PORT_4S, 0x10, 0, 8, + }, /* * 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. + * <URL:http://www.siig.com/downloads.asp> */ - /* - * SIIG "10x" family boards. - */ + { 0x131f, 0x1010, 0xffff, 0, + "SIIG Cyber I/O PCI 16C550 (10x family)", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x18, 4, 0, + }, - /* 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, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x1c, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x1c, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x1c, 0x00, 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, 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, 0x00 }, - { PUC_PORT_TYPE_LPT, 0x20, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x20, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x20, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x20, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x20, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x24, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x20, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x24, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x20, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x24, 0x00, COM_FREQ }, - }, + { 0x131f, 0x1011, 0xffff, 0, + "SIIG Cyber I/O PCI 16C650 (10x family)", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x18, 4, 0, }, - /* - * SIIG "20x" family boards. - */ + { 0x131f, 0x1012, 0xffff, 0, + "SIIG Cyber I/O PCI 16C850 (10x family)", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x18, 4, 0, + }, - /* 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, 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, 0x00 }, - { PUC_PORT_TYPE_LPT, 0x18, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x14, 0x00, 0x00 }, - { PUC_PORT_TYPE_LPT, 0x1c, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x14, 0x00, 0x00 }, - { PUC_PORT_TYPE_LPT, 0x1c, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x14, 0x00, 0x00 }, - { PUC_PORT_TYPE_LPT, 0x1c, 0x00, 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, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x14, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x14, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x14, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x18, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x18, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x18, 0x00, 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* 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, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* VScom PCI-200L: 2S */ - { "VScom PCI-200L", - { 0x14d2, 0x8020, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - }, - }, - - /* VScom PCI-400: 4S */ - { "VScom PCI-400", - { 0x10b5, 0x1077, 0x10b5, 0x1077 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - }, - }, - - /* VScom PCI-800: 8S */ - { "VScom PCI-800", - { 0x10b5, 0x1076, 0x10b5, 0x1076 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x20, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x28, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x30, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x38, COM_FREQ * 8 }, - }, + { 0x131f, 0x1021, 0xffff, 0, + "SIIG Cyber Parallel Dual PCI (10x family)", + 0, + PUC_PORT_2P, 0x18, 8, 0, }, - /* - * VScom PCI-800H. Uses 8 16950 UART, behind a PCI chips that offers - * 4 com port on PCI device 0 and 4 on PCI device 1. PCI device 0 has - * device ID 3 and PCI device 1 device ID 4. - */ - { "Titan PCI-800H", - { 0x14d2, 0xa003, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8 }, - }, - }, - { "Titan PCI-800H", - { 0x14d2, 0xa004, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8 }, - }, - }, - { "Titan PCI-200H", - { 0x14d2, 0xa005, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 }, - }, - }, - - { "Titan VScom PCI-200HV2", /* 2S */ - { 0x14d2, 0xe020, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ * 8 }, - }, + + { 0x131f, 0x1030, 0xffff, 0, + "SIIG Cyber Serial Dual PCI 16C550 (10x family)", + DEFAULT_RCLK, + PUC_PORT_2S, 0x18, 4, 0, }, - /* - * VScom (Titan?) PCI-800L. More modern variant of the - * PCI-800. Uses 6 discrete 16550 UARTs, plus another - * two of them obviously implemented as macro cells in - * the ASIC. This causes the weird port access pattern - * below, where two of the IO port ranges each access - * one of the ASIC UARTs, and a block of IO addresses - * access the external UARTs. - */ - { "Titan VScom PCI-800L", - { 0x14d2, 0x8080, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x20, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x20, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x20, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x20, 0x18, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x20, 0x20, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x20, 0x28, COM_FREQ * 8 }, - }, + + { 0x131f, 0x1031, 0xffff, 0, + "SIIG Cyber Serial Dual PCI 16C650 (10x family)", + DEFAULT_RCLK, + PUC_PORT_2S, 0x18, 4, 0, }, - /* - * NEC PK-UG-X001 K56flex PCI Modem card. - * Uses NEC MARTH bridge chip and Rockwell RCVDL56ACF/SP. - */ - { "NEC PK-UG-X001 K56flex PCI Modem", - { 0x1033, 0x0074, 0x1033, 0x8014 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - }, - }, - - /* NEC PK-UG-X008 */ - { "NEC PK-UG-X008", - { 0x1033, 0x007d, 0x1033, 0x8012 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - }, - }, - - /* Lava Computers 2SP-PCI */ - { "Lava Computers 2SP-PCI parallel port", - { 0x1407, 0x8000, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_LPT, 0x10, 0x00, 0x00 }, - }, - }, - - /* Lava Computers 2SP-PCI and Quattro-PCI serial ports */ - { "Lava Computers dual serial port", - { 0x1407, 0x0100, 0, 0 }, - { 0xffff, 0xfffc, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, - }, - - /* Lava Computers newer Quattro-PCI serial ports */ - { "Lava Computers Quattro-PCI serial port", - { 0x1407, 0x0120, 0, 0 }, - { 0xffff, 0xfffc, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, - }, - - /* Lava Computers DSerial PCI serial ports */ - { "Lava Computers serial port", - { 0x1407, 0x0110, 0, 0 }, - { 0xffff, 0xfffc, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - }, - }, - - /* Lava Computers Octopus-550 serial ports */ - { "Lava Computers Octopus-550 8-port serial", - { 0x1407, 0x0180, 0, 0 }, - { 0xffff, 0xfffc, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* US Robotics (3Com) PCI Modems */ - { "US Robotics (3Com) 3CP5609 PCI 16550 Modem", - { 0x12b9, 0x1008, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - }, - }, - - /* Actiontec 56K PCI Master */ - { "Actiontec 56K PCI Master", - { 0x11c1, 0x0480, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, + { 0x131f, 0x1032, 0xffff, 0, + "SIIG Cyber Serial Dual PCI 16C850 (10x family)", + DEFAULT_RCLK, + PUC_PORT_2S, 0x18, 4, 0, + }, + + { 0x131f, 0x1034, 0xffff, 0, /* XXX really? */ + "SIIG Cyber 2S1P PCI 16C550 (10x family)", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x18, 4, 0, + }, + + { 0x131f, 0x1035, 0xffff, 0, /* XXX really? */ + "SIIG Cyber 2S1P PCI 16C650 (10x family)", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x18, 4, 0, + }, + + { 0x131f, 0x1036, 0xffff, 0, /* XXX really? */ + "SIIG Cyber 2S1P PCI 16C850 (10x family)", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x18, 4, 0, + }, + + { 0x131f, 0x1050, 0xffff, 0, + "SIIG Cyber 4S PCI 16C550 (10x family)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x18, 4, 0, + }, + + { 0x131f, 0x1051, 0xffff, 0, + "SIIG Cyber 4S PCI 16C650 (10x family)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x18, 4, 0, + }, + + { 0x131f, 0x1052, 0xffff, 0, + "SIIG Cyber 4S PCI 16C850 (10x family)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x18, 4, 0, + }, + + { 0x131f, 0x2010, 0xffff, 0, + "SIIG Cyber I/O PCI 16C550 (20x family)", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x10, 4, 0, + }, + + { 0x131f, 0x2011, 0xffff, 0, + "SIIG Cyber I/O PCI 16C650 (20x family)", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x10, 4, 0, + }, + + { 0x131f, 0x2012, 0xffff, 0, + "SIIG Cyber I/O PCI 16C850 (20x family)", + DEFAULT_RCLK, + PUC_PORT_1S1P, 0x10, 4, 0, + }, + + { 0x131f, 0x2021, 0xffff, 0, + "SIIG Cyber Parallel Dual PCI (20x family)", + 0, + PUC_PORT_2P, 0x10, 8, 0, + }, + + { 0x131f, 0x2030, 0xffff, 0, + "SIIG Cyber Serial Dual PCI 16C550 (20x family)", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x131f, 0x2031, 0xffff, 0, + "SIIG Cyber Serial Dual PCI 16C650 (20x family)", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x131f, 0x2032, 0xffff, 0, + "SIIG Cyber Serial Dual PCI 16C850 (20x family)", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x131f, 0x2040, 0xffff, 0, + "SIIG Cyber 2P1S PCI 16C550 (20x family)", + DEFAULT_RCLK, + PUC_PORT_1S2P, 0x10, -1, 0, + .config_function = puc_config_siig + }, + + { 0x131f, 0x2041, 0xffff, 0, + "SIIG Cyber 2P1S PCI 16C650 (20x family)", + DEFAULT_RCLK, + PUC_PORT_1S2P, 0x10, -1, 0, + .config_function = puc_config_siig + }, + + { 0x131f, 0x2042, 0xffff, 0, + "SIIG Cyber 2P1S PCI 16C850 (20x family)", + DEFAULT_RCLK, + PUC_PORT_1S2P, 0x10, -1, 0, + .config_function = puc_config_siig + }, + + { 0x131f, 0x2050, 0xffff, 0, + "SIIG Cyber 4S PCI 16C550 (20x family)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0, + }, + + { 0x131f, 0x2051, 0xffff, 0, + "SIIG Cyber 4S PCI 16C650 (20x family)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0, + }, + + { 0x131f, 0x2052, 0xffff, 0, + "SIIG Cyber 4S PCI 16C850 (20x family)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0, + }, + + { 0x131f, 0x2060, 0xffff, 0, + "SIIG Cyber 2S1P PCI 16C550 (20x family)", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x10, 4, 0, + }, + + { 0x131f, 0x2061, 0xffff, 0, + "SIIG Cyber 2S1P PCI 16C650 (20x family)", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x10, 4, 0, + }, + + { 0x131f, 0x2062, 0xffff, 0, + "SIIG Cyber 2S1P PCI 16C850 (20x family)", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x10, 4, 0, + }, + + { 0x131f, 0x2081, 0xffff, 0, + "SIIG PS8000 8S PCI 16C650 (20x family)", + DEFAULT_RCLK, + PUC_PORT_8S, 0x10, -1, -1, + .config_function = puc_config_siig + }, + + { 0x135c, 0x0010, 0xffff, 0, + "Quatech QSC-100", + -3, /* max 8x clock rate */ + PUC_PORT_4S, 0x14, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0020, 0xffff, 0, + "Quatech DSC-100", + -1, /* max 2x clock rate */ + PUC_PORT_2S, 0x14, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0030, 0xffff, 0, + "Quatech DSC-200/300", + -1, /* max 2x clock rate */ + PUC_PORT_2S, 0x14, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0040, 0xffff, 0, + "Quatech QSC-200/300", + -3, /* max 8x clock rate */ + PUC_PORT_4S, 0x14, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0050, 0xffff, 0, + "Quatech ESC-100D", + -3, /* max 8x clock rate */ + PUC_PORT_8S, 0x14, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0060, 0xffff, 0, + "Quatech ESC-100M", + -3, /* max 8x clock rate */ + PUC_PORT_8S, 0x14, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0170, 0xffff, 0, + "Quatech QSCLP-100", + -1, /* max 2x clock rate */ + PUC_PORT_4S, 0x18, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x0180, 0xffff, 0, + "Quatech DSCLP-100", + -1, /* max 3x clock rate */ + PUC_PORT_2S, 0x18, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x01b0, 0xffff, 0, + "Quatech DSCLP-200/300", + -1, /* max 2x clock rate */ + PUC_PORT_2S, 0x18, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x135c, 0x01e0, 0xffff, 0, + "Quatech ESCLP-100", + -3, /* max 8x clock rate */ + PUC_PORT_8S, 0x10, 0, 8, + .config_function = puc_config_quatech + }, + + { 0x1393, 0x1040, 0xffff, 0, + "Moxa Technologies, Smartio C104H/PCI", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x18, 0, 8, + }, + + { 0x1393, 0x1041, 0xffff, 0, + "Moxa Technologies, Smartio CP-104UL/PCI", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x18, 0, 8, + }, + + { 0x1393, 0x1141, 0xffff, 0, + "Moxa Technologies, Industio CP-114", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x18, 0, 8, + }, + + { 0x1393, 0x1680, 0xffff, 0, + "Moxa Technologies, C168H/PCI", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x18, 0, 8, + }, + + { 0x1393, 0x1681, 0xffff, 0, + "Moxa Technologies, C168U/PCI", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x18, 0, 8, + }, + + { 0x13a8, 0x0158, 0xffff, 0, + "Cronyx Omega2-PCI", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x10, 0, -1, + .config_function = puc_config_cronyx + }, + + { 0x1407, 0x0100, 0xffff, 0, + "Lava Computers Dual Serial", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x1407, 0x0101, 0xffff, 0, + "Lava Computers Quatro A", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x1407, 0x0102, 0xffff, 0, + "Lava Computers Quatro B", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x1407, 0x0120, 0xffff, 0, + "Lava Computers Quattro-PCI A", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x1407, 0x0121, 0xffff, 0, + "Lava Computers Quattro-PCI B", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x1407, 0x0180, 0xffff, 0, + "Lava Computers Octo A", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0, + }, + + { 0x1407, 0x0181, 0xffff, 0, + "Lava Computers Octo B", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0, + }, + + { 0x1409, 0x7168, 0xffff, 0, + NULL, + DEFAULT_RCLK * 8, + PUC_PORT_NONSTANDARD, 0x10, -1, -1, + .config_function = puc_config_timedia }, /* @@ -846,442 +589,544 @@ const struct puc_device_description puc_devices[] = { * I/O Flex PCI I/O Card Model-223 with 4 serial and 1 parallel ports. */ - /* Oxford Semiconductor OX12PCI840 PCI Parallel port */ - { "Oxford Semiconductor OX12PCI840 Parallel port", - { 0x1415, 0x8403, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_LPT, 0x10, 0x00, 0x00 }, - }, - }, - - /* Oxford Semiconductor OX16PCI954 PCI UARTs */ - { "Oxford Semiconductor OX16PCI954 UARTs", - { 0x1415, 0x9501, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - }, - }, - - /* Oxford Semiconductor OX16PCI954 PCI UARTs */ - { "Oxford Semiconductor OX16PCI954 UARTs", - { 0x1415, 0x950a, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - }, - }, - - /* Oxford Semiconductor OXCB950 PCI/CardBus UARTs */ - { "Oxford Semiconductor OXCB950 UART", - { 0x1415, 0x950b, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - /* { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, */ - { PUC_PORT_TYPE_COM, 0x10, 0x00, 16384000 }, - }, + { 0x1415, 0x9501, 0xffff, 0, + "Oxford Semiconductor OX16PCI954 UARTs", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, 8, }, - /* - * Oxford Semiconductor OX9160/OX16PCI954 PCI UARTS - * Second chip on Exsys EX-41098 8x cards - */ - { "Oxford Semiconductor OX9160/OX16PCI954 UARTs (function 1)", - { 0x1415, 0x9511, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - }, - }, - - /* Oxford Semiconductor OX16PCI954 PCI Parallel port */ - { "Oxford Semiconductor OX16PCI954 Parallel port", - { 0x1415, 0x9513, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_LPT, 0x10, 0x00, 0x00 }, - }, - }, - - /* NetMos 2S1P PCI 16C650 : 2S, 1P */ - { "NetMos NM9835 Dual UART and 1284 Printer port", - { 0x9710, 0x9835, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x18, 0x00, 0x00 }, - }, - }, - - /* NetMos 4S0P PCI: 4S, 0P */ - { "NetMos NM9845 Quad UART", - { 0x9710, 0x9845, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* NetMos 0S1P PCI: 0S, 1P */ - { "NetMos NM9805 1284 Printer port", - { 0x9710, 0x9805, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_LPT, 0x10, 0x00, 0x00 }, - }, - }, + { 0x1415, 0x950a, 0xffff, 0, + "Oxford Semiconductor OX16PCI954 UARTs", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, 8, + }, - /* - * This is the Middle Digital, Inc. PCI-Weasel, which - * uses a PCI interface implemented in FPGA. - */ - { "Middle Digital, Inc. Weasel serial port", - { 0xdeaf, 0x9051, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - }, - }, - - /* SD-LAB PCI I/O Card 4S2P */ - { "Syba Tech Ltd. PCI-4S2P-550-ECP", - { 0x1592, 0x0781, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x2e8, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x2f8, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x10, 0x000, 0x00 }, - { PUC_PORT_TYPE_COM, 0x10, 0x3e8, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x3f8, COM_FREQ }, - { PUC_PORT_TYPE_LPT, 0x10, 0x000, 0x00 }, - }, - .init = puc_config_win877, - }, - - /* Moxa Technologies Co., Ltd. PCI I/O Card 4S RS232 */ - { "Moxa Technologies, Smartio C104H/PCI", - { 0x1393, 0x1040, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - }, - }, - - /* Moxa Technologies Co., Ltd. PCI I/O Card 4S RS232 */ - { "Moxa Technologies, Smartio CP-104UL/PCI", - { 0x1393, 0x1041, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - }, - }, - - /* Moxa Technologies Co., Ltd. PCI I/O Card 4S RS232/422/485 */ - { "Moxa Technologies, Industio CP-114", - { 0x1393, 0x1141, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - }, - }, - - /* Moxa Technologies Co., Ltd. PCI I/O Card 8S RS232 */ - { "Moxa Technologies, C168H/PCI", - { 0x1393, 0x1680, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x20, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x28, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x30, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x38, COM_FREQ * 8 }, - }, - }, - - /* Moxa Technologies Co., Ltd. PCI I/O Card 8S RS232 */ - { "Moxa Technologies, C168U/PCI", - { 0x1393, 0x1681, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x20, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x28, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x30, COM_FREQ * 8 }, - { PUC_PORT_TYPE_COM, 0x18, 0x38, COM_FREQ * 8 }, - }, - }, - - { "Avlab Technology, PCI IO 2S", - { 0x14db, 0x2130, 0, 0 }, - { 0xffff, 0xfffc, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - }, - }, - - /* Avlab Technology, Inc. Low Profile PCI 4 Serial: 4S */ - { "Avlab Low Profile PCI 4 Serial", - { 0x14db, 0x2150, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - }, - }, - - /* Decision Computer Inc, serial ports */ - { "Decision Computer Inc, PCCOM 4-port serial", - { 0x6666, 0x0001, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x18, COM_FREQ }, - }, - }, - - { "PCCOM dual port RS232/422/485", - { 0x6666, 0x0004, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x1c, 0x08, COM_FREQ }, - }, - }, - - { "IC Book Labs Gunboat x2 Low Profile", - { 0xb00c, 0x0a1c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - }, - }, - - { "IC Book Labs Gunboat x4 Lite", - { 0xb00c, 0x021c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - }, - PUC_ILR_TYPE_DIGI, { 0x07 }, - }, - - { "IC Book Labs Gunboat x4 Pro", - { 0xb00c, 0x031c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - }, - PUC_ILR_TYPE_DIGI, { 0x07 }, - }, - - { "IC Book Labs Gunboat x4 Low Profile", - { 0xb00c, 0x0b1c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - }, - PUC_ILR_TYPE_DIGI, { 0x07 }, - }, - - { "IC Book Labs Ironclad x8 Lite", - { 0xb00c, 0x041c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ }, - }, - PUC_ILR_TYPE_DIGI, { 0x07 }, - }, - - { "IC Book Labs Ironclad x8 Pro", - { 0xb00c, 0x051c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ }, - }, - PUC_ILR_TYPE_DIGI, { 0x07 }, - }, - - { "IC Book Labs Dreadnought x16 Lite", - { 0xb00c, 0x091c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ }, - { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ }, - }, - PUC_ILR_TYPE_DIGI, { 0x07, 0x47 }, - }, - - { "IC Book Labs Dreadnought x16 Pro", - { 0xb00c, 0x081c, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 8, 0x200000 }, - { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 8, 0x200000 }, - }, - PUC_ILR_TYPE_DIGI, { 0x07, 0x47 }, - }, - - { "Cronyx Omega2-PCI", - { 0x13a8, 0x0158, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_UART, 0x010, 0x000, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0x200, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0x400, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0x600, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0x800, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0xA00, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0xC00, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - { PUC_PORT_TYPE_UART, 0x010, 0xE00, COM_FREQ * 8, PUC_FLAGS_MEMORY }, - }, + { 0x1415, 0x9511, 0xffff, 0, + "Oxford Semiconductor OX9160/OX16PCI954 UARTs (function 1)", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x1415, 0x9521, 0xffff, 0, + "Oxford Semiconductor OX16PCI952 UARTs", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x14d2, 0x8020, 0xffff, 0, + "VScom PCI-200L", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x14, 4, 0, + }, + + { 0x14d2, 0x8028, 0xffff, 0, + "VScom 200Li", + DEFAULT_RCLK, + PUC_PORT_2S, 0x20, 0, 8, }, /* - * Boca Research Turbo Serial 654 (4 serial port) card. - * Appears to be the same as Chase Research PLC PCI-FAST4 - * and Perle PCI-FAST4 Multi-Port serial cards. + * VScom (Titan?) PCI-800L. More modern variant of the + * PCI-800. Uses 6 discrete 16550 UARTs, plus another + * two of them obviously implemented as macro cells in + * the ASIC. This causes the weird port access pattern + * below, where two of the IO port ranges each access + * one of the ASIC UARTs, and a block of IO addresses + * access the external UARTs. */ - { "Boca Research Turbo Serial 654", - { 0x10b5, 0x9050, 0x12e0, 0x0031 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 4 }, - }, + { 0x14d2, 0x8080, 0xffff, 0, + "Titan VScom PCI-800L", + DEFAULT_RCLK * 8, + PUC_PORT_8S, 0x14, -1, -1, + .config_function = puc_config_titan }, /* - * Boca Research Turbo Serial 658 (8 serial port) card. - * Appears to be the same as Chase Research PLC PCI-FAST8 - * and Perle PCI-FAST8 Multi-Port serial cards. + * VScom PCI-800H. Uses 8 16950 UART, behind a PCI chips that offers + * 4 com port on PCI device 0 and 4 on PCI device 1. PCI device 0 has + * device ID 3 and PCI device 1 device ID 4. */ - { "Boca Research Turbo Serial 658", - { 0x10b5, 0x9050, 0x12e0, 0x0021 }, - { 0xffff, 0xffff, 0xffff, 0xffff }, - { - { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x08, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x10, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x18, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x20, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x28, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x30, COM_FREQ * 4 }, - { PUC_PORT_TYPE_COM, 0x18, 0x38, COM_FREQ * 4 }, - }, - }, - - { "Dell RAC III Virtual UART", - { 0x1028, 0x0008, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ * 128 }, - }, - }, - - { "Dell RAC IV/ERA Virtual UART", - { 0x1028, 0x0012, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x14, 0x00, DEFAULT_RCLK * 128 }, - }, - }, - { /* "VScom 200Li" 00=14D2 02=8028 uart@20 uart@+8 */ - "VScom 200Li", - { 0x14d2, 0x8028, 0, 0 }, - { 0xffff, 0xffff, 0, 0 }, - { - { PUC_PORT_TYPE_COM, 0x20, 0x00, DEFAULT_RCLK }, - { PUC_PORT_TYPE_COM, 0x20, 0x08, DEFAULT_RCLK }, - }, + { 0x14d2, 0xa003, 0xffff, 0, + "Titan PCI-800H", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x10, 0, 8, + }, + { 0x14d2, 0xa004, 0xffff, 0, + "Titan PCI-800H", + DEFAULT_RCLK * 8, + PUC_PORT_4S, 0x10, 0, 8, + }, + + { 0x14d2, 0xa005, 0xffff, 0, + "Titan PCI-200H", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x10, 0, 8, + }, + + { 0x14d2, 0xe020, 0xffff, 0, + "Titan VScom PCI-200HV2", + DEFAULT_RCLK * 8, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x14db, 0x2130, 0xffff, 0, + "Avlab Technology, PCI IO 2S", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 4, 0, + }, + + { 0x14db, 0x2150, 0xffff, 0, + "Avlab Low Profile PCI 4 Serial", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 4, 0, }, - { 0 } + { 0x1592, 0x0781, 0xffff, 0, + "Syba Tech Ltd. PCI-4S2P-550-ECP", + DEFAULT_RCLK, + PUC_PORT_4S1P, 0x10, 0, -1, + .config_function = puc_config_syba + }, + + { 0x6666, 0x0001, 0xffff, 0, + "Decision Computer Inc, PCCOM 4-port serial", + DEFAULT_RCLK, + PUC_PORT_4S, 0x1c, 0, 8, + }, + + { 0x6666, 0x0004, 0xffff, 0, + "PCCOM dual port RS232/422/485", + DEFAULT_RCLK, + PUC_PORT_2S, 0x1c, 0, 8, + }, + + { 0x9710, 0x9815, 0xffff, 0, + "NetMos NM9815 Dual 1284 Printer port", + 0, + PUC_PORT_2P, 0x10, 8, 0, + }, + + { 0x9710, 0x9835, 0xffff, 0, + "NetMos NM9835 Dual UART and 1284 Printer port", + DEFAULT_RCLK, + PUC_PORT_2S1P, 0x10, 4, 0, + }, + + { 0x9710, 0x9845, 0x1000, 0x0006, + "NetMos NM9845 6 Port UART", + DEFAULT_RCLK, + PUC_PORT_6S, 0x10, 4, 0, + }, + + { 0x9710, 0x9845, 0xffff, 0, + "NetMos NM9845 Quad UART and 1284 Printer port", + DEFAULT_RCLK, + PUC_PORT_4S1P, 0x10, 4, 0, + }, + + { 0xb00c, 0x021c, 0xffff, 0, + "IC Book Labs Gunboat x4 Lite", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xb00c, 0x031c, 0xffff, 0, + "IC Book Labs Gunboat x4 Pro", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xb00c, 0x041c, 0xffff, 0, + "IC Book Labs Ironclad x8 Lite", + DEFAULT_RCLK, + PUC_PORT_8S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xb00c, 0x051c, 0xffff, 0, + "IC Book Labs Ironclad x8 Pro", + DEFAULT_RCLK, + PUC_PORT_8S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xb00c, 0x081c, 0xffff, 0, + "IC Book Labs Dreadnought x16 Pro", + DEFAULT_RCLK * 8, + PUC_PORT_16S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xb00c, 0x091c, 0xffff, 0, + "IC Book Labs Dreadnought x16 Lite", + DEFAULT_RCLK, + PUC_PORT_16S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xb00c, 0x0a1c, 0xffff, 0, + "IC Book Labs Gunboat x2 Low Profile", + DEFAULT_RCLK, + PUC_PORT_2S, 0x10, 0, 8, + }, + + { 0xb00c, 0x0b1c, 0xffff, 0, + "IC Book Labs Gunboat x4 Low Profile", + DEFAULT_RCLK, + PUC_PORT_4S, 0x10, 0, 8, + .config_function = puc_config_icbook + }, + + { 0xffff, 0, 0xffff, 0, NULL, 0 } }; + +static int +puc_config_amc(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + switch (cmd) { + case PUC_CFG_GET_OFS: + *res = 8 * (port & 1); + return (0); + case PUC_CFG_GET_RID: + *res = 0x14 + (port >> 1) * 4; + return (0); + default: + break; + } + return (ENXIO); +} + +static int +puc_config_cronyx(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + if (cmd == PUC_CFG_GET_OFS) { + *res = port * 0x200; + return (0); + } + return (ENXIO); +} + +static int +puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + const struct puc_cfg *cfg = sc->sc_cfg; + + if (cmd == PUC_CFG_GET_OFS) { + if (cfg->subdevice == 0x1282) /* Everest SP */ + port <<= 1; + else if (cfg->subdevice == 0x104b) /* Maestro SP2 */ + port = (port == 3) ? 4 : port; + *res = port * 8 + ((port > 2) ? 0x18 : 0); + return (0); + } + return (ENXIO); +} + +static int +puc_config_icbook(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + if (cmd == PUC_CFG_GET_ILR) { + *res = PUC_ILR_DIGI; + return (0); + } + return (ENXIO); +} + +static int +puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + const struct puc_cfg *cfg = sc->sc_cfg; + struct puc_bar *bar; + uint8_t v0, v1; + + switch (cmd) { + case PUC_CFG_SETUP: + /* + * Check if the scratchpad register is enabled or if the + * interrupt status and options registers are active. + */ + bar = puc_get_bar(sc, cfg->rid); + if (bar == NULL) + return (ENXIO); + /* Set DLAB in the LCR register of UART 0. */ + bus_write_1(bar->b_res, 3, 0x80); + /* Write 0 to the SPR register of UART 0. */ + bus_write_1(bar->b_res, 7, 0); + /* Read back the contents of the SPR register of UART 0. */ + v0 = bus_read_1(bar->b_res, 7); + /* Write a specific value to the SPR register of UART 0. */ + bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock); + /* Read back the contents of the SPR register of UART 0. */ + v1 = bus_read_1(bar->b_res, 7); + /* Clear DLAB in the LCR register of UART 0. */ + bus_write_1(bar->b_res, 3, 0); + /* Save the two values read-back from the SPR register. */ + sc->sc_cfg_data = (v0 << 8) | v1; + if (v0 == 0 && v1 == 0x80 + -cfg->clock) { + /* + * The SPR register echoed the two values written + * by us. This means that the SPAD jumper is set. + */ + device_printf(sc->sc_dev, "warning: extra features " + "not usable -- SPAD compatibility enabled\n"); + return (0); + } + if (v0 != 0) { + /* + * The first value doesn't match. This can only mean + * that the SPAD jumper is not set and that a non- + * standard fixed clock multiplier jumper is set. + */ + if (bootverbose) + device_printf(sc->sc_dev, "fixed clock rate " + "multiplier of %d\n", 1 << v0); + if (v0 < -cfg->clock) + device_printf(sc->sc_dev, "warning: " + "suboptimal fixed clock rate multiplier " + "setting\n"); + return (0); + } + /* + * The first value matched, but the second didn't. We know + * that the SPAD jumper is not set. We also know that the + * clock rate multiplier is software controlled *and* that + * we just programmed it to the maximum allowed. + */ + if (bootverbose) + device_printf(sc->sc_dev, "clock rate multiplier of " + "%d selected\n", 1 << -cfg->clock); + return (0); + case PUC_CFG_GET_CLOCK: + v0 = (sc->sc_cfg_data >> 8) & 0xff; + v1 = sc->sc_cfg_data & 0xff; + if (v0 == 0 && v1 == 0x80 + -cfg->clock) { + /* + * XXX With the SPAD jumper applied, there's no + * easy way of knowing if there's also a clock + * rate multiplier jumper installed. Let's hope + * not... + */ + *res = DEFAULT_RCLK; + } else if (v0 == 0) { + /* + * No clock rate multiplier jumper installed, + * so we programmed the board with the maximum + * multiplier allowed as given to us in the + * clock field of the config record (negated). + */ + *res = DEFAULT_RCLK << -cfg->clock; + } else + *res = DEFAULT_RCLK << v0; + return (0); + case PUC_CFG_GET_ILR: + v0 = (sc->sc_cfg_data >> 8) & 0xff; + v1 = sc->sc_cfg_data & 0xff; + *res = (v0 == 0 && v1 == 0x80 + -cfg->clock) + ? PUC_ILR_NONE : PUC_ILR_QUATECH; + return (0); + default: + break; + } + return (ENXIO); +} + +static int +puc_config_syba(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + static int base[] = { 0x251, 0x3f0, 0 }; + const struct puc_cfg *cfg = sc->sc_cfg; + struct puc_bar *bar; + int efir, idx, ofs; + uint8_t v; + + switch (cmd) { + case PUC_CFG_SETUP: + bar = puc_get_bar(sc, cfg->rid); + if (bar == NULL) + return (ENXIO); + + /* configure both W83877TFs */ + bus_write_1(bar->b_res, 0x250, 0x89); + bus_write_1(bar->b_res, 0x3f0, 0x87); + bus_write_1(bar->b_res, 0x3f0, 0x87); + idx = 0; + while (base[idx] != 0) { + efir = base[idx]; + bus_write_1(bar->b_res, efir, 0x09); + v = bus_read_1(bar->b_res, efir + 1); + if ((v & 0x0f) != 0x0c) + return (ENXIO); + bus_write_1(bar->b_res, efir, 0x16); + v = bus_read_1(bar->b_res, efir + 1); + bus_write_1(bar->b_res, efir, 0x16); + bus_write_1(bar->b_res, efir + 1, v | 0x04); + bus_write_1(bar->b_res, efir, 0x16); + bus_write_1(bar->b_res, efir + 1, v & ~0x04); + ofs = base[idx] & 0x300; + bus_write_1(bar->b_res, efir, 0x23); + bus_write_1(bar->b_res, efir + 1, (ofs + 0x78) >> 2); + bus_write_1(bar->b_res, efir, 0x24); + bus_write_1(bar->b_res, efir + 1, (ofs + 0xf8) >> 2); + bus_write_1(bar->b_res, efir, 0x25); + bus_write_1(bar->b_res, efir + 1, (ofs + 0xe8) >> 2); + bus_write_1(bar->b_res, efir, 0x17); + bus_write_1(bar->b_res, efir + 1, 0x03); + bus_write_1(bar->b_res, efir, 0x28); + bus_write_1(bar->b_res, efir + 1, 0x43); + idx++; + } + bus_write_1(bar->b_res, 0x250, 0xaa); + bus_write_1(bar->b_res, 0x3f0, 0xaa); + return (0); + case PUC_CFG_GET_OFS: + switch (port) { + case 0: + *res = 0x2f8; + return (0); + case 1: + *res = 0x2e8; + return (0); + case 2: + *res = 0x3f8; + return (0); + case 3: + *res = 0x3e8; + return (0); + case 4: + *res = 0x278; + return (0); + } + break; + default: + break; + } + return (ENXIO); +} + +static int +puc_config_siig(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + const struct puc_cfg *cfg = sc->sc_cfg; + + switch (cmd) { + case PUC_CFG_GET_OFS: + if (cfg->ports == PUC_PORT_8S) { + *res = (port > 4) ? 8 * (port - 4) : 0; + return (0); + } + break; + case PUC_CFG_GET_RID: + if (cfg->ports == PUC_PORT_8S) { + *res = 0x10 + ((port > 4) ? 0x10 : 4 * port); + return (0); + } + if (cfg->ports == PUC_PORT_2S1P) { + switch (port) { + case 0: *res = 0x10; return (0); + case 1: *res = 0x14; return (0); + case 2: *res = 0x1c; return (0); + } + } + break; + default: + break; + } + return (ENXIO); +} + +static int +puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + static uint16_t dual[] = { + 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085, + 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, + 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, + 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079, + 0xD079, 0 + }; + static uint16_t quad[] = { + 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, + 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, + 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056, + 0xB157, 0 + }; + static uint16_t octa[] = { + 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, + 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 + }; + static struct { + int ports; + uint16_t *ids; + } subdevs[] = { + { 2, dual }, + { 4, quad }, + { 8, octa }, + { 0, NULL } + }; + static char desc[64]; + int dev, id; + uint16_t subdev; + + switch (cmd) { + case PUC_CFG_GET_DESC: + snprintf(desc, sizeof(desc), + "Timedia technology %d Port Serial", (int)sc->sc_cfg_data); + *res = (intptr_t)desc; + return (0); + case PUC_CFG_GET_NPORTS: + subdev = pci_get_subdevice(sc->sc_dev); + dev = 0; + while (subdevs[dev].ports != 0) { + id = 0; + while (subdevs[dev].ids[id] != 0) { + if (subdev == subdevs[dev].ids[id]) { + sc->sc_cfg_data = subdevs[dev].ports; + *res = sc->sc_cfg_data; + return (0); + } + id++; + } + dev++; + } + return (ENXIO); + case PUC_CFG_GET_OFS: + *res = (port == 1 || port == 3) ? 8 : 0; + return (0); + case PUC_CFG_GET_RID: + *res = (port > 3) ? port - 2 : port >> 1; + return (0); + case PUC_CFG_GET_TYPE: + *res = PUC_TYPE_SERIAL; + return (0); + default: + break; + } + return (ENXIO); +} + +static int +puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, + intptr_t *res) +{ + switch (cmd) { + case PUC_CFG_GET_OFS: + *res = (port < 3) ? 0 : (port - 2) << 3; + return (0); + case PUC_CFG_GET_RID: + *res = 0x14 + ((port >= 2) ? 0x0c : port << 2); + return (0); + default: + break; + } + return (ENXIO); +} diff --git a/sys/dev/puc/pucvar.h b/sys/dev/puc/pucvar.h deleted file mode 100644 index bf9bb7f..0000000 --- a/sys/dev/puc/pucvar.h +++ /dev/null @@ -1,165 +0,0 @@ -/* $NetBSD: pucvar.h,v 1.2 1999/02/06 06:29:54 cgd Exp $ */ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2002 JF Hay. All rights reserved. - * Copyright (c) 2000 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. - */ - -/*- - * 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 16 - -struct puc_softc; -typedef int puc_init_t(struct puc_softc *sc); -struct puc_device_description { - const char *name; - uint32_t rval[4]; - uint32_t rmask[4]; - struct { - int type; - int bar; - int offset; - u_int serialfreq; - u_int flags; - int regshft; - } ports[PUC_MAX_PORTS]; - uint32_t ilr_type; - uint32_t ilr_offset[2]; - puc_init_t *init; -}; - -#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_TYPE_UART 3 - -/* UART subtypes. */ -#define PUC_PORT_SUBTYPE_MASK (~0xff) -#define PUC_PORT_UART_NS8250 (0<<8) -#define PUC_PORT_UART_SAB82532 (1<<8) -#define PUC_PORT_UART_Z8530 (2<<8) - -/* Interrupt Latch Register (ILR) types */ -#define PUC_ILR_TYPE_NONE 0 -#define PUC_ILR_TYPE_DIGI 1 - -#define PUC_FLAGS_MEMORY 0x0001 /* Use memory mapped I/O. */ -#define PUC_FLAGS_ALTRES 0x0002 /* Use alternate I/O type. */ - -#define PUC_PORT_VALID(desc, port) \ - ((port) < PUC_MAX_PORTS && (desc).ports[(port)].type != PUC_PORT_TYPE_NONE) - -#define PUC_MAX_BAR 6 - -enum puc_device_ivars { - PUC_IVAR_FREQ, - PUC_IVAR_SUBTYPE, - PUC_IVAR_REGSHFT, - PUC_IVAR_PORT -}; - -#ifdef PUC_ENTRAILS -int puc_attach(device_t dev, const struct puc_device_description *desc); -extern devclass_t puc_devclass; -struct resource *puc_alloc_resource(device_t, device_t, int, int *, - u_long, u_long, u_long, u_int); -int puc_release_resource(device_t, device_t, int, int, struct resource *); -int puc_get_resource(device_t, device_t, int, int, u_long *, u_long *); -int puc_read_ivar(device_t, device_t, int, uintptr_t *); -int puc_setup_intr(device_t, device_t, struct resource *, int, - void (*)(void *), void *, void **); -int puc_teardown_intr(device_t, device_t, struct resource *, - void *); - -struct puc_softc { - struct puc_device_description sc_desc; - - /* card-global dynamic data */ - int fastintr; - int barmuxed; - int irqrid; - struct resource *irqres; - void *intr_cookie; - int ilr_enabled; - bus_space_tag_t ilr_st; - bus_space_handle_t ilr_sh; - - struct { - int used; - int bar; - int type; /* SYS_RES_IOPORT or SYS_RES_MEMORY. */ - struct resource *res; - } sc_bar_mappings[PUC_MAX_BAR]; - - /* per-port dynamic data */ - struct { - struct device *dev; - /* filled in by bus_setup_intr() */ - void (*ihand)(void *); - void *ihandarg; - } sc_ports[PUC_MAX_PORTS]; -}; - -#endif /* PUC_ENTRAILS */ diff --git a/sys/dev/sio/sio_puc.c b/sys/dev/sio/sio_puc.c index dd80e68..0ae0e7d 100644 --- a/sys/dev/sio/sio_puc.c +++ b/sys/dev/sio/sio_puc.c @@ -39,8 +39,8 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <sys/timepps.h> -#include <dev/pci/pcivar.h> -#include <dev/puc/pucvar.h> +#include <dev/puc/puc_bus.h> + #include <dev/sio/siovar.h> #include <dev/sio/sioreg.h> @@ -63,30 +63,37 @@ static driver_t sio_puc_driver = { }; static int -sio_puc_attach(dev) - device_t dev; +sio_puc_attach(device_t dev) { uintptr_t rclk; - if (BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_FREQ, + if (BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_CLOCK, &rclk) != 0) rclk = DEFAULT_RCLK; return (sioattach(dev, 0, rclk)); } static int -sio_puc_probe(dev) - device_t dev; +sio_puc_probe(device_t dev) { - uintptr_t rclk; + device_t parent; + uintptr_t rclk, type; + int error; - if (BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_FREQ, - &rclk) != 0) + parent = device_get_parent(dev); + + if (BUS_READ_IVAR(parent, dev, PUC_IVAR_TYPE, &type)) + return (ENXIO); + if (type != PUC_TYPE_SERIAL) + return (ENXIO); + + if (BUS_READ_IVAR(parent, dev, PUC_IVAR_CLOCK, &rclk)) rclk = DEFAULT_RCLK; #ifdef PC98 SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550)); #endif - return (sioprobe(dev, 0, rclk, 1)); + error = sioprobe(dev, 0, rclk, 1); + return ((error > 0) ? error : BUS_PROBE_LOW_PRIORITY); } DRIVER_MODULE(sio, puc, sio_puc_driver, sio_devclass, 0, 0); diff --git a/sys/dev/uart/uart_bus_puc.c b/sys/dev/uart/uart_bus_puc.c index 7277df9..dff35b3 100644 --- a/sys/dev/uart/uart_bus_puc.c +++ b/sys/dev/uart/uart_bus_puc.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2006 Marcel Moolenaar. All rights reserved. * Copyright (c) 2002 JF Hay. All rights reserved. * Copyright (c) 2001 M. Warner Losh. All rights reserved. * @@ -32,12 +33,12 @@ __FBSDID("$FreeBSD$"); #include <sys/conf.h> #include <sys/kernel.h> #include <sys/module.h> + #include <machine/bus.h> #include <sys/rman.h> #include <machine/resource.h> -#include <dev/pci/pcivar.h> -#include <dev/puc/pucvar.h> +#include <dev/puc/puc_bus.h> #include <dev/uart/uart.h> #include <dev/uart/uart_bus.h> @@ -49,6 +50,9 @@ static device_method_t uart_puc_methods[] = { DEVMETHOD(device_probe, uart_puc_probe), DEVMETHOD(device_attach, uart_bus_attach), DEVMETHOD(device_detach, uart_bus_detach), + /* Serdev interface */ + DEVMETHOD(serdev_ihand, uart_bus_ihand), + DEVMETHOD(serdev_ipend, uart_bus_ipend), { 0, 0 } }; @@ -63,37 +67,21 @@ uart_puc_probe(device_t dev) { device_t parent; struct uart_softc *sc; - uintptr_t port, rclk, regshft, type; + uintptr_t rclk, type; parent = device_get_parent(dev); sc = device_get_softc(dev); - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_SUBTYPE, &type)) + if (BUS_READ_IVAR(parent, dev, PUC_IVAR_TYPE, &type)) return (ENXIO); - switch (type) { - case PUC_PORT_UART_NS8250: - sc->sc_class = &uart_ns8250_class; - port = 0; - break; - case PUC_PORT_UART_SAB82532: - sc->sc_class = &uart_sab82532_class; - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_PORT, &port)) - port = 0; - break; - case PUC_PORT_UART_Z8530: - sc->sc_class = &uart_z8530_class; - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_PORT, &port)) - port = 0; - break; - default: + if (type != PUC_TYPE_SERIAL) return (ENXIO); - } - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_FREQ, &rclk)) + sc->sc_class = &uart_ns8250_class; + + if (BUS_READ_IVAR(parent, dev, PUC_IVAR_CLOCK, &rclk)) rclk = 0; - if (BUS_READ_IVAR(parent, dev, PUC_IVAR_REGSHFT, ®shft)) - regshft = 0; - return (uart_bus_probe(dev, regshft, rclk, 0, port)); + return (uart_bus_probe(dev, 0, rclk, 0, 0)); } DRIVER_MODULE(uart, puc, uart_puc_driver, uart_devclass, 0, 0); diff --git a/sys/i386/conf/DEFAULTS b/sys/i386/conf/DEFAULTS index 775233b..ca2497c 100644 --- a/sys/i386/conf/DEFAULTS +++ b/sys/i386/conf/DEFAULTS @@ -14,5 +14,3 @@ device npx # Pseudo devices. device mem # Memory and kernel memory devices device io # I/O device - -options PUC_FASTINTR diff --git a/sys/ia64/conf/DEFAULTS b/sys/ia64/conf/DEFAULTS index e4fe155..082989c 100644 --- a/sys/ia64/conf/DEFAULTS +++ b/sys/ia64/conf/DEFAULTS @@ -10,5 +10,3 @@ device acpi # ACPI support # Pseudo devices. device mem # Memory and kernel memory devices - -options PUC_FASTINTR diff --git a/sys/modules/puc/Makefile b/sys/modules/puc/Makefile index b011db5..2b0fbfc 100644 --- a/sys/modules/puc/Makefile +++ b/sys/modules/puc/Makefile @@ -2,9 +2,13 @@ # $FreeBSD$ .PATH: ${.CURDIR}/../../dev/puc + KMOD= puc -SRCS= bus_if.h device_if.h pci_if.h card_if.h \ - puc.c puc_pci.c puc_pccard.c pucdata.c \ - opt_puc.h +SRCS= puc.c puc_cfg.c puc_pci.c puc_pccard.c pucdata.c +SRCS+= bus_if.h device_if.h serdev_if.c serdev_if.h \ + card_if.h pci_if.h + +MFILES= kern/bus_if.m kern/device_if.m kern/serdev_if.m \ + dev/pccard/card_if.m dev/pci/pci_if.m .include <bsd.kmod.mk> diff --git a/sys/modules/sio/Makefile b/sys/modules/sio/Makefile index 59386e6..dc683ba 100644 --- a/sys/modules/sio/Makefile +++ b/sys/modules/sio/Makefile @@ -6,7 +6,7 @@ .PATH: ${.CURDIR}/../../dev/sio KMOD= sio -SRCS= bus_if.h card_if.h device_if.h isa_if.h pci_if.h \ +SRCS= bus_if.h card_if.h device_if.h isa_if.h pci_if.h serdev_if.h \ opt_comconsole.h opt_compat.h opt_gdb.h opt_kdb.h opt_sio.h \ sio.c sio_pccard.c sio_pci.c sio_puc.c pccarddevs.h .if ${MACHINE} == "pc98" diff --git a/sys/pc98/conf/DEFAULTS b/sys/pc98/conf/DEFAULTS index d04a633..37af803 100644 --- a/sys/pc98/conf/DEFAULTS +++ b/sys/pc98/conf/DEFAULTS @@ -15,5 +15,3 @@ device npx # Pseudo devices. device mem # Memory and kernel memory devices device io # I/O device - -options PUC_FASTINTR |