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:
Marcel Moolenaar 2006-04-28 21:21:53 +00:00
parent f088002825
commit 64220a7e28
25 changed files with 2057 additions and 2262 deletions

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));
} }

File diff suppressed because it is too large Load Diff

94
sys/dev/puc/puc_bfe.h Normal file
View 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
View 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
View 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
View 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_ */

View File

@ -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);

View File

@ -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),
}; };

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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, &regshft)) 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);

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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"

View File

@ -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