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.
|
||||
device mem # Memory and kernel memory devices
|
||||
|
||||
options PUC_FASTINTR
|
||||
|
@ -11,5 +11,3 @@ device isa
|
||||
# Pseudo devices.
|
||||
device mem # Memory and kernel memory devices
|
||||
device io # I/O device
|
||||
|
||||
options PUC_FASTINTR
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
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>
|
||||
__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(device_attach, puc_bfe_attach),
|
||||
DEVMETHOD(device_detach, puc_bfe_detach),
|
||||
|
||||
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_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),
|
||||
};
|
||||
|
@ -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>
|
||||
#include <dev/puc/puc_bfe.h>
|
||||
#include <dev/puc/puc_cfg.h>
|
||||
|
||||
extern const struct puc_device_description puc_devices[];
|
||||
|
||||
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)
|
||||
static const struct puc_cfg *
|
||||
puc_pci_match(device_t dev, const struct puc_cfg *desc)
|
||||
{
|
||||
int i;
|
||||
uint16_t device, subdev, subven, vendor;
|
||||
|
||||
#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);
|
||||
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(device_attach, puc_bfe_attach),
|
||||
DEVMETHOD(device_detach, puc_bfe_detach),
|
||||
|
||||
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_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
|
||||
|
||||
|
@ -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 <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);
|
||||
|
@ -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);
|
||||
|
@ -14,5 +14,3 @@ device npx
|
||||
# Pseudo devices.
|
||||
device mem # Memory and kernel memory devices
|
||||
device io # I/O device
|
||||
|
||||
options PUC_FASTINTR
|
||||
|
@ -10,5 +10,3 @@ device acpi # ACPI support
|
||||
|
||||
# Pseudo devices.
|
||||
device mem # Memory and kernel memory devices
|
||||
|
||||
options PUC_FASTINTR
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -15,5 +15,3 @@ device npx
|
||||
# Pseudo devices.
|
||||
device mem # Memory and kernel memory devices
|
||||
device io # I/O device
|
||||
|
||||
options PUC_FASTINTR
|
||||
|
Loading…
Reference in New Issue
Block a user