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.
This commit is contained in:
parent
f088002825
commit
64220a7e28
@ -7,5 +7,3 @@ machine alpha
|
|||||||
|
|
||||||
# Pseudo devices.
|
# Pseudo devices.
|
||||||
device mem # Memory and kernel memory devices
|
device mem # Memory and kernel memory devices
|
||||||
|
|
||||||
options PUC_FASTINTR
|
|
||||||
|
@ -11,5 +11,3 @@ device isa
|
|||||||
# Pseudo devices.
|
# Pseudo devices.
|
||||||
device mem # Memory and kernel memory devices
|
device mem # Memory and kernel memory devices
|
||||||
device io # I/O device
|
device io # I/O device
|
||||||
|
|
||||||
options PUC_FASTINTR
|
|
||||||
|
@ -1689,15 +1689,8 @@ options ALT_BREAK_TO_DEBUGGER
|
|||||||
device scc
|
device scc
|
||||||
|
|
||||||
# PCI Universal Communications driver
|
# PCI Universal Communications driver
|
||||||
# Supports various single and multi port PCI serial cards. Maybe later
|
# Supports various multi port PCI I/O cards.
|
||||||
# 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.
|
|
||||||
device puc
|
device puc
|
||||||
options PUC_FASTINTR
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Network interfaces:
|
# Network interfaces:
|
||||||
|
@ -805,10 +805,9 @@ dev/pst/pst-iop.c optional pst
|
|||||||
dev/pst/pst-pci.c optional pst pci
|
dev/pst/pst-pci.c optional pst pci
|
||||||
dev/pst/pst-raid.c optional pst
|
dev/pst/pst-raid.c optional pst
|
||||||
dev/puc/puc.c optional puc
|
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_pccard.c optional puc pccard
|
||||||
dev/puc/puc_pci.c optional puc pci
|
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/puc/pucdata.c optional puc pci
|
||||||
dev/ral/rt2560.c optional ral
|
dev/ral/rt2560.c optional ral
|
||||||
dev/ral/rt2661.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/si/si_pci.c optional si pci
|
||||||
dev/sio/sio_pccard.c optional sio pccard
|
dev/sio/sio_pccard.c optional sio pccard
|
||||||
dev/sio/sio_pci.c optional sio pci
|
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/sk/if_sk.c optional sk pci
|
||||||
dev/smbus/smb.c optional smb
|
dev/smbus/smb.c optional smb
|
||||||
dev/smbus/smbconf.c optional smbus
|
dev/smbus/smbconf.c optional smbus
|
||||||
@ -1321,7 +1320,7 @@ kern/md4c.c optional netsmb
|
|||||||
kern/md5c.c standard
|
kern/md5c.c standard
|
||||||
kern/sched_4bsd.c optional sched_4bsd
|
kern/sched_4bsd.c optional sched_4bsd
|
||||||
kern/sched_ule.c optional sched_ule
|
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_autoconf.c standard
|
||||||
kern/subr_blist.c standard
|
kern/subr_blist.c standard
|
||||||
kern/subr_bus.c standard
|
kern/subr_bus.c standard
|
||||||
|
@ -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/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/ac97_if.m dev/sound/pcm/channel_if.m \
|
||||||
dev/sound/pcm/feeder_if.m dev/sound/pcm/mixer_if.m \
|
dev/sound/pcm/feeder_if.m dev/sound/pcm/mixer_if.m \
|
||||||
dev/usb/usb_if.m isa/isa_if.m \
|
dev/usb/usb_if.m isa/isa_if.m kern/bus_if.m kern/cpufreq_if.m \
|
||||||
kern/bus_if.m kern/cpufreq_if.m kern/device_if.m \
|
kern/device_if.m kern/serdev_if.m \
|
||||||
libkern/iconv_converter_if.m opencrypto/crypto_if.m \
|
libkern/iconv_converter_if.m opencrypto/crypto_if.m \
|
||||||
pc98/pc98/canbus_if.m pci/agp_if.m
|
pc98/pc98/canbus_if.m pci/agp_if.m
|
||||||
|
|
||||||
|
@ -125,7 +125,6 @@ PPC_DEBUG opt_ppc.h
|
|||||||
PPC_PROBE_CHIPSET opt_ppc.h
|
PPC_PROBE_CHIPSET opt_ppc.h
|
||||||
PPS_SYNC opt_ntp.h
|
PPS_SYNC opt_ntp.h
|
||||||
PREEMPTION opt_sched.h
|
PREEMPTION opt_sched.h
|
||||||
PUC_FASTINTR opt_puc.h
|
|
||||||
QUOTA
|
QUOTA
|
||||||
SCHED_4BSD opt_sched.h
|
SCHED_4BSD opt_sched.h
|
||||||
SCHED_ULE opt_sched.h
|
SCHED_ULE opt_sched.h
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
|
* Copyright (c) 2006 Marcel Moolenaar
|
||||||
* Copyright (c) 1997-2000 Nicolas Souchu
|
* Copyright (c) 1997-2000 Nicolas Souchu
|
||||||
* Copyright (c) 2001 Alcove - Nicolas Souchu
|
* Copyright (c) 2001 Alcove - Nicolas Souchu
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -35,6 +36,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
|
|
||||||
|
#include <dev/puc/puc_bus.h>
|
||||||
|
|
||||||
#include <dev/ppbus/ppbconf.h>
|
#include <dev/ppbus/ppbconf.h>
|
||||||
#include <dev/ppbus/ppb_msq.h>
|
#include <dev/ppbus/ppb_msq.h>
|
||||||
#include <dev/ppc/ppcvar.h>
|
#include <dev/ppc/ppcvar.h>
|
||||||
@ -48,6 +51,7 @@ static device_method_t ppc_puc_methods[] = {
|
|||||||
/* device interface */
|
/* device interface */
|
||||||
DEVMETHOD(device_probe, ppc_puc_probe),
|
DEVMETHOD(device_probe, ppc_puc_probe),
|
||||||
DEVMETHOD(device_attach, ppc_attach),
|
DEVMETHOD(device_attach, ppc_attach),
|
||||||
|
DEVMETHOD(device_detach, ppc_detach),
|
||||||
|
|
||||||
/* bus interface */
|
/* bus interface */
|
||||||
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
|
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
|
||||||
@ -76,6 +80,15 @@ static driver_t ppc_puc_driver = {
|
|||||||
static int
|
static int
|
||||||
ppc_puc_probe(device_t dev)
|
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");
|
device_set_desc(dev, "Parallel port");
|
||||||
return (ppc_probe(dev, 0));
|
return (ppc_probe(dev, 0));
|
||||||
}
|
}
|
||||||
|
1145
sys/dev/puc/puc.c
1145
sys/dev/puc/puc.c
File diff suppressed because it is too large
Load Diff
94
sys/dev/puc/puc_bfe.h
Normal file
94
sys/dev/puc/puc_bfe.h
Normal file
@ -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_ */
|
42
sys/dev/puc/puc_bus.h
Normal file
42
sys/dev/puc/puc_bus.h
Normal file
@ -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_ */
|
175
sys/dev/puc/puc_cfg.c
Normal file
175
sys/dev/puc/puc_cfg.c
Normal file
@ -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);
|
||||||
|
}
|
88
sys/dev/puc/puc_cfg.h
Normal file
88
sys/dev/puc/puc_cfg.h
Normal file
@ -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_ */
|
@ -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);
|
|
@ -27,8 +27,6 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include "opt_puc.h"
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
@ -41,25 +39,19 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/resource.h>
|
#include <machine/resource.h>
|
||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
|
|
||||||
#define PUC_ENTRAILS 1
|
|
||||||
#include <dev/puc/pucvar.h>
|
|
||||||
|
|
||||||
#include <dev/sio/sioreg.h>
|
|
||||||
#include <dev/pccard/pccardvar.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",
|
"ARGOSY SP320 Dual port serial PCMCIA",
|
||||||
/* http://www.argosy.com.tw/product/sp320.htm */
|
DEFAULT_RCLK,
|
||||||
{ 0, 0, 0, 0 },
|
PUC_PORT_2S, 0, 1, 0,
|
||||||
{ 0, 0, 0, 0 },
|
|
||||||
{
|
|
||||||
{ PUC_PORT_TYPE_COM, 0x0, 0x00, DEFAULT_RCLK, 0x100000 },
|
|
||||||
{ PUC_PORT_TYPE_COM, 0x1, 0x00, DEFAULT_RCLK, 0 },
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
puc_pccard_probe(device_t dev)
|
puc_pccard_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -72,39 +64,31 @@ puc_pccard_probe(device_t dev)
|
|||||||
error = pccard_get_product_str(dev, &product);
|
error = pccard_get_product_str(dev, &product);
|
||||||
if (error)
|
if (error)
|
||||||
return(error);
|
return(error);
|
||||||
if (!strcmp(vendor, "PCMCIA") && !strcmp(product, "RS-COM 2P")) {
|
if (!strcmp(vendor, "PCMCIA") && !strcmp(product, "RS-COM 2P"))
|
||||||
device_set_desc(dev, rscom_devices.name);
|
return (puc_bfe_probe(dev, &puc_pccard_rscom));
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
puc_pccard_attach(device_t dev)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (puc_attach(dev, &rscom_devices));
|
|
||||||
}
|
|
||||||
|
|
||||||
static device_method_t puc_pccard_methods[] = {
|
static device_method_t puc_pccard_methods[] = {
|
||||||
/* Device interface */
|
/* Device interface */
|
||||||
DEVMETHOD(device_probe, puc_pccard_probe),
|
DEVMETHOD(device_probe, puc_pccard_probe),
|
||||||
DEVMETHOD(device_attach, puc_pccard_attach),
|
DEVMETHOD(device_attach, puc_bfe_attach),
|
||||||
|
DEVMETHOD(device_detach, puc_bfe_detach),
|
||||||
|
|
||||||
DEVMETHOD(bus_alloc_resource, puc_alloc_resource),
|
DEVMETHOD(bus_alloc_resource, puc_bus_alloc_resource),
|
||||||
DEVMETHOD(bus_release_resource, puc_release_resource),
|
DEVMETHOD(bus_release_resource, puc_bus_release_resource),
|
||||||
DEVMETHOD(bus_get_resource, puc_get_resource),
|
DEVMETHOD(bus_get_resource, puc_bus_get_resource),
|
||||||
DEVMETHOD(bus_read_ivar, puc_read_ivar),
|
DEVMETHOD(bus_read_ivar, puc_bus_read_ivar),
|
||||||
DEVMETHOD(bus_setup_intr, puc_setup_intr),
|
DEVMETHOD(bus_setup_intr, puc_bus_setup_intr),
|
||||||
DEVMETHOD(bus_teardown_intr, puc_teardown_intr),
|
DEVMETHOD(bus_teardown_intr, puc_bus_teardown_intr),
|
||||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static driver_t puc_pccard_driver = {
|
static driver_t puc_pccard_driver = {
|
||||||
"puc",
|
puc_driver_name,
|
||||||
puc_pccard_methods,
|
puc_pccard_methods,
|
||||||
sizeof(struct puc_softc),
|
sizeof(struct puc_softc),
|
||||||
};
|
};
|
||||||
|
@ -60,8 +60,6 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include "opt_puc.h"
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
@ -77,215 +75,68 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/pci/pcireg.h>
|
#include <dev/pci/pcireg.h>
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/pci/pcivar.h>
|
||||||
|
|
||||||
#define PUC_ENTRAILS 1
|
#include <dev/puc/puc_bfe.h>
|
||||||
#include <dev/puc/pucvar.h>
|
#include <dev/puc/puc_cfg.h>
|
||||||
|
|
||||||
extern const struct puc_device_description puc_devices[];
|
static const struct puc_cfg *
|
||||||
|
puc_pci_match(device_t dev, const struct puc_cfg *desc)
|
||||||
int puc_config_win877(struct puc_softc *);
|
|
||||||
|
|
||||||
static const struct puc_device_description *
|
|
||||||
puc_find_description(uint32_t vend, uint32_t prod, uint32_t svend,
|
|
||||||
uint32_t sprod)
|
|
||||||
{
|
{
|
||||||
int i;
|
uint16_t device, subdev, subven, vendor;
|
||||||
|
|
||||||
#define checkreg(val, index) \
|
vendor = pci_get_vendor(dev);
|
||||||
(((val) & puc_devices[i].rmask[(index)]) == puc_devices[i].rval[(index)])
|
device = pci_get_device(dev);
|
||||||
|
while (desc->vendor != 0xffff &&
|
||||||
for (i = 0; puc_devices[i].name != NULL; i++) {
|
(desc->vendor != vendor || desc->device != device))
|
||||||
if (checkreg(vend, PUC_REG_VEND) &&
|
desc++;
|
||||||
checkreg(prod, PUC_REG_PROD) &&
|
if (desc->vendor == 0xffff)
|
||||||
checkreg(svend, PUC_REG_SVEND) &&
|
return (NULL);
|
||||||
checkreg(sprod, PUC_REG_SPROD))
|
if (desc->subvendor == 0xffff)
|
||||||
return (&puc_devices[i]);
|
return (desc);
|
||||||
}
|
subven = pci_get_subvendor(dev);
|
||||||
|
subdev = pci_get_subdevice(dev);
|
||||||
#undef checkreg
|
while (desc->vendor == vendor && desc->device == device &&
|
||||||
|
(desc->subvendor != subven || desc->subdevice != subdev))
|
||||||
return (NULL);
|
desc++;
|
||||||
|
return ((desc->vendor == vendor && desc->device == device)
|
||||||
|
? desc : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
puc_pci_probe(device_t dev)
|
puc_pci_probe(device_t dev)
|
||||||
{
|
{
|
||||||
uint32_t v1, v2, d1, d2;
|
const struct puc_cfg *desc;
|
||||||
const struct puc_device_description *desc;
|
|
||||||
|
|
||||||
if ((pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) != 0)
|
if ((pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) != 0)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
|
|
||||||
v1 = pci_read_config(dev, PCIR_VENDOR, 2);
|
desc = puc_pci_match(dev, puc_pci_devices);
|
||||||
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);
|
|
||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
device_set_desc(dev, desc->name);
|
return (puc_bfe_probe(dev, desc));
|
||||||
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)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static device_method_t puc_pci_methods[] = {
|
static device_method_t puc_pci_methods[] = {
|
||||||
/* Device interface */
|
/* Device interface */
|
||||||
DEVMETHOD(device_probe, puc_pci_probe),
|
DEVMETHOD(device_probe, puc_pci_probe),
|
||||||
DEVMETHOD(device_attach, puc_pci_attach),
|
DEVMETHOD(device_attach, puc_bfe_attach),
|
||||||
|
DEVMETHOD(device_detach, puc_bfe_detach),
|
||||||
|
|
||||||
DEVMETHOD(bus_alloc_resource, puc_alloc_resource),
|
DEVMETHOD(bus_alloc_resource, puc_bus_alloc_resource),
|
||||||
DEVMETHOD(bus_release_resource, puc_release_resource),
|
DEVMETHOD(bus_release_resource, puc_bus_release_resource),
|
||||||
DEVMETHOD(bus_get_resource, puc_get_resource),
|
DEVMETHOD(bus_get_resource, puc_bus_get_resource),
|
||||||
DEVMETHOD(bus_read_ivar, puc_read_ivar),
|
DEVMETHOD(bus_read_ivar, puc_bus_read_ivar),
|
||||||
DEVMETHOD(bus_setup_intr, puc_setup_intr),
|
DEVMETHOD(bus_setup_intr, puc_bus_setup_intr),
|
||||||
DEVMETHOD(bus_teardown_intr, puc_teardown_intr),
|
DEVMETHOD(bus_teardown_intr, puc_bus_teardown_intr),
|
||||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static driver_t puc_pci_driver = {
|
static driver_t puc_pci_driver = {
|
||||||
"puc",
|
puc_driver_name,
|
||||||
puc_pci_methods,
|
puc_pci_methods,
|
||||||
sizeof(struct puc_softc),
|
sizeof(struct puc_softc),
|
||||||
};
|
};
|
||||||
|
|
||||||
DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0);
|
DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0);
|
||||||
DRIVER_MODULE(puc, cardbus, 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
|
|
||||||
|
|
||||||
|
@ -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);
|
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
|
@ -39,8 +39,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <sys/timepps.h>
|
#include <sys/timepps.h>
|
||||||
|
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/puc/puc_bus.h>
|
||||||
#include <dev/puc/pucvar.h>
|
|
||||||
#include <dev/sio/siovar.h>
|
#include <dev/sio/siovar.h>
|
||||||
#include <dev/sio/sioreg.h>
|
#include <dev/sio/sioreg.h>
|
||||||
|
|
||||||
@ -63,30 +63,37 @@ static driver_t sio_puc_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sio_puc_attach(dev)
|
sio_puc_attach(device_t dev)
|
||||||
device_t dev;
|
|
||||||
{
|
{
|
||||||
uintptr_t rclk;
|
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) != 0)
|
||||||
rclk = DEFAULT_RCLK;
|
rclk = DEFAULT_RCLK;
|
||||||
return (sioattach(dev, 0, rclk));
|
return (sioattach(dev, 0, rclk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sio_puc_probe(dev)
|
sio_puc_probe(device_t dev)
|
||||||
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,
|
parent = device_get_parent(dev);
|
||||||
&rclk) != 0)
|
|
||||||
|
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;
|
rclk = DEFAULT_RCLK;
|
||||||
#ifdef PC98
|
#ifdef PC98
|
||||||
SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550));
|
SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550));
|
||||||
#endif
|
#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);
|
DRIVER_MODULE(sio, puc, sio_puc_driver, sio_devclass, 0, 0);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
|
* Copyright (c) 2006 Marcel Moolenaar. All rights reserved.
|
||||||
* Copyright (c) 2002 JF Hay. All rights reserved.
|
* Copyright (c) 2002 JF Hay. All rights reserved.
|
||||||
* Copyright (c) 2001 M. Warner Losh. All rights reserved.
|
* Copyright (c) 2001 M. Warner Losh. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -32,12 +33,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
#include <machine/resource.h>
|
#include <machine/resource.h>
|
||||||
|
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/puc/puc_bus.h>
|
||||||
#include <dev/puc/pucvar.h>
|
|
||||||
|
|
||||||
#include <dev/uart/uart.h>
|
#include <dev/uart/uart.h>
|
||||||
#include <dev/uart/uart_bus.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_probe, uart_puc_probe),
|
||||||
DEVMETHOD(device_attach, uart_bus_attach),
|
DEVMETHOD(device_attach, uart_bus_attach),
|
||||||
DEVMETHOD(device_detach, uart_bus_detach),
|
DEVMETHOD(device_detach, uart_bus_detach),
|
||||||
|
/* Serdev interface */
|
||||||
|
DEVMETHOD(serdev_ihand, uart_bus_ihand),
|
||||||
|
DEVMETHOD(serdev_ipend, uart_bus_ipend),
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,37 +67,21 @@ uart_puc_probe(device_t dev)
|
|||||||
{
|
{
|
||||||
device_t parent;
|
device_t parent;
|
||||||
struct uart_softc *sc;
|
struct uart_softc *sc;
|
||||||
uintptr_t port, rclk, regshft, type;
|
uintptr_t rclk, type;
|
||||||
|
|
||||||
parent = device_get_parent(dev);
|
parent = device_get_parent(dev);
|
||||||
sc = device_get_softc(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);
|
return (ENXIO);
|
||||||
switch (type) {
|
if (type != PUC_TYPE_SERIAL)
|
||||||
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:
|
|
||||||
return (ENXIO);
|
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;
|
rclk = 0;
|
||||||
if (BUS_READ_IVAR(parent, dev, PUC_IVAR_REGSHFT, ®shft))
|
return (uart_bus_probe(dev, 0, rclk, 0, 0));
|
||||||
regshft = 0;
|
|
||||||
return (uart_bus_probe(dev, regshft, rclk, 0, port));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DRIVER_MODULE(uart, puc, uart_puc_driver, uart_devclass, 0, 0);
|
DRIVER_MODULE(uart, puc, uart_puc_driver, uart_devclass, 0, 0);
|
||||||
|
@ -14,5 +14,3 @@ device npx
|
|||||||
# Pseudo devices.
|
# Pseudo devices.
|
||||||
device mem # Memory and kernel memory devices
|
device mem # Memory and kernel memory devices
|
||||||
device io # I/O device
|
device io # I/O device
|
||||||
|
|
||||||
options PUC_FASTINTR
|
|
||||||
|
@ -10,5 +10,3 @@ device acpi # ACPI support
|
|||||||
|
|
||||||
# Pseudo devices.
|
# Pseudo devices.
|
||||||
device mem # Memory and kernel memory devices
|
device mem # Memory and kernel memory devices
|
||||||
|
|
||||||
options PUC_FASTINTR
|
|
||||||
|
@ -2,9 +2,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/../../dev/puc
|
.PATH: ${.CURDIR}/../../dev/puc
|
||||||
|
|
||||||
KMOD= puc
|
KMOD= puc
|
||||||
SRCS= bus_if.h device_if.h pci_if.h card_if.h \
|
SRCS= puc.c puc_cfg.c puc_pci.c puc_pccard.c pucdata.c
|
||||||
puc.c puc_pci.c puc_pccard.c pucdata.c \
|
SRCS+= bus_if.h device_if.h serdev_if.c serdev_if.h \
|
||||||
opt_puc.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>
|
.include <bsd.kmod.mk>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
.PATH: ${.CURDIR}/../../dev/sio
|
.PATH: ${.CURDIR}/../../dev/sio
|
||||||
|
|
||||||
KMOD= 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 \
|
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
|
sio.c sio_pccard.c sio_pci.c sio_puc.c pccarddevs.h
|
||||||
.if ${MACHINE} == "pc98"
|
.if ${MACHINE} == "pc98"
|
||||||
|
@ -15,5 +15,3 @@ device npx
|
|||||||
# Pseudo devices.
|
# Pseudo devices.
|
||||||
device mem # Memory and kernel memory devices
|
device mem # Memory and kernel memory devices
|
||||||
device io # I/O device
|
device io # I/O device
|
||||||
|
|
||||||
options PUC_FASTINTR
|
|
||||||
|
Loading…
Reference in New Issue
Block a user