summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/tc
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/alpha/tc')
-rw-r--r--sys/arch/alpha/tc/asc.c2175
-rw-r--r--sys/arch/alpha/tc/ascreg.h149
-rw-r--r--sys/arch/alpha/tc/ascvar.h339
-rw-r--r--sys/arch/alpha/tc/ioasic.c262
-rw-r--r--sys/arch/alpha/tc/ioasicreg.h227
-rw-r--r--sys/arch/alpha/tc/mcclock_ioasic.c20
-rw-r--r--sys/arch/alpha/tc/scc.c352
-rw-r--r--sys/arch/alpha/tc/sccreg.h4
-rw-r--r--sys/arch/alpha/tc/sccvar.h15
-rw-r--r--sys/arch/alpha/tc/tc_3000_300.c115
-rw-r--r--sys/arch/alpha/tc/tc_3000_300.h6
-rw-r--r--sys/arch/alpha/tc/tc_3000_500.c97
-rw-r--r--sys/arch/alpha/tc/tc_3000_500.h6
-rw-r--r--sys/arch/alpha/tc/tc_bus_mem.c176
-rw-r--r--sys/arch/alpha/tc/tc_conf.h15
-rw-r--r--sys/arch/alpha/tc/tc_dma.c83
-rw-r--r--sys/arch/alpha/tc/tc_dma_3000_300.c58
-rw-r--r--sys/arch/alpha/tc/tc_dma_3000_300.h41
-rw-r--r--sys/arch/alpha/tc/tc_dma_3000_500.c247
-rw-r--r--sys/arch/alpha/tc/tc_dma_3000_500.h55
-rw-r--r--sys/arch/alpha/tc/tc_machdep.h95
-rw-r--r--sys/arch/alpha/tc/tc_sgmap.c55
-rw-r--r--sys/arch/alpha/tc/tc_sgmap.h60
-rw-r--r--sys/arch/alpha/tc/tcasic.c117
-rw-r--r--sys/arch/alpha/tc/tcds.c424
-rw-r--r--sys/arch/alpha/tc/tcds_dma.c275
-rw-r--r--sys/arch/alpha/tc/tcdsreg.h215
-rw-r--r--sys/arch/alpha/tc/tcdsvar.h112
28 files changed, 1172 insertions, 4623 deletions
diff --git a/sys/arch/alpha/tc/asc.c b/sys/arch/alpha/tc/asc.c
deleted file mode 100644
index 5b8b4418d8c..00000000000
--- a/sys/arch/alpha/tc/asc.c
+++ /dev/null
@@ -1,2175 +0,0 @@
-/* $OpenBSD: asc.c,v 1.3 2002/03/14 01:26:27 millert Exp $ */
-/* $NetBSD: esp.c,v 1.26 1996/12/05 01:39:40 cgd Exp $ */
-
-#ifdef __sparc__
-#define SPARC_DRIVER
-#endif
-
-/*
- * Copyright (c) 1996 Charles M. Hannum. 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 Charles M. Hannum.
- * 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.
- */
-
-/*
- * Copyright (c) 1994 Peter Galbavy
- * Copyright (c) 1995 Paul Kranenburg
- * 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 Peter Galbavy
- * 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.
- */
-
-/*
- * Based on aic6360 by Jarle Greipsland
- *
- * Acknowledgements: Many of the algorithms used in this driver are
- * inspired by the work of Julian Elischer (julian@tfs.com) and
- * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/device.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/queue.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-#include <scsi/scsi_message.h>
-
-#include <machine/cpu.h>
-#ifdef SPARC_DRIVER
-#include <machine/autoconf.h>
-#include <sparc/dev/sbusvar.h>
-#include <sparc/dev/dmareg.h>
-#include <sparc/dev/dmavar.h>
-#include <sparc/dev/espreg.h>
-#include <sparc/dev/espvar.h>
-#else
-#include <machine/autoconf.h> /* badaddr() prototype */
-#include <dev/tc/tcvar.h>
-#include <alpha/tc/tcdsvar.h>
-#include <alpha/tc/ascreg.h>
-#include <alpha/tc/ascvar.h>
-#endif
-
-int esp_debug = 0; /*ESP_SHOWPHASE|ESP_SHOWMISC|ESP_SHOWTRAC|ESP_SHOWCMDS;*/
-
-/*static*/ void espattach(struct device *, struct device *,
- void *);
-/*static*/ int espprint(void *, const char *);
-#ifdef __BROKEN_INDIRECT_CONFIG
-/*static*/ int espmatch(struct device *, void *, void *);
-#else
-/*static*/ int espmatch(struct device *, struct cfdata *,
- void *);
-#endif
-/*static*/ u_int esp_adapter_info(struct esp_softc *);
-/*static*/ void espreadregs(struct esp_softc *);
-/*static*/ void esp_select(struct esp_softc *, struct esp_ecb *);
-/*static*/ int esp_reselect(struct esp_softc *, int);
-/*static*/ void esp_scsi_reset(struct esp_softc *);
-/*static*/ void esp_reset(struct esp_softc *);
-/*static*/ void espinit(struct esp_softc *, int);
-/*static*/ int esp_scsi_cmd(struct scsi_xfer *);
-/*static*/ int esp_poll(struct esp_softc *, struct scsi_xfer *,
- int);
-/*static*/ void esp_sched(struct esp_softc *);
-/*static*/ void esp_done(struct esp_softc *, struct esp_ecb *);
-/*static*/ void esp_msgin(struct esp_softc *);
-/*static*/ void esp_msgout(struct esp_softc *);
-/*static*/ int espintr(struct esp_softc *);
-/*static*/ void esp_timeout(void *arg);
-/*static*/ void esp_abort(struct esp_softc *, struct esp_ecb *);
-/*static*/ void esp_dequeue(struct esp_softc *, struct esp_ecb *);
-void esp_sense(struct esp_softc *, struct esp_ecb *);
-void esp_free_ecb(struct esp_softc *, struct esp_ecb *, int);
-struct esp_ecb *esp_get_ecb(struct esp_softc *, int);
-static inline int esp_stp2cpb(struct esp_softc *, int);
-static inline int esp_cpb2stp(struct esp_softc *, int);
-static inline void esp_setsync(struct esp_softc *, struct esp_tinfo *);
-
-/* Linkup to the rest of the kernel */
-struct cfattach asc_ca = {
- sizeof(struct esp_softc), espmatch, espattach
-};
-
-struct cfdriver asc_cd = {
- NULL, "asc", DV_DULL
-};
-
-struct scsi_adapter esp_switch = {
- esp_scsi_cmd,
- minphys, /* no max at this level; handled by DMA code */
- NULL,
- NULL,
-};
-
-struct scsi_device esp_dev = {
- NULL, /* Use default error handler */
- NULL, /* have a queue, served by this */
- NULL, /* have no async handler */
- NULL, /* Use default 'done' routine */
-};
-
-/*
- * XXX should go when new generic scsiprint finds its way here
- */
-int
-espprint(aux, name)
- void *aux;
- const char *name;
-{
- if (name != NULL)
- printf("scsibus at %s", name);
- return UNCONF;
-}
-
-int
-#ifdef __BROKEN_INDIRECT_CONFIG
-espmatch(parent, vcf, aux)
-#else
-espmatch(parent, cf, aux)
-#endif
- struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *vcf;
-#else
- struct cfdata *cf;
-#endif
- void *aux;
-{
-#ifdef SPARC_DRIVER
-#ifdef __BROKEN_INDIRECT_CONFIG
- struct cfdata *cf = vcf;
-#endif
- register struct confargs *ca = aux;
- register struct romaux *ra = &ca->ca_ra;
-
- if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
- return (0);
- if (ca->ca_bustype == BUS_SBUS)
- return (1);
- ra->ra_len = NBPG;
- return (probeget(ra->ra_vaddr, 1) != -1);
-#else
- struct tcdsdev_attach_args *tcdsdev = aux;
-
- if (strncmp(tcdsdev->tcdsda_modname, "PMAZ-AA ", TC_ROM_LLEN))
- return (0);
- return (!tc_badaddr(tcdsdev->tcdsda_addr));
-#endif
-}
-
-/*
- * Attach this instance, and then all the sub-devices
- */
-void
-espattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
-#ifdef SPARC_DRIVER
- register struct confargs *ca = aux;
-#else
- register struct tcdsdev_attach_args *tcdsdev = aux;
-#endif
- struct esp_softc *sc = (void *)self;
-#ifdef SPARC_DRIVER
- struct bootpath *bp;
- int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
-#endif
-
-#ifdef SPARC_DRIVER
- /*
- * Make sure things are sane. I don't know if this is ever
- * necessary, but it seem to be in all of Torek's code.
- */
- if (ca->ca_ra.ra_nintr != 1) {
- printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
- return;
- }
-
- sc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
- printf(" pri %d", sc->sc_pri);
-
- /*
- * Map my registers in, if they aren't already in virtual
- * address space.
- */
- if (ca->ca_ra.ra_vaddr)
- sc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
- else {
- sc->sc_reg = (volatile u_char *)
- mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len, ca->ca_bustype);
- }
-#else
- sc->sc_reg = (volatile u_int32_t *)tcdsdev->tcdsda_addr;
- sc->sc_cookie = tcdsdev->tcdsda_cookie;
- sc->sc_dma = tcdsdev->tcdsda_sc;
-
- printf(": address %p", sc->sc_reg);
- tcds_intr_establish(parent, sc->sc_cookie, TC_IPL_BIO,
- (int (*)(void *))espintr, sc);
-#endif
-
-#ifdef SPARC_DRIVER
- /* Other settings */
- sc->sc_node = ca->ca_ra.ra_node;
- if (ca->ca_bustype == BUS_SBUS) {
- sc->sc_id = getpropint(sc->sc_node, "initiator-id", 7);
- sc->sc_freq = getpropint(sc->sc_node, "clock-frequency", -1);
- } else {
- sc->sc_id = 7;
- sc->sc_freq = 24000000;
- }
- if (sc->sc_freq < 0)
- sc->sc_freq = ((struct sbus_softc *)
- sc->sc_dev.dv_parent)->sc_clockfreq;
-#else
- if (parent->dv_cfdata->cf_driver == &tcds_cd) {
- sc->sc_id = tcdsdev->tcdsda_id;
- sc->sc_freq = tcdsdev->tcdsda_freq;
- } else {
- /* XXX */
- sc->sc_id = 7;
- sc->sc_freq = 24000000;
- }
-#endif
-
- /* gimme Mhz */
- sc->sc_freq /= 1000000;
-
-#ifdef SPARC_DRIVER
- if (dmachild) {
- sc->sc_dma = (struct dma_softc *)parent;
- sc->sc_dma->sc_esp = sc;
- } else {
- /*
- * find the DMA by poking around the dma device structures
- *
- * What happens here is that if the dma driver has not been
- * configured, then this returns a NULL pointer. Then when the
- * dma actually gets configured, it does the opposing test, and
- * if the sc->sc_esp field in it's softc is NULL, then tries to
- * find the matching esp driver.
- *
- */
- sc->sc_dma = (struct dma_softc *)
- getdevunit("dma", sc->sc_dev.dv_unit);
-
- /*
- * and a back pointer to us, for DMA
- */
- if (sc->sc_dma)
- sc->sc_dma->sc_esp = sc;
- else
- panic("espattach: no dma found");
- }
-#else
- sc->sc_dma->sc_esp = sc; /* XXX */
-#endif
-
- /*
- * It is necessary to try to load the 2nd config register here,
- * to find out what rev the esp chip is, else the esp_reset
- * will not set up the defaults correctly.
- */
- sc->sc_cfg1 = sc->sc_id | ESPCFG1_PARENB;
-#ifdef SPARC_DRIVER
- sc->sc_cfg2 = ESPCFG2_SCSI2 | ESPCFG2_RPE;
- sc->sc_cfg3 = ESPCFG3_CDB;
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
-
- if ((ESP_READ_REG(sc, ESP_CFG2) & ~ESPCFG2_RSVD) != (ESPCFG2_SCSI2 | ESPCFG2_RPE)) {
- printf(": ESP100");
- sc->sc_rev = ESP100;
- } else {
- sc->sc_cfg2 = ESPCFG2_SCSI2;
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
- sc->sc_cfg3 = 0;
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- sc->sc_cfg3 = (ESPCFG3_CDB | ESPCFG3_FCLK);
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- if (ESP_READ_REG(sc, ESP_CFG3) != (ESPCFG3_CDB | ESPCFG3_FCLK)) {
- printf(": ESP100A");
- sc->sc_rev = ESP100A;
- } else {
- /* ESPCFG2_FE enables > 64K transfers */
- sc->sc_cfg2 |= ESPCFG2_FE;
- sc->sc_cfg3 = 0;
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- printf(": ESP200");
- sc->sc_rev = ESP200;
- }
- }
-#else
- sc->sc_cfg2 = ESPCFG2_SCSI2;
- sc->sc_cfg3 = 0x4; /* Save residual byte. XXX??? */
- printf(": NCR53C94");
- sc->sc_rev = NCR53C94;
-#endif
-
- /*
- * This is the value used to start sync negotiations
- * Note that the ESP register "SYNCTP" is programmed
- * in "clocks per byte", and has a minimum value of 4.
- * The SCSI period used in negotiation is one-fourth
- * of the time (in nanoseconds) needed to transfer one byte.
- * Since the chip's clock is given in MHz, we have the following
- * formula: 4 * period = (1000 / freq) * 4
- */
- sc->sc_minsync = 1000 / sc->sc_freq;
-
-#ifdef SPARC_DRIVER
- /*
- * Alas, we must now modify the value a bit, because it's
- * only valid when can switch on FASTCLK and FASTSCSI bits
- * in config register 3...
- */
- switch (sc->sc_rev) {
- case ESP100:
- sc->sc_maxxfer = 64 * 1024;
- sc->sc_minsync = 0; /* No synch on old chip? */
- break;
- case ESP100A:
- sc->sc_maxxfer = 64 * 1024;
- sc->sc_minsync = esp_cpb2stp(sc, 5); /* Min clocks/byte is 5 */
- break;
- case ESP200:
- sc->sc_maxxfer = 16 * 1024 * 1024;
- /* XXX - do actually set FAST* bits */
- }
-#else
- sc->sc_maxxfer = 64 * 1024;
-#endif
-
- sc->sc_ccf = FREQTOCCF(sc->sc_freq);
-
- /* The value *must not* be == 1. Make it 2 */
- if (sc->sc_ccf == 1)
- sc->sc_ccf = 2;
-
- /*
- * The recommended timeout is 250ms. This register is loaded
- * with a value calculated as follows, from the docs:
- *
- * (timout period) x (CLK frequency)
- * reg = -------------------------------------
- * 8192 x (Clock Conversion Factor)
- *
- * Since CCF has a linear relation to CLK, this generally computes
- * to the constant of 153.
- */
- sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
-
- /* CCF register only has 3 bits; 0 is actually 8 */
- sc->sc_ccf &= 7;
-
- /* Reset state & bus */
- sc->sc_state = 0;
- espinit(sc, 1);
-
- printf(" %dMhz, target %d\n", sc->sc_freq, sc->sc_id);
-
-#ifdef SPARC_DRIVER
- /* add me to the sbus structures */
- sc->sc_sd.sd_reset = (void *) esp_reset;
-#if defined(SUN4C) || defined(SUN4M)
- if (ca->ca_bustype == BUS_SBUS) {
- if (dmachild)
- sbus_establish(&sc->sc_sd, sc->sc_dev.dv_parent);
- else
- sbus_establish(&sc->sc_sd, &sc->sc_dev);
- }
-#endif /* SUN4C || SUN4M */
-#endif
-
-#ifdef SPARC_DRIVER
- /* and the interuppts */
- sc->sc_ih.ih_fun = (void *) espintr;
- sc->sc_ih.ih_arg = sc;
- intr_establish(sc->sc_pri, &sc->sc_ih);
- evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
-#endif
-
- /*
- * fill in the prototype scsi_link.
- */
- /* sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE; */
- sc->sc_link.adapter_softc = sc;
- sc->sc_link.adapter_target = sc->sc_id;
- sc->sc_link.adapter = &esp_switch;
- sc->sc_link.device = &esp_dev;
- sc->sc_link.openings = 2;
-
- /*
- * If the boot path is "esp" at the moment and it's me, then
- * walk our pointer to the sub-device, ready for the config
- * below.
- */
-#ifdef SPARC_DRIVER
- bp = ca->ca_ra.ra_bp;
- switch (ca->ca_bustype) {
- case BUS_SBUS:
- if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
- SAME_ESP(sc, bp, ca))
- bootpath_store(1, bp + 1);
- break;
- default:
- if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
- bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit)
- bootpath_store(1, bp + 1);
- break;
- }
-#endif
-
- /*
- * Now try to attach all the sub-devices
- */
- config_found(self, &sc->sc_link, /* scsiprint */ espprint); /* XXX */
-
-#ifdef SPARC_DRIVER
- bootpath_store(1, NULL);
-#endif
-}
-
-/*
- * This is the generic esp reset function. It does not reset the SCSI bus,
- * only this controllers, but kills any on-going commands, and also stops
- * and resets the DMA.
- *
- * After reset, registers are loaded with the defaults from the attach
- * routine above.
- */
-void
-esp_reset(sc)
- struct esp_softc *sc;
-{
-
- /* reset DMA first */
- DMA_RESET(sc->sc_dma);
-
- /* reset SCSI chip */
- ESPCMD(sc, ESPCMD_RSTCHIP);
- ESPCMD(sc, ESPCMD_NOP);
- DELAY(500);
-
- /* do these backwards, and fall through */
- switch (sc->sc_rev) {
-#ifndef SPARC_DRIVER
- case NCR53C94:
-#endif
- case ESP200:
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- case ESP100A:
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
- case ESP100:
- ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
- ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
- break;
- default:
- printf("%s: unknown revision code, assuming ESP100\n",
- sc->sc_dev.dv_xname);
- ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
- ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
- }
-}
-
-/*
- * Reset the SCSI bus, but not the chip
- */
-void
-esp_scsi_reset(sc)
- struct esp_softc *sc;
-{
-#ifdef SPARC_DRIVER
- /* stop DMA first, as the chip will return to Bus Free phase */
- DMACSR(sc->sc_dma) &= ~D_EN_DMA;
-#else
- /*
- * XXX STOP DMA FIRST
- */
-#endif
-
- printf("esp: resetting SCSI bus\n");
- ESPCMD(sc, ESPCMD_RSTSCSI);
-}
-
-/*
- * Initialize esp state machine
- */
-void
-espinit(sc, doreset)
- struct esp_softc *sc;
- int doreset;
-{
- struct esp_ecb *ecb;
- int r;
-
- ESP_TRACE(("[ESPINIT(%d)] ", doreset));
-
- if (sc->sc_state == 0) {
- /* First time through; initialize. */
- TAILQ_INIT(&sc->ready_list);
- TAILQ_INIT(&sc->nexus_list);
- TAILQ_INIT(&sc->free_list);
- sc->sc_nexus = NULL;
- ecb = sc->sc_ecb;
- bzero(ecb, sizeof(sc->sc_ecb));
- for (r = 0; r < sizeof(sc->sc_ecb) / sizeof(*ecb); r++) {
- TAILQ_INSERT_TAIL(&sc->free_list, ecb, chain);
- ecb++;
- }
- bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
- } else {
- /* Cancel any active commands. */
- sc->sc_state = ESP_CLEANING;
- if ((ecb = sc->sc_nexus) != NULL) {
- ecb->xs->error = XS_DRIVER_STUFFUP;
- timeout_del(&ecb->xs->stimeout);
- esp_done(sc, ecb);
- }
- while ((ecb = sc->nexus_list.tqh_first) != NULL) {
- ecb->xs->error = XS_DRIVER_STUFFUP;
- timeout_del(&ecb->xs->stimeout);
- esp_done(sc, ecb);
- }
- }
-
- /*
- * reset the chip to a known state
- */
- esp_reset(sc);
-
- sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
- for (r = 0; r < 8; r++) {
- struct esp_tinfo *ti = &sc->sc_tinfo[r];
-/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
- int fl = sc->sc_dev.dv_cfdata->cf_flags;
-
- ti->flags = ((sc->sc_minsync && !(fl & (1<<(r+8))))
- ? T_NEGOTIATE : 0) |
- ((fl & (1<<r)) ? T_RSELECTOFF : 0) |
- T_NEED_TO_RESET;
- ti->period = sc->sc_minsync;
- ti->offset = 0;
- }
-
- if (doreset) {
- sc->sc_state = ESP_SBR;
- ESPCMD(sc, ESPCMD_RSTSCSI);
- } else {
- sc->sc_state = ESP_IDLE;
- }
-}
-
-/*
- * Read the ESP registers, and save their contents for later use.
- * ESP_STAT, ESP_STEP & ESP_INTR are mostly zeroed out when reading
- * ESP_INTR - so make sure it is the last read.
- *
- * I think that (from reading the docs) most bits in these registers
- * only make sense when he DMA CSR has an interrupt showing. Call only
- * if an interrupt is pending.
- */
-void
-espreadregs(sc)
- struct esp_softc *sc;
-{
-
- sc->sc_espstat = ESP_READ_REG(sc, ESP_STAT);
- /* Only the stepo bits are of interest */
- sc->sc_espstep = ESP_READ_REG(sc, ESP_STEP) & ESPSTEP_MASK;
- sc->sc_espintr = ESP_READ_REG(sc, ESP_INTR);
-#ifndef SPARC_DRIVER
- /* Clear the TCDS interrupt bit. */
- (void)tcds_scsi_isintr(sc->sc_dma, 1);
-#endif
-
- /*
- * Determine the SCSI bus phase, return either a real SCSI bus phase
- * or some pseudo phase we use to detect certain exceptions.
- */
-
- sc->sc_phase = (sc->sc_espintr & ESPINTR_DIS)
- ? /* Disconnected */ BUSFREE_PHASE
- : sc->sc_espstat & ESPSTAT_PHASE;
-
- ESP_MISC(("regs[intr=%02x,stat=%02x,step=%02x] ",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
-}
-
-/*
- * Convert chip register Clock Per Byte value to Synchronous Transfer Period.
- */
-static inline int
-esp_cpb2stp(sc, cpb)
- struct esp_softc *sc;
- int cpb;
-{
- return ((250 * cpb) / sc->sc_freq);
-}
-
-/*
- * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
- */
-static inline int
-esp_stp2cpb(sc, period)
- struct esp_softc *sc;
- int period;
-{
- int v;
- v = (sc->sc_freq * period) / 250;
- if (esp_cpb2stp(sc, v) < period)
- /* Correct round-down error */
- v++;
- return v;
-}
-
-static inline void
-esp_setsync(sc, ti)
- struct esp_softc *sc;
- struct esp_tinfo *ti;
-{
-
- if (ti->flags & T_SYNCMODE) {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP, esp_stp2cpb(sc, ti->period));
- } else {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP, 0);
- }
-}
-
-/*
- * Send a command to a target, set the driver state to ESP_SELECTING
- * and let the caller take care of the rest.
- *
- * Keeping this as a function allows me to say that this may be done
- * by DMA instead of programmed I/O soon.
- */
-void
-esp_select(sc, ecb)
- struct esp_softc *sc;
- struct esp_ecb *ecb;
-{
- struct scsi_link *sc_link = ecb->xs->sc_link;
- int target = sc_link->target;
- struct esp_tinfo *ti = &sc->sc_tinfo[target];
- u_char *cmd;
- int clen;
-
- ESP_TRACE(("[esp_select(t%d,l%d,cmd:%x)] ", sc_link->target, sc_link->lun, ecb->cmd.opcode));
-
- /* new state ESP_SELECTING */
- sc->sc_state = ESP_SELECTING;
-
- ESPCMD(sc, ESPCMD_FLUSH);
-
- /*
- * The docs say the target register is never reset, and I
- * can't think of a better place to set it
- */
- ESP_WRITE_REG(sc, ESP_SELID, target);
- esp_setsync(sc, ti);
-
- /*
- * Who am I. This is where we tell the target that we are
- * happy for it to disconnect etc.
- */
- ESP_WRITE_REG(sc, ESP_FIFO,
- MSG_IDENTIFY(sc_link->lun, (ti->flags & T_RSELECTOFF)?0:1));
-
- if (ti->flags & T_NEGOTIATE) {
- /* Arbitrate, select and stop after IDENTIFY message */
- ESPCMD(sc, ESPCMD_SELATNS);
- return;
- }
-
- /* Now the command into the FIFO */
- cmd = (u_char *)&ecb->cmd;
- clen = ecb->clen;
- while (clen--)
- ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
-
- /* And get the targets attention */
- ESPCMD(sc, ESPCMD_SELATN);
-}
-
-void
-esp_free_ecb(sc, ecb, flags)
- struct esp_softc *sc;
- struct esp_ecb *ecb;
- int flags;
-{
- int s;
-
- s = splbio();
-
- ecb->flags = 0;
- TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
-
- /*
- * If there were none, wake anybody waiting for one to come free,
- * starting with queued entries.
- */
- if (ecb->chain.tqe_next == 0)
- wakeup(&sc->free_list);
-
- splx(s);
-}
-
-struct esp_ecb *
-esp_get_ecb(sc, flags)
- struct esp_softc *sc;
- int flags;
-{
- struct esp_ecb *ecb;
- int s;
-
- s = splbio();
-
- while ((ecb = sc->free_list.tqh_first) == NULL &&
- (flags & SCSI_NOSLEEP) == 0)
- tsleep(&sc->free_list, PRIBIO, "especb", 0);
- if (ecb) {
- TAILQ_REMOVE(&sc->free_list, ecb, chain);
- ecb->flags |= ECB_ALLOC;
- }
-
- splx(s);
- return ecb;
-}
-
-/*
- * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
- */
-
-/*
- * Start a SCSI-command
- * This function is called by the higher level SCSI-driver to queue/run
- * SCSI-commands.
- */
-int
-esp_scsi_cmd(xs)
- struct scsi_xfer *xs;
-{
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_softc *sc = sc_link->adapter_softc;
- struct esp_ecb *ecb;
- int s, flags;
-
- ESP_TRACE(("[esp_scsi_cmd] "));
- ESP_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
- sc_link->target));
-
- flags = xs->flags;
- if ((ecb = esp_get_ecb(sc, flags)) == NULL) {
- xs->error = XS_DRIVER_STUFFUP;
- return TRY_AGAIN_LATER;
- }
-
- /* Initialize ecb */
- ecb->xs = xs;
- ecb->timeout = xs->timeout;
- timeout_set(&ecb->xs->stimeout, esp_timeout, ecb);
-
- if (xs->flags & SCSI_RESET) {
- ecb->flags |= ECB_RESET;
- ecb->clen = 0;
- ecb->dleft = 0;
- } else {
- bcopy(xs->cmd, &ecb->cmd, xs->cmdlen);
- ecb->clen = xs->cmdlen;
- ecb->daddr = xs->data;
- ecb->dleft = xs->datalen;
- }
- ecb->stat = 0;
-
- s = splbio();
-
- TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
-
- splx(s);
-
- if ((flags & SCSI_POLL) == 0)
- return SUCCESSFULLY_QUEUED;
-
- /* Not allowed to use interrupts, use polling instead */
- if (esp_poll(sc, xs, ecb->timeout)) {
- esp_timeout(ecb);
- if (esp_poll(sc, xs, ecb->timeout))
- esp_timeout(ecb);
- }
- return COMPLETE;
-}
-
-/*
- * Used when interrupt driven I/O isn't allowed, e.g. during boot.
- */
-int
-esp_poll(sc, xs, count)
- struct esp_softc *sc;
- struct scsi_xfer *xs;
- int count;
-{
-
- ESP_TRACE(("[esp_poll] "));
- while (count) {
- if (DMA_ISINTR(sc->sc_dma)) {
- espintr(sc);
- }
-#if alternatively
- if (ESP_READ_REG(sc, ESP_STAT) & ESPSTAT_INT)
- espintr(sc);
-#endif
- if ((xs->flags & ITSDONE) != 0)
- return 0;
- if (sc->sc_state == ESP_IDLE) {
- ESP_TRACE(("[esp_poll: rescheduling] "));
- esp_sched(sc);
- }
- DELAY(1000);
- count--;
- }
- return 1;
-}
-
-
-/*
- * LOW LEVEL SCSI UTILITIES
- */
-
-/*
- * Schedule a scsi operation. This has now been pulled out of the interrupt
- * handler so that we may call it from esp_scsi_cmd and esp_done. This may
- * save us an unecessary interrupt just to get things going. Should only be
- * called when state == ESP_IDLE and at bio pl.
- */
-void
-esp_sched(sc)
- struct esp_softc *sc;
-{
- struct esp_ecb *ecb;
- struct scsi_link *sc_link;
- struct esp_tinfo *ti;
-
- ESP_TRACE(("[esp_sched] "));
- if (sc->sc_state != ESP_IDLE)
- panic("esp_sched: not IDLE (state=%d)", sc->sc_state);
-
- /*
- * Find first ecb in ready queue that is for a target/lunit
- * combinations that is not busy.
- */
- for (ecb = sc->ready_list.tqh_first; ecb; ecb = ecb->chain.tqe_next) {
- sc_link = ecb->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
- if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- sc->sc_nexus = ecb;
- esp_select(sc, ecb);
- break;
- } else
- ESP_MISC(("%d:%d busy\n",
- sc_link->target, sc_link->lun));
- }
-}
-
-void
-esp_sense(sc, ecb)
- struct esp_softc *sc;
- struct esp_ecb *ecb;
-{
- struct scsi_xfer *xs = ecb->xs;
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
- struct scsi_sense *ss = (void *)&ecb->cmd;
-
- ESP_MISC(("requesting sense "));
- /* Next, setup a request sense command block */
- bzero(ss, sizeof(*ss));
- ss->opcode = REQUEST_SENSE;
- ss->byte2 = sc_link->lun << 5;
- ss->length = sizeof(struct scsi_sense_data);
- ecb->clen = sizeof(*ss);
- ecb->daddr = (char *)&xs->sense;
- ecb->dleft = sizeof(struct scsi_sense_data);
- ecb->flags |= ECB_SENSE;
- ti->senses++;
- if (ecb->flags & ECB_NEXUS)
- ti->lubusy &= ~(1 << sc_link->lun);
- if (ecb == sc->sc_nexus) {
- esp_select(sc, ecb);
- } else {
- esp_dequeue(sc, ecb);
- TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
- }
-}
-
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- */
-void
-esp_done(sc, ecb)
- struct esp_softc *sc;
- struct esp_ecb *ecb;
-{
- struct scsi_xfer *xs = ecb->xs;
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
-
- ESP_TRACE(("[esp_done(error:%x)] ", xs->error));
-
- /*
- * Now, if we've come here with no error code, i.e. we've kept the
- * initial XS_NOERROR, and the status code signals that we should
- * check sense, we'll need to set up a request sense cmd block and
- * push the command back into the ready queue *before* any other
- * commands for this target/lunit, else we lose the sense info.
- * We don't support chk sense conditions for the request sense cmd.
- */
- if (xs->error == XS_NOERROR) {
- if ((ecb->flags & ECB_ABORT) != 0) {
- xs->error = XS_DRIVER_STUFFUP;
- } else if ((ecb->flags & ECB_SENSE) != 0) {
- xs->error = XS_SENSE;
- } else if ((ecb->stat & ST_MASK) == SCSI_CHECK) {
- /* First, save the return values */
- xs->resid = ecb->dleft;
- xs->status = ecb->stat;
- esp_sense(sc, ecb);
- return;
- } else {
- xs->resid = ecb->dleft;
- }
- }
-
- xs->flags |= ITSDONE;
-
-#ifdef ESP_DEBUG
- if (esp_debug & ESP_SHOWMISC) {
- if (xs->resid != 0)
- printf("resid=%lu ", xs->resid);
- if (xs->error == XS_SENSE)
- printf("sense=0x%02x\n", xs->sense.error_code);
- else
- printf("error=%d\n", xs->error);
- }
-#endif
-
- /*
- * Remove the ECB from whatever queue it's on.
- */
- if (ecb->flags & ECB_NEXUS)
- ti->lubusy &= ~(1 << sc_link->lun);
- if (ecb == sc->sc_nexus) {
- sc->sc_nexus = NULL;
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- } else
- esp_dequeue(sc, ecb);
-
- esp_free_ecb(sc, ecb, xs->flags);
- ti->cmds++;
- scsi_done(xs);
-}
-
-void
-esp_dequeue(sc, ecb)
- struct esp_softc *sc;
- struct esp_ecb *ecb;
-{
-
- if (ecb->flags & ECB_NEXUS) {
- TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
- } else {
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- }
-}
-
-/*
- * INTERRUPT/PROTOCOL ENGINE
- */
-
-/*
- * Schedule an outgoing message by prioritizing it, and asserting
- * attention on the bus. We can only do this when we are the initiator
- * else there will be an illegal command interrupt.
- */
-#define esp_sched_msgout(m) \
- do { \
- ESP_MISC(("esp_sched_msgout %d ", m)); \
- ESPCMD(sc, ESPCMD_SETATN); \
- sc->sc_flags |= ESP_ATN; \
- sc->sc_msgpriq |= (m); \
- } while (0)
-
-int
-esp_reselect(sc, message)
- struct esp_softc *sc;
- int message;
-{
- u_char selid, target, lun;
- struct esp_ecb *ecb;
- struct scsi_link *sc_link;
- struct esp_tinfo *ti;
-
- /*
- * The SCSI chip made a snapshot of the data bus while the reselection
- * was being negotiated. This enables us to determine which target did
- * the reselect.
- */
- selid = sc->sc_selid & ~(1 << sc->sc_id);
- if (selid & (selid - 1)) {
- printf("%s: reselect with invalid selid %02x; sending DEVICE RESET\n",
- sc->sc_dev.dv_xname, selid);
- goto reset;
- }
-
- /*
- * Search wait queue for disconnected cmd
- * The list should be short, so I haven't bothered with
- * any more sophisticated structures than a simple
- * singly linked list.
- */
- target = ffs(selid) - 1;
- lun = message & 0x07;
- for (ecb = sc->nexus_list.tqh_first; ecb != NULL;
- ecb = ecb->chain.tqe_next) {
- sc_link = ecb->xs->sc_link;
- if (sc_link->target == target && sc_link->lun == lun)
- break;
- }
- if (ecb == NULL) {
- printf("%s: reselect from target %d lun %d with no nexus; sending ABORT\n",
- sc->sc_dev.dv_xname, target, lun);
- goto abort;
- }
-
- /* Make this nexus active again. */
- TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
- sc->sc_state = ESP_CONNECTED;
- sc->sc_nexus = ecb;
- ti = &sc->sc_tinfo[target];
- ti->lubusy |= (1 << lun);
- esp_setsync(sc, ti);
-
- if (ecb->flags & ECB_RESET)
- esp_sched_msgout(SEND_DEV_RESET);
- else if (ecb->flags & ECB_ABORT)
- esp_sched_msgout(SEND_ABORT);
-
- /* Do an implicit RESTORE POINTERS. */
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
-
- return (0);
-
-reset:
- esp_sched_msgout(SEND_DEV_RESET);
- return (1);
-
-abort:
- esp_sched_msgout(SEND_ABORT);
- return (1);
-}
-
-#define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
-#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
-#define ISEXTMSG(m) ((m) == 1)
-
-/*
- * Get an incoming message as initiator.
- *
- * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
- * byte in the FIFO
- */
-void
-esp_msgin(sc)
- register struct esp_softc *sc;
-{
- register int v;
-
- ESP_TRACE(("[esp_msgin(curmsglen:%ld)] ", (long)sc->sc_imlen));
-
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) == 0) {
- printf("%s: msgin: no msg byte available\n",
- sc->sc_dev.dv_xname);
- return;
- }
-
- /*
- * Prepare for a new message. A message should (according
- * to the SCSI standard) be transmitted in one single
- * MESSAGE_IN_PHASE. If we have been in some other phase,
- * then this is a new message.
- */
- if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
- sc->sc_flags &= ~ESP_DROP_MSGI;
- sc->sc_imlen = 0;
- }
-
- v = ESP_READ_REG(sc, ESP_FIFO);
- ESP_MISC(("<msgbyte:0x%02x>", v));
-
-#if 0
- if (sc->sc_state == ESP_RESELECTED && sc->sc_imlen == 0) {
- /*
- * Which target is reselecting us? (The ID bit really)
- */
- sc->sc_selid = v;
- ESP_MISC(("selid=0x%2x ", sc->sc_selid));
- return;
- }
-#endif
-
- sc->sc_imess[sc->sc_imlen] = v;
-
- /*
- * If we're going to reject the message, don't bother storing
- * the incoming bytes. But still, we need to ACK them.
- */
-
- if ((sc->sc_flags & ESP_DROP_MSGI)) {
- ESPCMD(sc, ESPCMD_MSGOK);
- printf("<dropping msg byte %x>",
- sc->sc_imess[sc->sc_imlen]);
- return;
- }
-
- if (sc->sc_imlen >= ESP_MAX_MSG_LEN) {
- esp_sched_msgout(SEND_REJECT);
- sc->sc_flags |= ESP_DROP_MSGI;
- } else {
- sc->sc_imlen++;
- /*
- * This testing is suboptimal, but most
- * messages will be of the one byte variety, so
- * it should not effect performance
- * significantly.
- */
- if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
- goto gotit;
- if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
- goto gotit;
- if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
- sc->sc_imlen == sc->sc_imess[1] + 2)
- goto gotit;
- }
- /* Ack what we have so far */
- ESPCMD(sc, ESPCMD_MSGOK);
- return;
-
-gotit:
- ESP_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
- /*
- * Now we should have a complete message (1 byte, 2 byte
- * and moderately long extended messages). We only handle
- * extended messages which total length is shorter than
- * ESP_MAX_MSG_LEN. Longer messages will be amputated.
- */
- switch (sc->sc_state) {
- struct esp_ecb *ecb;
- struct esp_tinfo *ti;
-
- case ESP_CONNECTED:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-
- switch (sc->sc_imess[0]) {
- case MSG_CMDCOMPLETE:
- ESP_MSGS(("cmdcomplete "));
- if (sc->sc_dleft < 0) {
- struct scsi_link *sc_link = ecb->xs->sc_link;
- printf("%s: %ld extra bytes from %d:%d\n",
- sc->sc_dev.dv_xname, -(long)sc->sc_dleft,
- sc_link->target, sc_link->lun);
- sc->sc_dleft = 0;
- }
- ecb->xs->resid = ecb->dleft = sc->sc_dleft;
- sc->sc_state = ESP_CMDCOMPLETE;
- break;
-
- case MSG_MESSAGE_REJECT:
- if (esp_debug & ESP_SHOWMSGS)
- printf("%s: our msg rejected by target\n",
- sc->sc_dev.dv_xname);
- switch (sc->sc_msgout) {
- case SEND_SDTR:
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
- esp_setsync(sc, ti);
- break;
- case SEND_INIT_DET_ERR:
- goto abort;
- }
- break;
-
- case MSG_NOOP:
- ESP_MSGS(("noop "));
- break;
-
- case MSG_DISCONNECT:
- ESP_MSGS(("disconnect "));
- ti->dconns++;
- sc->sc_state = ESP_DISCONNECT;
- if ((ecb->xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
- break;
- /*FALLTHROUGH*/
-
- case MSG_SAVEDATAPOINTER:
- ESP_MSGS(("save datapointer "));
- ecb->daddr = sc->sc_dp;
- ecb->dleft = sc->sc_dleft;
- break;
-
- case MSG_RESTOREPOINTERS:
- ESP_MSGS(("restore datapointer "));
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- break;
-
- case MSG_EXTENDED:
- ESP_MSGS(("extended(%x) ", sc->sc_imess[2]));
- switch (sc->sc_imess[2]) {
- case MSG_EXT_SDTR:
- ESP_MSGS(("SDTR period %d, offset %d ",
- sc->sc_imess[3], sc->sc_imess[4]));
- if (sc->sc_imess[1] != 3)
- goto reject;
- ti->period = sc->sc_imess[3];
- ti->offset = sc->sc_imess[4];
- ti->flags &= ~T_NEGOTIATE;
- if (sc->sc_minsync == 0 ||
- ti->offset == 0 ||
- ti->period > 124) {
- printf("%s:%d: async\n", "esp",
- ecb->xs->sc_link->target);
- if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
- /* target initiated negotiation */
- ti->offset = 0;
- ti->flags &= ~T_SYNCMODE;
- esp_sched_msgout(SEND_SDTR);
- } else {
- /* we are async */
- ti->flags &= ~T_SYNCMODE;
- }
- } else {
- int r = 250/ti->period;
- int s = (100*250)/ti->period - 100*r;
- int p;
-
- p = esp_stp2cpb(sc, ti->period);
- ti->period = esp_cpb2stp(sc, p);
-#ifdef ESP_DEBUG
- sc_print_addr(ecb->xs->sc_link);
- printf("max sync rate %d.%02dMb/s\n",
- r, s);
-#endif
- if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
- /* target initiated negotiation */
- if (ti->period < sc->sc_minsync)
- ti->period = sc->sc_minsync;
- if (ti->offset > 15)
- ti->offset = 15;
- ti->flags &= ~T_SYNCMODE;
- esp_sched_msgout(SEND_SDTR);
- } else {
- /* we are sync */
- ti->flags |= T_SYNCMODE;
- }
- }
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- esp_setsync(sc, ti);
- break;
-
- default:
- printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
- sc->sc_dev.dv_xname);
- goto reject;
- }
- break;
-
- default:
- ESP_MSGS(("ident "));
- printf("%s: unrecognized MESSAGE; sending REJECT\n",
- sc->sc_dev.dv_xname);
- reject:
- esp_sched_msgout(SEND_REJECT);
- break;
- }
- break;
-
- case ESP_RESELECTED:
- if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
- printf("%s: reselect without IDENTIFY; sending DEVICE RESET\n",
- sc->sc_dev.dv_xname);
- goto reset;
- }
-
- (void) esp_reselect(sc, sc->sc_imess[0]);
- break;
-
- default:
- printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
- sc->sc_dev.dv_xname);
- reset:
- esp_sched_msgout(SEND_DEV_RESET);
- break;
-
- abort:
- esp_sched_msgout(SEND_ABORT);
- break;
- }
-
- /* Ack last message byte */
- ESPCMD(sc, ESPCMD_MSGOK);
-
- /* Done, reset message pointer. */
- sc->sc_flags &= ~ESP_DROP_MSGI;
- sc->sc_imlen = 0;
-}
-
-
-/*
- * Send the highest priority, scheduled message
- */
-void
-esp_msgout(sc)
- register struct esp_softc *sc;
-{
- struct esp_tinfo *ti;
- struct esp_ecb *ecb;
- size_t size;
-
- ESP_TRACE(("[esp_msgout(priq:%x, prevphase:%x)]", sc->sc_msgpriq, sc->sc_prevphase));
-
- if (sc->sc_flags & ESP_ATN) {
- if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
- new:
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- sc->sc_msgoutq = 0;
- sc->sc_omlen = 0;
- }
- } else {
- if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
- esp_sched_msgout(sc->sc_msgoutq);
- goto new;
- } else {
- printf("esp at line %d: unexpected MESSAGE OUT phase\n", __LINE__);
- }
- }
-
- if (sc->sc_omlen == 0) {
- /* Pick up highest priority message */
- sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
- sc->sc_msgoutq |= sc->sc_msgout;
- sc->sc_msgpriq &= ~sc->sc_msgout;
- sc->sc_omlen = 1; /* "Default" message len */
- switch (sc->sc_msgout) {
- case SEND_SDTR:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- sc->sc_omess[0] = MSG_EXTENDED;
- sc->sc_omess[1] = 3;
- sc->sc_omess[2] = MSG_EXT_SDTR;
- sc->sc_omess[3] = ti->period;
- sc->sc_omess[4] = ti->offset;
- sc->sc_omlen = 5;
- if ((sc->sc_flags & ESP_SYNCHNEGO) == 0) {
- ti->flags |= T_SYNCMODE;
- esp_setsync(sc, ti);
- }
- break;
- case SEND_IDENTIFY:
- if (sc->sc_state != ESP_CONNECTED) {
- printf("esp at line %d: no nexus\n", __LINE__);
- }
- ecb = sc->sc_nexus;
- sc->sc_omess[0] = MSG_IDENTIFY(ecb->xs->sc_link->lun,0);
- break;
- case SEND_DEV_RESET:
- sc->sc_flags |= ESP_ABORTING;
- sc->sc_omess[0] = MSG_BUS_DEV_RESET;
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- ti->flags &= ~T_SYNCMODE;
- ti->flags |= T_NEGOTIATE;
- break;
- case SEND_PARITY_ERROR:
- sc->sc_omess[0] = MSG_PARITY_ERROR;
- break;
- case SEND_ABORT:
- sc->sc_flags |= ESP_ABORTING;
- sc->sc_omess[0] = MSG_ABORT;
- break;
- case SEND_INIT_DET_ERR:
- sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
- break;
- case SEND_REJECT:
- sc->sc_omess[0] = MSG_MESSAGE_REJECT;
- break;
- default:
- ESPCMD(sc, ESPCMD_RSTATN);
- sc->sc_flags &= ~ESP_ATN;
- sc->sc_omess[0] = MSG_NOOP;
- break;
- }
- sc->sc_omp = sc->sc_omess;
- }
-
-#if 1
- /* (re)send the message */
- size = min(sc->sc_omlen, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_omp, &sc->sc_omlen, 0, &size);
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc, ESP_TCL, size);
- ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
- if (sc->sc_cfg2 & ESPCFG2_FE) {
- ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
- ESPCMD(sc, ESPCMD_TRANS|ESPCMD_DMA);
- DMA_GO(sc->sc_dma);
-#else
- { int i;
- for (i = 0; i < sc->sc_omlen; i++)
- ESP_WRITE_REG(sc, FIFO, sc->sc_omess[i]);
- ESPCMD(sc, ESPCMD_TRANS);
- sc->sc_omlen = 0;
- }
-#endif
-}
-
-/*
- * This is the most critical part of the driver, and has to know
- * how to deal with *all* error conditions and phases from the SCSI
- * bus. If there are no errors and the DMA was active, then call the
- * DMA pseudo-interrupt handler. If this returns 1, then that was it
- * and we can return from here without further processing.
- *
- * Most of this needs verifying.
- */
-int
-espintr(sc)
- register struct esp_softc *sc;
-{
- register struct esp_ecb *ecb;
- register struct scsi_link *sc_link;
- struct esp_tinfo *ti;
- int loop;
- size_t size;
-
- ESP_TRACE(("[espintr]"));
-
- /*
- * I have made some (maybe seriously flawed) assumptions here,
- * but basic testing (uncomment the printf() below), show that
- * certainly something happens when this loop is here.
- *
- * The idea is that many of the SCSI operations take very little
- * time, and going away and getting interrupted is too high an
- * overhead to pay. For example, selecting, sending a message
- * and command and then doing some work can be done in one "pass".
- *
- * The DELAY is not variable because I do not understand that the
- * DELAY loop should be fixed-time regardless of CPU speed, but
- * I am *assuming* that the faster SCSI processors get things done
- * quicker (sending a command byte etc), and so there is no
- * need to be too slow.
- *
- * This is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
- * at 40Mhz. This needs testing.
- */
- for (loop = 0; 1;loop++, DELAY(50/sc->sc_freq)) {
- /* a feeling of deja-vu */
- if (!DMA_ISINTR(sc->sc_dma))
- return (loop != 0);
-#if 0
- if (loop)
- printf("*");
-#endif
-
- /* and what do the registers say... */
- espreadregs(sc);
-
- sc->sc_intrcnt.ev_count++;
-
- /*
- * At the moment, only a SCSI Bus Reset or Illegal
- * Command are classed as errors. A disconnect is a
- * valid condition, and we let the code check is the
- * "ESP_BUSFREE_OK" flag was set before declaring it
- * and error.
- *
- * Also, the status register tells us about "Gross
- * Errors" and "Parity errors". Only the Gross Error
- * is really bad, and the parity errors are dealt
- * with later
- *
- * TODO
- * If there are too many parity error, go to slow
- * cable mode ?
- */
-
- /* SCSI Reset */
- if (sc->sc_espintr & ESPINTR_SBR) {
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state != ESP_SBR) {
- printf("%s: SCSI bus reset\n",
- sc->sc_dev.dv_xname);
- espinit(sc, 0); /* Restart everything */
- return 1;
- }
-#if 0
- /*XXX*/ printf("<expected bus reset: "
- "[intr %x, stat %x, step %d]>\n",
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
-#endif
- if (sc->sc_nexus)
- panic("%s: nexus in reset state",
- sc->sc_dev.dv_xname);
- goto sched;
- }
-
- ecb = sc->sc_nexus;
-
-#define ESPINTR_ERR (ESPINTR_SBR|ESPINTR_ILL)
- if (sc->sc_espintr & ESPINTR_ERR ||
- sc->sc_espstat & ESPSTAT_GE) {
-
- if (sc->sc_espstat & ESPSTAT_GE) {
- /* no target ? */
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state == ESP_CONNECTED ||
- sc->sc_state == ESP_SELECTING) {
- ecb->xs->error = XS_DRIVER_STUFFUP;
- esp_done(sc, ecb);
- }
- return 1;
- }
-
- if (sc->sc_espintr & ESPINTR_ILL) {
- /* illegal command, out of sync ? */
- printf("%s: illegal command: 0x%x (state %d, phase %x, prevphase %x)\n",
- sc->sc_dev.dv_xname, sc->sc_lastcmd,
- sc->sc_state, sc->sc_phase,
- sc->sc_prevphase);
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- espinit(sc, 0); /* Restart everything */
- return 1;
- }
- }
-
- /*
- * Call if DMA is active.
- *
- * If DMA_INTR returns true, then maybe go 'round the loop
- * again in case there is no more DMA queued, but a phase
- * change is expected.
- */
- if (DMA_ISACTIVE(sc->sc_dma)) {
- int r = DMA_INTR(sc->sc_dma);
- if (r == -1) {
- printf("%s: DMA error; resetting\n",
- sc->sc_dev.dv_xname);
- espinit(sc, 1);
- }
- /* If DMA active here, then go back to work... */
- if (DMA_ISACTIVE(sc->sc_dma))
- return 1;
-
- if (sc->sc_dleft == 0 &&
- (sc->sc_espstat & ESPSTAT_TC) == 0)
- printf("%s: !TC [intr %x, stat %x, step %d]"
- " prevphase %x, resid %lx\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep,
- sc->sc_prevphase,
- ecb?ecb->dleft:-1);
- }
-
-#if 0 /* Unreliable on some ESP revisions? */
- if ((sc->sc_espstat & ESPSTAT_INT) == 0) {
- printf("%s: spurious interrupt\n", sc->sc_dev.dv_xname);
- return 1;
- }
-#endif
-
- /*
- * check for less serious errors
- */
- if (sc->sc_espstat & ESPSTAT_PE) {
- printf("%s: SCSI bus parity error\n",
- sc->sc_dev.dv_xname);
- if (sc->sc_prevphase == MESSAGE_IN_PHASE)
- esp_sched_msgout(SEND_PARITY_ERROR);
- else
- esp_sched_msgout(SEND_INIT_DET_ERR);
- }
-
- if (sc->sc_espintr & ESPINTR_DIS) {
- ESP_MISC(("<DISC [intr %x, stat %x, step %d]>",
- sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- /*
- * This command must (apparently) be issued within
- * 250mS of a disconnect. So here you are...
- */
- ESPCMD(sc, ESPCMD_ENSEL);
- switch (sc->sc_state) {
- case ESP_RESELECTED:
- goto sched;
-
- case ESP_SELECTING:
- ecb->xs->error = XS_SELTIMEOUT;
- goto finish;
-
- case ESP_CONNECTED:
- if ((sc->sc_flags & ESP_SYNCHNEGO)) {
-#ifdef ESP_DEBUG
- if (ecb)
- sc_print_addr(ecb->xs->sc_link);
- printf("sync nego not completed!\n");
-#endif
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
- }
-
- /* it may be OK to disconnect */
- if ((sc->sc_flags & ESP_ABORTING) == 0) {
- /*
- * Section 5.1.1 of the SCSI 2 spec
- * suggests issuing a REQUEST SENSE
- * following an unexpected disconnect.
- * Some devices go into a contingent
- * allegiance condition when
- * disconnecting, and this is necessary
- * to clean up their state.
- */
- printf("%s: unexpected disconnect; ",
- sc->sc_dev.dv_xname);
- if (ecb->flags & ECB_SENSE) {
- printf("resetting\n");
- goto reset;
- }
- printf("sending REQUEST SENSE\n");
- esp_sense(sc, ecb);
- goto out;
- }
-
- ecb->xs->error = XS_DRIVER_STUFFUP;
- goto finish;
-
- case ESP_DISCONNECT:
- TAILQ_INSERT_HEAD(&sc->nexus_list, ecb, chain);
- sc->sc_nexus = NULL;
- goto sched;
-
- case ESP_CMDCOMPLETE:
- goto finish;
- }
- }
-
- switch (sc->sc_state) {
-
- case ESP_SBR:
- printf("%s: waiting for SCSI Bus Reset to happen\n",
- sc->sc_dev.dv_xname);
- return 1;
-
- case ESP_RESELECTED:
- /*
- * we must be continuing a message ?
- */
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- printf("%s: target didn't identify\n",
- sc->sc_dev.dv_xname);
- espinit(sc, 1);
- return 1;
- }
-printf("<<RESELECT CONT'd>>");
-#if XXXX
- esp_msgin(sc);
- if (sc->sc_state != ESP_CONNECTED) {
- /* IDENTIFY fail?! */
- printf("%s: identify failed\n",
- sc->sc_dev.dv_xname);
- espinit(sc, 1);
- return 1;
- }
-#endif
- break;
-
- case ESP_IDLE:
-if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
- case ESP_SELECTING:
- sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
- sc->sc_flags = 0;
-
- if (sc->sc_espintr & ESPINTR_RESEL) {
- /*
- * If we're trying to select a
- * target ourselves, push our command
- * back into the ready list.
- */
- if (sc->sc_state == ESP_SELECTING) {
- ESP_MISC(("backoff selector "));
- sc_link = sc->sc_nexus->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
- TAILQ_INSERT_HEAD(&sc->ready_list,
- sc->sc_nexus, chain);
- ecb = sc->sc_nexus = NULL;
- }
- sc->sc_state = ESP_RESELECTED;
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- /*
- * Things are seriously fucked up.
- * Pull the brakes, i.e. reset
- */
- printf("%s: target didn't identify\n",
- sc->sc_dev.dv_xname);
- espinit(sc, 1);
- return 1;
- }
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
- printf("%s: RESELECT: %d bytes in FIFO!\n",
- sc->sc_dev.dv_xname,
- ESP_READ_REG(sc, ESP_FFLAG) &
- ESPFIFO_FF);
- espinit(sc, 1);
- return 1;
- }
- sc->sc_selid = ESP_READ_REG(sc, ESP_FIFO);
- ESP_MISC(("selid=0x%2x ", sc->sc_selid));
- esp_msgin(sc); /* Handle identify message */
- if (sc->sc_state != ESP_CONNECTED) {
- /* IDENTIFY fail?! */
- printf("%s: identify failed\n",
- sc->sc_dev.dv_xname);
- espinit(sc, 1);
- return 1;
- }
- continue; /* ie. next phase expected soon */
- }
-
-#define ESPINTR_DONE (ESPINTR_FC|ESPINTR_BS)
- if ((sc->sc_espintr & ESPINTR_DONE) == ESPINTR_DONE) {
- ecb = sc->sc_nexus;
- if (!ecb)
- panic("esp: not nexus at sc->sc_nexus");
-
- sc_link = ecb->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
-
- switch (sc->sc_espstep) {
- case 0:
- printf("%s: select timeout/no disconnect\n",
- sc->sc_dev.dv_xname);
- ecb->xs->error = XS_SELTIMEOUT;
- goto finish;
- case 1:
- if ((ti->flags & T_NEGOTIATE) == 0) {
- printf("%s: step 1 & !NEG\n",
- sc->sc_dev.dv_xname);
- goto reset;
- }
- if (sc->sc_phase != MESSAGE_OUT_PHASE) {
- printf("%s: !MSGOUT\n",
- sc->sc_dev.dv_xname);
- goto reset;
- }
- /* Start negotiating */
- ti->period = sc->sc_minsync;
- ti->offset = 15;
- sc->sc_flags |= ESP_SYNCHNEGO;
- esp_sched_msgout(SEND_SDTR);
- break;
- case 3:
- /*
- * Grr, this is supposed to mean
- * "target left command phase
- * prematurely". It seems to happen
- * regularly when sync mode is on.
- * Look at FIFO to see if command
- * went out.
- * (Timing problems?)
- */
- if ((ESP_READ_REG(sc, ESP_FFLAG)&ESPFIFO_FF) == 0) {
- /* Hope for the best.. */
- break;
- }
- printf("(%s:%d:%d): selection failed;"
- " %d left in FIFO "
- "[intr %x, stat %x, step %d]\n",
- sc->sc_dev.dv_xname,
- sc_link->target,
- sc_link->lun,
- ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- esp_sched_msgout(SEND_ABORT);
- return 1;
- case 2:
- /* Select stuck at Command Phase */
- ESPCMD(sc, ESPCMD_FLUSH);
- case 4:
- /* So far, everything went fine */
- break;
- }
-#if 0
- if (ecb->xs->flags & SCSI_RESET)
- esp_sched_msgout(SEND_DEV_RESET);
- else if (ti->flags & T_NEGOTIATE)
- esp_sched_msgout(
- SEND_IDENTIFY | SEND_SDTR);
- else
- esp_sched_msgout(SEND_IDENTIFY);
-#endif
-
- ecb->flags |= ECB_NEXUS;
- ti->lubusy |= (1 << sc_link->lun);
-
- sc->sc_prevphase = INVALID_PHASE; /* ?? */
- /* Do an implicit RESTORE POINTERS. */
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
-
- /* On our first connection, schedule a timeout. */
- if ((ecb->xs->flags & SCSI_POLL) == 0)
- timeout_add(&ecb->xs->stimeout,
- (ecb->timeout * hz) / 1000);
-
- sc->sc_state = ESP_CONNECTED;
- break;
- } else {
- printf("%s: unexpected status after select"
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- goto reset;
- }
- if (sc->sc_state == ESP_IDLE) {
- printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
- return 0;
- }
- break;
-
- case ESP_CONNECTED:
- if (sc->sc_flags & ESP_ICCS) {
- u_char msg;
-
- sc->sc_flags &= ~ESP_ICCS;
-
- if (!(sc->sc_espintr & ESPINTR_DONE)) {
- printf("%s: ICCS: "
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
- int i = (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) - 2;
- while (i--)
- (void) ESP_READ_REG(sc, ESP_FIFO);
- }
- ecb->stat = ESP_READ_REG(sc, ESP_FIFO);
- msg = ESP_READ_REG(sc, ESP_FIFO);
- ESP_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
- if (msg == MSG_CMDCOMPLETE) {
- ecb->xs->resid = ecb->dleft = sc->sc_dleft;
- sc->sc_state = ESP_CMDCOMPLETE;
- } else
- printf("%s: STATUS_PHASE: msg %d\n",
- sc->sc_dev.dv_xname, msg);
- ESPCMD(sc, ESPCMD_MSGOK);
- continue; /* ie. wait for disconnect */
- }
- break;
- default:
- panic("%s: invalid state: %d",
- sc->sc_dev.dv_xname,
- sc->sc_state);
- }
-
- /*
- * Driver is now in state ESP_CONNECTED, i.e. we
- * have a current command working the SCSI bus.
- */
- if (sc->sc_state != ESP_CONNECTED || ecb == NULL) {
- panic("esp no nexus");
- }
-
- switch (sc->sc_phase) {
- case MESSAGE_OUT_PHASE:
- ESP_PHASE(("MESSAGE_OUT_PHASE "));
- esp_msgout(sc);
- sc->sc_prevphase = MESSAGE_OUT_PHASE;
- break;
- case MESSAGE_IN_PHASE:
- ESP_PHASE(("MESSAGE_IN_PHASE "));
- if (sc->sc_espintr & ESPINTR_BS) {
- ESPCMD(sc, ESPCMD_FLUSH);
- sc->sc_flags |= ESP_WAITI;
- ESPCMD(sc, ESPCMD_TRANS);
- } else if (sc->sc_espintr & ESPINTR_FC) {
- if ((sc->sc_flags & ESP_WAITI) == 0) {
- printf("%s: MSGIN: unexpected FC bit: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_flags &= ~ESP_WAITI;
- esp_msgin(sc);
- } else {
- printf("%s: MSGIN: weird bits: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_prevphase = MESSAGE_IN_PHASE;
- break;
- case COMMAND_PHASE: {
- /* well, this means send the command again */
- u_char *cmd = (u_char *)&ecb->cmd;
- int i;
-
- ESP_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
- ecb->cmd.opcode, ecb->clen));
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- /* Now the command into the FIFO */
- for (i = 0; i < ecb->clen; i++)
- ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
- ESPCMD(sc, ESPCMD_TRANS);
- sc->sc_prevphase = COMMAND_PHASE;
- }
- break;
- case DATA_OUT_PHASE:
- ESP_PHASE(("DATA_OUT_PHASE [%ld] ",(long)sc->sc_dleft));
- ESPCMD(sc, ESPCMD_FLUSH);
- size = min(sc->sc_dleft, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
- 0, &size);
- sc->sc_prevphase = DATA_OUT_PHASE;
- goto setup_xfer;
- case DATA_IN_PHASE:
- ESP_PHASE(("DATA_IN_PHASE "));
- if (sc->sc_rev == ESP100)
- ESPCMD(sc, ESPCMD_FLUSH);
- size = min(sc->sc_dleft, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
- 1, &size);
- sc->sc_prevphase = DATA_IN_PHASE;
- setup_xfer:
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc, ESP_TCL, size);
- ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
- if (sc->sc_cfg2 & ESPCFG2_FE) {
- ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
-
- /*
- * Note that if `size' is 0, we've already transceived
- * all the bytes we want but we're still in DATA PHASE.
- * Apparently, the device needs padding. Also, a
- * transfer size of 0 means "maximum" to the chip
- * DMA logic.
- */
- ESPCMD(sc,
- (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
- DMA_GO(sc->sc_dma);
- return 1;
- case STATUS_PHASE:
- ESP_PHASE(("STATUS_PHASE "));
- sc->sc_flags |= ESP_ICCS;
- ESPCMD(sc, ESPCMD_ICCS);
- sc->sc_prevphase = STATUS_PHASE;
- break;
- case INVALID_PHASE:
- break;
- default:
- printf("%s: unexpected bus phase; resetting\n",
- sc->sc_dev.dv_xname);
- goto reset;
- }
- }
- panic("esp: should not get here..");
-
-reset:
- espinit(sc, 1);
- return 1;
-
-finish:
- timeout_del(&ecb->xs->stimeout);
- esp_done(sc, ecb);
- goto out;
-
-sched:
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- goto out;
-
-out:
- return 1;
-}
-
-void
-esp_abort(sc, ecb)
- struct esp_softc *sc;
- struct esp_ecb *ecb;
-{
-
- /* 2 secs for the abort */
- ecb->timeout = ESP_ABORT_TIMEOUT;
- ecb->flags |= ECB_ABORT;
-
- if (ecb == sc->sc_nexus) {
- /*
- * If we're still selecting, the message will be scheduled
- * after selection is complete.
- */
- if (sc->sc_state == ESP_CONNECTED)
- esp_sched_msgout(SEND_ABORT);
-
- /*
- * Reschedule timeout. First, cancel a queued timeout (if any)
- * in case someone decides to call esp_abort() from elsewhere.
- */
- timeout_add(&ecb->xs->stimeout, (ecb->timeout * hz) / 1000);
- } else {
- esp_dequeue(sc, ecb);
- TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
- }
-}
-
-void
-esp_timeout(arg)
- void *arg;
-{
- struct esp_ecb *ecb = arg;
- struct scsi_xfer *xs = ecb->xs;
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_softc *sc = sc_link->adapter_softc;
- int s;
-
- sc_print_addr(sc_link);
- printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
- "<state %d, nexus %p, phase(c %x, p %x), resid %lx, msg(q %x,o %x) %s>",
- sc->sc_dev.dv_xname,
- ecb, ecb->flags, ecb->dleft, ecb->stat,
- sc->sc_state, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
- (long)sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
- DMA_ISACTIVE(sc->sc_dma) ? "DMA active" : "");
-#if ESP_DEBUG > 0
- printf("TRACE: %s.", ecb->trace);
-#endif
-
- s = splbio();
-
- if (ecb->flags & ECB_ABORT) {
- /* abort timed out */
- printf(" AGAIN\n");
- espinit(sc, 1);
- } else {
- /* abort the operation that has timed out */
- printf("\n");
- xs->error = XS_TIMEOUT;
- esp_abort(sc, ecb);
- }
-
- splx(s);
-}
diff --git a/sys/arch/alpha/tc/ascreg.h b/sys/arch/alpha/tc/ascreg.h
deleted file mode 100644
index 3ed0088e759..00000000000
--- a/sys/arch/alpha/tc/ascreg.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/* $OpenBSD: ascreg.h,v 1.1 2000/07/05 21:50:38 ericj Exp $ */
-/* $NetBSD: espreg.h,v 1.3 1996/09/09 18:10:37 cgd Exp $ */
-
-/*
- * Copyright (c) 1994 Peter Galbavy. 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 Peter Galbavy.
- * 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.
- */
-
-/*
- * Register addresses, relative to some base address
- */
-
-#define ESP_TCL 0x00 /* RW - Transfer Count Low */
-#define ESP_TCM 0x01 /* RW - Transfer Count Mid */
-#define ESP_TCH 0x0e /* RW - Transfer Count High */
- /* NOT on 53C90 */
-
-#define ESP_FIFO 0x02 /* RW - FIFO data */
-
-#define ESP_CMD 0x03 /* RW - Command (2 deep) */
-#define ESPCMD_DMA 0x80 /* DMA Bit */
-#define ESPCMD_NOP 0x00 /* No Operation */
-#define ESPCMD_FLUSH 0x01 /* Flush FIFO */
-#define ESPCMD_RSTCHIP 0x02 /* Reset Chip */
-#define ESPCMD_RSTSCSI 0x03 /* Reset SCSI Bus */
-#define ESPCMD_RESEL 0x40 /* Reselect Sequence */
-#define ESPCMD_SELNATN 0x41 /* Select without ATN */
-#define ESPCMD_SELATN 0x42 /* Select with ATN */
-#define ESPCMD_SELATNS 0x43 /* Select with ATN & Stop */
-#define ESPCMD_ENSEL 0x44 /* Enable (Re)Selection */
-#define ESPCMD_DISSEL 0x45 /* Disable (Re)Selection */
-#define ESPCMD_SELATN3 0x46 /* Select with ATN3 */
-#define ESPCMD_RESEL3 0x47 /* Reselect3 Sequence */
-#define ESPCMD_SNDMSG 0x20 /* Send Message */
-#define ESPCMD_SNDSTAT 0x21 /* Send Status */
-#define ESPCMD_SNDDATA 0x22 /* Send Data */
-#define ESPCMD_DISCSEQ 0x23 /* Disconnect Sequence */
-#define ESPCMD_TERMSEQ 0x24 /* Terminate Sequence */
-#define ESPCMD_TCCS 0x25 /* Target Command Comp Seq */
-#define ESPCMD_DISC 0x27 /* Disconnect */
-#define ESPCMD_RECMSG 0x28 /* Receive Message */
-#define ESPCMD_RECCMD 0x29 /* Receive Command */
-#define ESPCMD_RECDATA 0x2a /* Receive Data */
-#define ESPCMD_RECCSEQ 0x2b /* Receive Command Sequence*/
-#define ESPCMD_ABORT 0x04 /* Target Abort DMA */
-#define ESPCMD_TRANS 0x10 /* Transfer Information */
-#define ESPCMD_ICCS 0x11 /* Initiator Cmd Comp Seq */
-#define ESPCMD_MSGOK 0x12 /* Message Accepted */
-#define ESPCMD_TRPAD 0x18 /* Transfer Pad */
-#define ESPCMD_SETATN 0x1a /* Set ATN */
-#define ESPCMD_RSTATN 0x1b /* Reset ATN */
-
-#define ESP_STAT 0x04 /* RO - Status */
-#define ESPSTAT_INT 0x80 /* Interrupt */
-#define ESPSTAT_GE 0x40 /* Gross Error */
-#define ESPSTAT_PE 0x20 /* Parity Error */
-#define ESPSTAT_TC 0x10 /* Terminal Count */
-#define ESPSTAT_VGC 0x08 /* Valid Group Code */
-#define ESPSTAT_PHASE 0x07 /* Phase bits */
-
-#define ESP_SELID 0x04 /* WO - Select/Reselect Bus ID */
-
-#define ESP_INTR 0x05 /* RO - Interrupt */
-#define ESPINTR_SBR 0x80 /* SCSI Bus Reset */
-#define ESPINTR_ILL 0x40 /* Illegal Command */
-#define ESPINTR_DIS 0x20 /* Disconnect */
-#define ESPINTR_BS 0x10 /* Bus Service */
-#define ESPINTR_FC 0x08 /* Function Complete */
-#define ESPINTR_RESEL 0x04 /* Reselected */
-#define ESPINTR_SELATN 0x02 /* Select with ATN */
-#define ESPINTR_SEL 0x01 /* Selected */
-
-#define ESP_TIMEOUT 0x05 /* WO - Select/Reselect Timeout */
-
-#define ESP_STEP 0x06 /* RO - Sequence Step */
-#define ESPSTEP_MASK 0x07 /* the last 3 bits */
-#define ESPSTEP_DONE 0x04 /* command went out */
-
-#define ESP_SYNCTP 0x06 /* WO - Synch Transfer Period */
- /* Default 5 (53C9X) */
-
-#define ESP_FFLAG 0x07 /* RO - FIFO Flags */
-#define ESPFIFO_SS 0xe0 /* Sequence Step (Dup) */
-#define ESPFIFO_FF 0x1f /* Bytes in FIFO */
-
-#define ESP_SYNCOFF 0x07 /* WO - Synch Offset */
- /* 0 = ASYNC */
- /* 1 - 15 = SYNC bytes */
-
-#define ESP_CFG1 0x08 /* RW - Configuration #1 */
-#define ESPCFG1_SLOW 0x80 /* Slow Cable Mode */
-#define ESPCFG1_SRR 0x40 /* SCSI Reset Rep Int Dis */
-#define ESPCFG1_PTEST 0x20 /* Parity Test Mod */
-#define ESPCFG1_PARENB 0x10 /* Enable Parity Check */
-#define ESPCFG1_CTEST 0x08 /* Enable Chip Test */
-#define ESPCFG1_BUSID 0x07 /* Bus ID */
-
-#define ESP_CCF 0x09 /* WO - Clock Conversion Factor */
- /* 0 = 35.01 - 40Mhz */
- /* NEVER SET TO 1 */
- /* 2 = 10Mhz */
- /* 3 = 10.01 - 15Mhz */
- /* 4 = 15.01 - 20Mhz */
- /* 5 = 20.01 - 25Mhz */
- /* 6 = 25.01 - 30Mhz */
- /* 7 = 30.01 - 35Mhz */
-
-#define ESP_TEST 0x0a /* WO - Test (Chip Test Only) */
-
-#define ESP_CFG2 0x0b /* RW - Configuration #2 */
-#define ESPCFG2_RSVD 0xa0 /* reserved */
-#define ESPCFG2_FE 0x40 /* Features Enable */
-#define ESPCFG2_DREQ 0x10 /* DREQ High Impedance */
-#define ESPCFG2_SCSI2 0x08 /* SCSI-2 Enable */
-#define ESPCFG2_BPA 0x04 /* Target Bad Parity Abort */
-#define ESPCFG2_RPE 0x02 /* Register Parity Error */
-#define ESPCFG2_DPE 0x01 /* DMA Parity Error */
-
-/* Config #3 only on 53C9X */
-#define ESP_CFG3 0x0c /* RW - Configuration #3 */
-#define ESPCFG3_RSVD 0xe0 /* reserved */
-#define ESPCFG3_IDM 0x10 /* ID Message Res Check */
-#define ESPCFG3_QTE 0x08 /* Queue Tag Enable */
-#define ESPCFG3_CDB 0x04 /* CDB 10-bytes OK */
-#define ESPCFG3_FSCSI 0x02 /* Fast SCSI */
-#define ESPCFG3_FCLK 0x01 /* Fast Clock (>25Mhz) */
diff --git a/sys/arch/alpha/tc/ascvar.h b/sys/arch/alpha/tc/ascvar.h
deleted file mode 100644
index 7d6b140f7a4..00000000000
--- a/sys/arch/alpha/tc/ascvar.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/* $OpenBSD: ascvar.h,v 1.2 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: espvar.h,v 1.12 1996/11/24 04:21:30 cgd Exp $ */
-
-#if defined(__sparc__) && !defined(SPARC_DRIVER)
-#define SPARC_DRIVER
-#endif
-
-/*
- * Copyright (c) 1994 Peter Galbavy. 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 Peter Galbavy.
- * 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.
- */
-
-#define ESP_DEBUG 0
-
-#define ESP_ABORT_TIMEOUT 2000 /* time to wait for abort */
-
-#define FREQTOCCF(freq) (((freq + 4) / 5))
-
-/* esp revisions */
-#define ESP100 0x01
-#define ESP100A 0x02
-#define ESP200 0x03
-#define NCR53C94 0x04
-
-/*
- * ECB. Holds additional information for each SCSI command Comments: We
- * need a separate scsi command block because we may need to overwrite it
- * with a request sense command. Basicly, we refrain from fiddling with
- * the scsi_xfer struct (except do the expected updating of return values).
- * We'll generally update: xs->{flags,resid,error,sense,status} and
- * occasionally xs->retries.
- */
-struct esp_ecb {
- TAILQ_ENTRY(esp_ecb) chain;
- struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
- int flags;
-#define ECB_ALLOC 0x01
-#define ECB_NEXUS 0x02
-#define ECB_SENSE 0x04
-#define ECB_ABORT 0x40
-#define ECB_RESET 0x80
- int timeout;
-
- struct scsi_generic cmd; /* SCSI command block */
- int clen;
- char *daddr; /* Saved data pointer */
- int dleft; /* Residue */
- u_char stat; /* SCSI status byte */
-
-#if ESP_DEBUG > 0
- char trace[1000];
-#endif
-};
-#if ESP_DEBUG > 0
-#define ECB_TRACE(ecb, msg, a, b) do { \
- const char *f = "[" msg "]"; \
- int n = strlen((ecb)->trace); \
- if (n < (sizeof((ecb)->trace)-100)) \
- sprintf((ecb)->trace + n, f, a, b); \
-} while(0)
-#else
-#define ECB_TRACE(ecb, msg, a, b)
-#endif
-
-/*
- * Some info about each (possible) target on the SCSI bus. This should
- * probably have been a "per target+lunit" structure, but we'll leave it at
- * this for now. Is there a way to reliably hook it up to sc->fordriver??
- */
-struct esp_tinfo {
- int cmds; /* #commands processed */
- int dconns; /* #disconnects */
- int touts; /* #timeouts */
- int perrs; /* #parity errors */
- int senses; /* #request sense commands sent */
- ushort lubusy; /* What local units/subr. are busy? */
- u_char flags;
-#define T_NEED_TO_RESET 0x01 /* Should send a BUS_DEV_RESET */
-#define T_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */
-#define T_BUSY 0x04 /* Target is busy, i.e. cmd in progress */
-#define T_SYNCMODE 0x08 /* sync mode has been negotiated */
-#define T_SYNCHOFF 0x10 /* .. */
-#define T_RSELECTOFF 0x20 /* .. */
- u_char period; /* Period suggestion */
- u_char offset; /* Offset suggestion */
-} tinfo_t;
-
-/* Register a linenumber (for debugging) */
-#define LOGLINE(p)
-
-#define ESP_SHOWECBS 0x01
-#define ESP_SHOWINTS 0x02
-#define ESP_SHOWCMDS 0x04
-#define ESP_SHOWMISC 0x08
-#define ESP_SHOWTRAC 0x10
-#define ESP_SHOWSTART 0x20
-#define ESP_SHOWPHASE 0x40
-#define ESP_SHOWDMA 0x80
-#define ESP_SHOWCCMDS 0x100
-#define ESP_SHOWMSGS 0x200
-
-#ifdef ESP_DEBUG
-extern int esp_debug;
-#define ESP_ECBS(str) do {if (esp_debug & ESP_SHOWECBS) printf str;} while (0)
-#define ESP_MISC(str) do {if (esp_debug & ESP_SHOWMISC) printf str;} while (0)
-#define ESP_INTS(str) do {if (esp_debug & ESP_SHOWINTS) printf str;} while (0)
-#define ESP_TRACE(str) do {if (esp_debug & ESP_SHOWTRAC) printf str;} while (0)
-#define ESP_CMDS(str) do {if (esp_debug & ESP_SHOWCMDS) printf str;} while (0)
-#define ESP_START(str) do {if (esp_debug & ESP_SHOWSTART) printf str;}while (0)
-#define ESP_PHASE(str) do {if (esp_debug & ESP_SHOWPHASE) printf str;}while (0)
-#define ESP_DMA(str) do {if (esp_debug & ESP_SHOWDMA) printf str;}while (0)
-#define ESP_MSGS(str) do {if (esp_debug & ESP_SHOWMSGS) printf str;}while (0)
-#else
-#define ESP_ECBS(str)
-#define ESP_MISC(str)
-#define ESP_INTS(str)
-#define ESP_TRACE(str)
-#define ESP_CMDS(str)
-#define ESP_START(str)
-#define ESP_PHASE(str)
-#define ESP_DMA(str)
-#define ESP_MSGS(str)
-#endif
-
-#define ESP_MAX_MSG_LEN 8
-
-struct esp_softc {
- struct device sc_dev; /* us as a device */
-#ifdef SPARC_DRIVER
- struct sbusdev sc_sd; /* sbus device */
- struct intrhand sc_ih; /* intr handler */
-#endif
- struct evcnt sc_intrcnt; /* intr count */
- struct scsi_link sc_link; /* scsi lint struct */
-#ifdef SPARC_DRIVER
- volatile u_char *sc_reg; /* the registers */
- struct dma_softc *sc_dma; /* pointer to my dma */
-#else
- volatile u_int32_t *sc_reg; /* the registers */
- struct tcds_slotconfig *sc_dma; /* DMA/slot info lives here. */
- void *sc_cookie; /* intr. handling cookie */
-#endif
-
- /* register defaults */
- u_char sc_cfg1; /* Config 1 */
- u_char sc_cfg2; /* Config 2, not ESP100 */
- u_char sc_cfg3; /* Config 3, only ESP200 */
- u_char sc_ccf; /* Clock Conversion */
- u_char sc_timeout;
-
- /* register copies, see espreadregs() */
- u_char sc_espintr;
- u_char sc_espstat;
- u_char sc_espstep;
- u_char sc_espfflags;
-
- /* Lists of command blocks */
- TAILQ_HEAD(ecb_list, esp_ecb) free_list,
- ready_list,
- nexus_list;
-
- struct esp_ecb *sc_nexus; /* current command */
- struct esp_ecb sc_ecb[3*8]; /* three per target */
- struct esp_tinfo sc_tinfo[8];
-
- /* Data about the current nexus (updated for every cmd switch) */
- caddr_t sc_dp; /* Current data pointer */
- ssize_t sc_dleft; /* Data left to transfer */
-
- /* Adapter state */
- int sc_phase; /* Copy of what bus phase we are in */
- int sc_prevphase; /* Copy of what bus phase we were in */
- u_char sc_state; /* State applicable to the adapter */
- u_char sc_flags;
- u_char sc_selid;
- u_char sc_lastcmd;
-
- /* Message stuff */
- u_char sc_msgpriq; /* One or more messages to send (encoded) */
- u_char sc_msgout; /* What message is on its way out? */
- u_char sc_msgoutq; /* What messages have been sent so far? */
- u_char sc_omess[ESP_MAX_MSG_LEN];
- caddr_t sc_omp; /* Message pointer (for multibyte messages) */
- size_t sc_omlen;
- u_char sc_imess[ESP_MAX_MSG_LEN + 1];
- caddr_t sc_imp; /* Message pointer (for multibyte messages) */
- size_t sc_imlen;
-
- /* hardware/openprom stuff */
- int sc_node; /* PROM node ID */
- int sc_freq; /* Freq in HZ */
-#ifdef SPARC_DRIVER
- int sc_pri; /* SBUS priority */
-#endif
- int sc_id; /* our scsi id */
- int sc_rev; /* esp revision */
- int sc_minsync; /* minimum sync period / 4 */
- int sc_maxxfer; /* maximum transfer size */
-};
-
-/* values for sc_state */
-#define ESP_IDLE 1 /* waiting for something to do */
-#define ESP_SELECTING 2 /* SCSI command is arbiting */
-#define ESP_RESELECTED 3 /* Has been reselected */
-#define ESP_CONNECTED 4 /* Actively using the SCSI bus */
-#define ESP_DISCONNECT 5 /* MSG_DISCONNECT received */
-#define ESP_CMDCOMPLETE 6 /* MSG_CMDCOMPLETE received */
-#define ESP_CLEANING 7
-#define ESP_SBR 8 /* Expect a SCSI RST because we commanded it */
-
-/* values for sc_flags */
-#define ESP_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
-#define ESP_ABORTING 0x02 /* Bailing out */
-#define ESP_DOINGDMA 0x04 /* The FIFO data path is active! */
-#define ESP_SYNCHNEGO 0x08 /* Synch negotiation in progress. */
-#define ESP_ICCS 0x10 /* Expect status phase results */
-#define ESP_WAITI 0x20 /* Waiting for non-DMA data to arrive */
-#define ESP_ATN 0x40 /* ATN asserted */
-
-/* values for sc_msgout */
-#define SEND_DEV_RESET 0x01
-#define SEND_PARITY_ERROR 0x02
-#define SEND_INIT_DET_ERR 0x04
-#define SEND_REJECT 0x08
-#define SEND_IDENTIFY 0x10
-#define SEND_ABORT 0x20
-#define SEND_SDTR 0x40
-#define SEND_WDTR 0x80
-
-/* SCSI Status codes */
-#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
-
-/* phase bits */
-#define IOI 0x01
-#define CDI 0x02
-#define MSGI 0x04
-
-/* Information transfer phases */
-#define DATA_OUT_PHASE (0)
-#define DATA_IN_PHASE (IOI)
-#define COMMAND_PHASE (CDI)
-#define STATUS_PHASE (CDI|IOI)
-#define MESSAGE_OUT_PHASE (MSGI|CDI)
-#define MESSAGE_IN_PHASE (MSGI|CDI|IOI)
-
-#define PHASE_MASK (MSGI|CDI|IOI)
-
-/* Some pseudo phases for getphase()*/
-#define BUSFREE_PHASE 0x100 /* Re/Selection no longer valid */
-#define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */
-#define PSEUDO_PHASE 0x100 /* "pseudo" bit */
-
-/*
- * Macros to read and write the chip's registers.
- */
-#ifdef SPARC_DRIVER
-#define ESP_READ_REG(sc, reg) \
- ((sc)->sc_reg[(reg) * 4])
-#define ESP_WRITE_REG(sc, reg, val) \
- do { \
- u_char v = (val); \
- (sc)->sc_reg[(reg) * 4] = v; \
- } while (0)
-#else /* ! SPARC_DRIVER */
-#if 1
-static __inline u_char ESP_READ_REG(struct esp_softc *, int);
-
-static __inline u_char
-ESP_READ_REG(sc, reg)
- struct esp_softc *sc;
- int reg;
-{
- u_char v;
-
- v = sc->sc_reg[reg * 2] & 0xff;
- alpha_mb();
- return v;
-}
-#else
-#define ESP_READ_REG(sc, reg) \
- ((u_char)((sc)->sc_reg[(reg) * 2] & 0xff))
-#endif
-#define ESP_WRITE_REG(sc, reg, val) \
- do { \
- u_char v = (val); \
- (sc)->sc_reg[(reg) * 2] = v; \
- alpha_mb(); \
- } while (0)
-#endif /* SPARC_DRIVER */
-
-#ifdef ESP_DEBUG
-#define ESPCMD(sc, cmd) do { \
- if (esp_debug & ESP_SHOWCCMDS) \
- printf("<cmd:0x%x>", (unsigned)cmd); \
- sc->sc_lastcmd = cmd; \
- ESP_WRITE_REG(sc, ESP_CMD, cmd); \
-} while (0)
-#else
-#define ESPCMD(sc, cmd) ESP_WRITE_REG(sc, ESP_CMD, cmd)
-#endif
-
-#define SAME_ESP(sc, bp, ca) \
- ((bp->val[0] == ca->ca_slot && bp->val[1] == ca->ca_offset) || \
- (bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit))
-
-#ifndef SPARC_DRIVER
-/* DMA macros for ESP */
-#define DMA_ISINTR(sc) tcds_dma_isintr(sc)
-#define DMA_RESET(sc) tcds_dma_reset(sc)
-#define DMA_INTR(sc) tcds_dma_intr(sc)
-#define DMA_SETUP(sc, addr, len, datain, dmasize) \
- tcds_dma_setup(sc, addr, len, datain, dmasize)
-#define DMA_GO(sc) tcds_dma_go(sc)
-#define DMA_ISACTIVE(sc) tcds_dma_isactive(sc)
-#endif
diff --git a/sys/arch/alpha/tc/ioasic.c b/sys/arch/alpha/tc/ioasic.c
index d95660442b6..a66b8eaf010 100644
--- a/sys/arch/alpha/tc/ioasic.c
+++ b/sys/arch/alpha/tc/ioasic.c
@@ -1,5 +1,42 @@
-/* $OpenBSD: ioasic.c,v 1.8 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: ioasic.c,v 1.10 1996/12/05 01:39:41 cgd Exp $ */
+/* $OpenBSD: ioasic.c,v 1.9 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: ioasic.c,v 1.34 2000/07/18 06:10:06 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -32,33 +69,21 @@
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <machine/autoconf.h>
+#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/rpb.h>
-#ifndef EVCNT_COUNTERS
#include <machine/intrcnt.h>
-#endif
#include <dev/tc/tcvar.h>
-#include <alpha/tc/ioasicreg.h>
+#include <dev/tc/ioasicreg.h>
#include <dev/tc/ioasicvar.h>
-struct ioasic_softc {
- struct device sc_dv;
-
- tc_addr_t sc_base;
- void *sc_cookie;
-};
-
/* Definition of the driver for autoconfig. */
-#ifdef __BROKEN_INDIRECT_CONFIG
int ioasicmatch(struct device *, void *, void *);
-#else
-int ioasicmatch(struct device *, struct cfdata *, void *);
-#endif
void ioasicattach(struct device *, struct device *, void *);
-int ioasicprint(void *, const char *);
struct cfattach ioasic_ca = {
sizeof(struct ioasic_softc), ioasicmatch, ioasicattach,
@@ -82,24 +107,26 @@ int ioasic_intrnull(void *);
#define IOASIC_NCOOKIES 4
-struct ioasic_dev {
- char *iad_modname;
- tc_offset_t iad_offset;
- void *iad_cookie;
- u_int32_t iad_intrbits;
-} ioasic_devs[] = {
- /* XXX lance name */
- { "lance", 0x000c0000, C(IOASIC_DEV_LANCE), IOASIC_INTR_LANCE, },
- { "z8530 ", 0x00100000, C(IOASIC_DEV_SCC0), IOASIC_INTR_SCC_0, },
- { "z8530 ", 0x00180000, C(IOASIC_DEV_SCC1), IOASIC_INTR_SCC_1, },
- { "TOY_RTC ", 0x00200000, C(IOASIC_DEV_BOGUS), 0, },
- { "AMD79c30", 0x00240000, C(IOASIC_DEV_ISDN), IOASIC_INTR_ISDN, },
+struct ioasic_dev ioasic_devs[] = {
+ { "PMAD-BA ", IOASIC_SLOT_3_START, C(IOASIC_DEV_LANCE),
+ IOASIC_INTR_LANCE, },
+ { "z8530 ", IOASIC_SLOT_4_START, C(IOASIC_DEV_SCC0),
+ IOASIC_INTR_SCC_0, },
+ { "z8530 ", IOASIC_SLOT_6_START, C(IOASIC_DEV_SCC1),
+ IOASIC_INTR_SCC_1, },
+ { "TOY_RTC ", IOASIC_SLOT_8_START, C(IOASIC_DEV_BOGUS),
+ 0, },
+ { "AMD79c30", IOASIC_SLOT_9_START, C(IOASIC_DEV_ISDN),
+ IOASIC_INTR_ISDN_TXLOAD | IOASIC_INTR_ISDN_RXLOAD, },
};
int ioasic_ndevs = sizeof(ioasic_devs) / sizeof(ioasic_devs[0]);
struct ioasicintr {
int (*iai_func)(void *);
void *iai_arg;
+#ifdef EVCNT_COUNTERS
+ struct evcnt iai_evcnt;
+#endif
} ioasicintrs[IOASIC_NCOOKIES];
tc_addr_t ioasic_base; /* XXX XXX XXX */
@@ -107,17 +134,10 @@ tc_addr_t ioasic_base; /* XXX XXX XXX */
/* There can be only one. */
int ioasicfound;
-extern int cputype;
-
int
ioasicmatch(parent, cfdata, aux)
struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *cfdata;
-#else
- struct cfdata *cfdata;
-#endif
- void *aux;
+ void *cfdata, *aux;
{
struct tc_attach_args *ta = aux;
@@ -142,20 +162,30 @@ ioasicattach(parent, self, aux)
{
struct ioasic_softc *sc = (struct ioasic_softc *)self;
struct tc_attach_args *ta = aux;
- struct ioasicdev_attach_args ioasicdev;
- u_long i;
+#ifdef DEC_3000_300
+ u_long ssr;
+#endif
+ u_long i, imsk;
+ const struct evcnt *pevcnt;
+ char *cp;
ioasicfound = 1;
- sc->sc_base = ta->ta_addr;
- ioasic_base = sc->sc_base; /* XXX XXX XXX */
- sc->sc_cookie = ta->ta_cookie;
+ sc->sc_bst = ta->ta_memt;
+ if (bus_space_map(ta->ta_memt, ta->ta_addr,
+ 0x400000, 0, &sc->sc_bsh)) {
+ printf("%s: unable to map device\n", sc->sc_dv.dv_xname);
+ return;
+ }
+ sc->sc_dmat = ta->ta_dmat;
+
+ ioasic_base = sc->sc_base = ta->ta_addr; /* XXX XXX XXX */
#ifdef DEC_3000_300
if (cputype == ST_DEC_3000_300) {
- *(volatile u_int *)IOASIC_REG_CSR(sc->sc_base) |=
- IOASIC_CSR_FASTMODE;
- tc_mb();
+ ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
+ ssr |= IOASIC_CSR_FASTMODE;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
printf(": slow mode\n");
} else
#endif
@@ -165,57 +195,34 @@ ioasicattach(parent, self, aux)
* Turn off all device interrupt bits.
* (This does _not_ include 3000/300 TC option slot bits.
*/
+ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
for (i = 0; i < ioasic_ndevs; i++)
- *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
- ~ioasic_devs[i].iad_intrbits;
- tc_mb();
+ imsk &= ~ioasic_devs[i].iad_intrbits;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
/*
* Set up interrupt handlers.
*/
+ pevcnt = tc_intr_evcnt(parent, ta->ta_cookie);
for (i = 0; i < IOASIC_NCOOKIES; i++) {
ioasicintrs[i].iai_func = ioasic_intrnull;
ioasicintrs[i].iai_arg = (void *)i;
+
+ cp = malloc(12, M_DEVBUF, M_NOWAIT);
+ if (cp == NULL)
+ panic("ioasicattach");
+ sprintf(cp, "slot %lu", i);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach_dynamic(&ioasicintrs[i].iai_evcnt,
+ EVCNT_TYPE_INTR, pevcnt, self->dv_xname, cp);
+#endif
}
- tc_intr_establish(parent, sc->sc_cookie, TC_IPL_NONE, ioasic_intr, sc);
+ tc_intr_establish(parent, ta->ta_cookie, TC_IPL_NONE, ioasic_intr, sc);
- /*
+ /*
* Try to configure each device.
*/
- for (i = 0; i < ioasic_ndevs; i++) {
- strncpy(ioasicdev.iada_modname, ioasic_devs[i].iad_modname,
- TC_ROM_LLEN);
- ioasicdev.iada_modname[TC_ROM_LLEN] = '\0';
- ioasicdev.iada_offset = ioasic_devs[i].iad_offset;
- ioasicdev.iada_addr = sc->sc_base + ioasic_devs[i].iad_offset;
- ioasicdev.iada_cookie = ioasic_devs[i].iad_cookie;
-
- /* Tell the autoconfig machinery we've found the hardware. */
- config_found(self, &ioasicdev, ioasicprint);
- }
-}
-
-int
-ioasicprint(aux, pnp)
- void *aux;
- const char *pnp;
-{
- struct ioasicdev_attach_args *d = aux;
-
- if (pnp)
- printf("%s at %s", d->iada_modname, pnp);
- printf(" offset 0x%lx", (long)d->iada_offset);
- return (UNCONF);
-}
-
-int
-ioasic_submatch(match, d)
- struct cfdata *match;
- struct ioasicdev_attach_args *d;
-{
-
- return ((match->ioasiccf_offset == d->iada_offset) ||
- (match->ioasiccf_offset == IOASIC_OFFSET_UNKNOWN));
+ ioasic_attach_devs(sc, ioasic_devs, ioasic_ndevs);
}
void
@@ -225,7 +232,8 @@ ioasic_intr_establish(ioa, cookie, level, func, arg)
tc_intrlevel_t level;
int (*func)(void *);
{
- u_long dev, i;
+ struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0];
+ u_long dev, i, imsk;
dev = (u_long)cookie;
#ifdef DIAGNOSTIC
@@ -233,7 +241,7 @@ ioasic_intr_establish(ioa, cookie, level, func, arg)
#endif
if (ioasicintrs[dev].iai_func != ioasic_intrnull)
- panic("ioasic_intr_establish: cookie %d twice", dev);
+ panic("ioasic_intr_establish: cookie %lu twice", dev);
ioasicintrs[dev].iai_func = func;
ioasicintrs[dev].iai_arg = arg;
@@ -244,9 +252,10 @@ ioasic_intr_establish(ioa, cookie, level, func, arg)
break;
if (i == ioasic_ndevs)
panic("ioasic_intr_establish: invalid cookie.");
- *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
- ioasic_devs[i].iad_intrbits;
- tc_mb();
+
+ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
+ imsk |= ioasic_devs[i].iad_intrbits;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
}
void
@@ -254,7 +263,8 @@ ioasic_intr_disestablish(ioa, cookie)
struct device *ioa;
void *cookie;
{
- u_long dev, i;
+ struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0];
+ u_long dev, i, imsk;
dev = (u_long)cookie;
#ifdef DIAGNOSTIC
@@ -262,7 +272,7 @@ ioasic_intr_disestablish(ioa, cookie)
#endif
if (ioasicintrs[dev].iai_func == ioasic_intrnull)
- panic("ioasic_intr_disestablish: cookie %d missing intr", dev);
+ panic("ioasic_intr_disestablish: cookie %lu missing intr", dev);
/* Enable interrupts for the device. */
for (i = 0; i < ioasic_ndevs; i++)
@@ -270,9 +280,10 @@ ioasic_intr_disestablish(ioa, cookie)
break;
if (i == ioasic_ndevs)
panic("ioasic_intr_disestablish: invalid cookie.");
- *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
- ~ioasic_devs[i].iad_intrbits;
- tc_mb();
+
+ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
+ imsk &= ~ioasic_devs[i].iad_intrbits;
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
ioasicintrs[dev].iai_func = ioasic_intrnull;
ioasicintrs[dev].iai_arg = (void *)dev;
@@ -288,8 +299,7 @@ ioasic_intrnull(val)
}
/*
- * asic_intr --
- * ASIC interrupt handler.
+ * ASIC interrupt handler.
*/
int
ioasic_intr(val)
@@ -298,66 +308,44 @@ ioasic_intr(val)
register struct ioasic_softc *sc = val;
register int ifound;
int gifound;
- u_int32_t sir;
- volatile u_int32_t *sirp;
-
- sirp = (volatile u_int32_t *)IOASIC_REG_INTR(sc->sc_base);
+ u_int32_t sir, osir;
gifound = 0;
do {
ifound = 0;
tc_syncbus();
- sir = *sirp;
+ osir = sir =
+ bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR);
#ifdef EVCNT_COUNTERS
- /* No interrupt counting via evcnt counters */
- XXX BREAK HERE XXX
-#else /* !EVCNT_COUNTERS */
+#define INCRINTRCNT(slot) ioasicintrs[slot].iai_evcnt.ev_count++
+#else
#define INCRINTRCNT(slot) intrcnt[INTRCNT_IOASIC + slot]++
-#endif /* EVCNT_COUNTERS */
+#endif
/* XXX DUPLICATION OF INTERRUPT BIT INFORMATION... */
-#define CHECKINTR(slot, bits) \
- if (sir & bits) { \
+#define CHECKINTR(slot, bits, clear) \
+ if (sir & (bits)) { \
ifound = 1; \
INCRINTRCNT(slot); \
(*ioasicintrs[slot].iai_func) \
(ioasicintrs[slot].iai_arg); \
+ if (clear) \
+ sir &= ~(bits); \
}
- CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0);
- CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1);
- CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE);
- CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN);
+ CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0, 0);
+ CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1, 0);
+ CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE, 0);
+ CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN_TXLOAD |
+ IOASIC_INTR_ISDN_RXLOAD | IOASIC_INTR_ISDN_OVRUN, 1);
+
+ if (sir != osir)
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+ IOASIC_INTR, sir);
gifound |= ifound;
} while (ifound);
return (gifound);
}
-
-/* XXX */
-char *
-ioasic_lance_ether_address()
-{
-
- return (u_char *)IOASIC_SYS_ETHER_ADDRESS(ioasic_base);
-}
-
-void
-ioasic_lance_dma_setup(v)
- void *v;
-{
- volatile u_int32_t *ldp;
- tc_addr_t tca;
-
- tca = (tc_addr_t)v;
-
- ldp = (volatile u_int *)IOASIC_REG_LANCE_DMAPTR(ioasic_base);
- *ldp = ((tca << 3) & ~(tc_addr_t)0x1f) | ((tca >> 29) & 0x1f);
- tc_wmb();
-
- *(volatile u_int32_t *)IOASIC_REG_CSR(ioasic_base) |=
- IOASIC_CSR_DMAEN_LANCE;
- tc_mb();
-}
diff --git a/sys/arch/alpha/tc/ioasicreg.h b/sys/arch/alpha/tc/ioasicreg.h
deleted file mode 100644
index 2c09ef47776..00000000000
--- a/sys/arch/alpha/tc/ioasicreg.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/* $OpenBSD: ioasicreg.h,v 1.3 1996/10/30 22:41:09 niklas Exp $ */
-/* $NetBSD: ioasicreg.h,v 1.1 1995/12/20 00:43:22 cgd Exp $ */
-
-/*
- * Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * The Mach Operating System project at Carnegie-Mellon University,
- * Ralph Campbell and Rick Macklem.
- *
- * 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 the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- *
- * @(#)asic.h 8.1 (Berkeley) 6/10/93
- */
-
-/*
- * Slot definitions
- */
-
-#define IOASIC_SLOT_0_START 0x000000
-#define IOASIC_SLOT_1_START 0x040000
-#define IOASIC_SLOT_2_START 0x080000
-#define IOASIC_SLOT_3_START 0x0c0000
-#define IOASIC_SLOT_4_START 0x100000
-#define IOASIC_SLOT_5_START 0x140000
-#define IOASIC_SLOT_6_START 0x180000
-#define IOASIC_SLOT_7_START 0x1c0000
-#define IOASIC_SLOT_8_START 0x200000
-#define IOASIC_SLOT_9_START 0x240000
-#define IOASIC_SLOT_10_START 0x280000
-#define IOASIC_SLOT_11_START 0x2c0000
-#define IOASIC_SLOT_12_START 0x300000
-#define IOASIC_SLOT_13_START 0x340000
-#define IOASIC_SLOT_14_START 0x380000
-#define IOASIC_SLOT_15_START 0x3c0000
-#define IOASIC_SLOTS_END 0x3fffff
-
-/*
- * Register offsets (slot 1)
- */
-
-#define IOASIC_SCSI_DMAPTR IOASIC_SLOT_1_START+0x000
-#define IOASIC_SCSI_NEXTPTR IOASIC_SLOT_1_START+0x010
-#define IOASIC_LANCE_DMAPTR IOASIC_SLOT_1_START+0x020
-#define IOASIC_SCC_T1_DMAPTR IOASIC_SLOT_1_START+0x030
-#define IOASIC_SCC_R1_DMAPTR IOASIC_SLOT_1_START+0x040
-#define IOASIC_SCC_T2_DMAPTR IOASIC_SLOT_1_START+0x050
-#define IOASIC_SCC_R2_DMAPTR IOASIC_SLOT_1_START+0x060
-#define IOASIC_FLOPPY_DMAPTR IOASIC_SLOT_1_START+0x070
-#define IOASIC_ISDN_X_DMAPTR IOASIC_SLOT_1_START+0x080
-#define IOASIC_ISDN_X_NEXTPTR IOASIC_SLOT_1_START+0x090
-#define IOASIC_ISDN_R_DMAPTR IOASIC_SLOT_1_START+0x0a0
-#define IOASIC_ISDN_R_NEXTPTR IOASIC_SLOT_1_START+0x0b0
-#define IOASIC_BUFF0 IOASIC_SLOT_1_START+0x0c0
-#define IOASIC_BUFF1 IOASIC_SLOT_1_START+0x0d0
-#define IOASIC_BUFF2 IOASIC_SLOT_1_START+0x0e0
-#define IOASIC_BUFF3 IOASIC_SLOT_1_START+0x0f0
-#define IOASIC_CSR IOASIC_SLOT_1_START+0x100
-#define IOASIC_INTR IOASIC_SLOT_1_START+0x110
-#define IOASIC_IMSK IOASIC_SLOT_1_START+0x120
-#define IOASIC_CURADDR IOASIC_SLOT_1_START+0x130
-#define IOASIC_ISDN_X_DATA IOASIC_SLOT_1_START+0x140
-#define IOASIC_ISDN_R_DATA IOASIC_SLOT_1_START+0x150
-#define IOASIC_LANCE_DECODE IOASIC_SLOT_1_START+0x160
-#define IOASIC_SCSI_DECODE IOASIC_SLOT_1_START+0x170
-#define IOASIC_SCC0_DECODE IOASIC_SLOT_1_START+0x180
-#define IOASIC_SCC1_DECODE IOASIC_SLOT_1_START+0x190
-#define IOASIC_FLOPPY_DECODE IOASIC_SLOT_1_START+0x1a0
-#define IOASIC_SCSI_SCR IOASIC_SLOT_1_START+0x1b0
-#define IOASIC_SCSI_SDR0 IOASIC_SLOT_1_START+0x1c0
-#define IOASIC_SCSI_SDR1 IOASIC_SLOT_1_START+0x1d0
-
-/* System Status and control Register (SSR). */
-#define IOASIC_CSR_DMAEN_T1 0x80000000 /* rw */
-#define IOASIC_CSR_DMAEN_R1 0x40000000 /* rw */
-#define IOASIC_CSR_DMAEN_T2 0x20000000 /* rw */
-#define IOASIC_CSR_DMAEN_R2 0x10000000 /* rw */
-#define IOASIC_CSR_FASTMODE 0x08000000 /* rw */
-#define IOASIC_CSR_xxx 0x07800000 /* unused/reserved */
-#define IOASIC_CSR_FLOPPY_DIR 0x00400000 /* rw */
-#define IOASIC_CSR_DMAEN_FLOPPY 0x00200000 /* rw */
-#define IOASIC_CSR_DMAEN_ISDN_T 0x00100000 /* rw */
-#define IOASIC_CSR_DMAEN_ISDN_R 0x00080000 /* rw */
-#define IOASIC_CSR_SCSI_DIR 0x00040000 /* rw */
-#define IOASIC_CSR_DMAEN_SCSI 0x00020000 /* rw */
-#define IOASIC_CSR_DMAEN_LANCE 0x00010000 /* rw */
-/* low 16 bits are rw gp outputs */
-
-/* System Interrupt Register (and Interrupt Mask Register). */
-#define IOASIC_INTR_T1_PAGE_END 0x80000000 /* rz */
-#define IOASIC_INTR_T1_READ_E 0x40000000 /* rz */
-#define IOASIC_INTR_R1_HALF_PAGE 0x20000000 /* rz */
-#define IOASIC_INTR_R1_DMA_OVRUN 0x10000000 /* rz */
-#define IOASIC_INTR_T2_PAGE_END 0x08000000 /* rz */
-#define IOASIC_INTR_T2_READ_E 0x04000000 /* rz */
-#define IOASIC_INTR_R2_HALF_PAGE 0x02000000 /* rz */
-#define IOASIC_INTR_R2_DMA_OVRUN 0x01000000 /* rz */
-#define IOASIC_INTR_FLOPPY_DMA_E 0x00800000 /* rz */
-#define IOASIC_INTR_ISDN_PTR_LOAD 0x00400000 /* rz */
-#define IOASIC_INTR_ISDN_OVRUN 0x00200000 /* rz */
-#define IOASIC_INTR_ISDN_READ_E 0x00100000 /* rz */
-#define IOASIC_INTR_SCSI_PTR_LOAD 0x00080000 /* rz */
-#define IOASIC_INTR_SCSI_OVRUN 0x00040000 /* rz */
-#define IOASIC_INTR_SCSI_READ_E 0x00020000 /* rz */
-#define IOASIC_INTR_LANCE_READ_E 0x00010000 /* rz */
-#define IOASIC_INTR_ISDN 0x00002000 /* ro */
-#define IOASIC_INTR_SEC_CON 0x00000200 /* ro */
-#define IOASIC_INTR_LANCE 0x00000100 /* ro */
-#define IOASIC_INTR_SCC_1 0x00000080 /* ro */
-#define IOASIC_INTR_SCC_0 0x00000040 /* ro */
-#define IOASIC_INTR_ALT_CON 0x00000008 /* ro - 3000/500 */
-#define IOASIC_INTR_300_OPT1 IOASIC_INTR_ALT_CON /* ro - 3000/300 */
-#define IOASIC_INTR_300_OPT0 0x00000004 /* ro - 3000/300 */
-
-/* DMA pointer registers (SCSI, Comm, ...) */
-
-#define IOASIC_DMAPTR_MASK 0xffffffe0
-#define IOASIC_DMAPTR_SHIFT 5
-#define IOASIC_DMAPTR_SET(reg,val) \
- (reg) = (((val)<<IOASIC_DMAPTR_SHIFT)&IOASIC_DMAPTR_MASK)
-#define IOASIC_DMAPTR_GET(reg,val) \
- (val) = (((reg)&IOASIC_DMAPTR_MASK)>>IOASIC_DMAPTR_SHIFT)
-#define IOASIC_DMA_ADDR(p) (((unsigned)p) << (5-2))
-
-/* For the LANCE DMA pointer register initialization the above suffices */
-
-/* More SCSI DMA registers */
-
-#define IOASIC_SCR_STATUS 0x00000004
-#define IOASIC_SCR_WORD 0x00000003
-
-/* Various Decode registers */
-
-#define IOASIC_DECODE_HW_ADDRESS 0x000003f0
-#define IOASIC_DECODE_CHIP_SELECT 0x0000000f
-
-/*
- * Asic register addresses at offset from base.
- */
-#define IOASIC_REG_SCSI_DMAPTR(base) ((base) + IOASIC_SCSI_DMAPTR)
-#define IOASIC_REG_SCSI_DMANPTR(base) ((base) + IOASIC_SCSI_NEXTPTR)
-#define IOASIC_REG_LANCE_DMAPTR(base) ((base) + IOASIC_LANCE_DMAPTR)
-#define IOASIC_REG_SCC_T1_DMAPTR(base) ((base) + IOASIC_SCC_T1_DMAPTR)
-#define IOASIC_REG_SCC_R1_DMAPTR(base) ((base) + IOASIC_SCC_R1_DMAPTR)
-#define IOASIC_REG_SCC_T2_DMAPTR(base) ((base) + IOASIC_SCC_T2_DMAPTR)
-#define IOASIC_REG_SCC_R2_DMAPTR(base) ((base) + IOASIC_SCC_R2_DMAPTR)
-#define IOASIC_REG_FLOPPY_DMAPTR(base) ((base) + IOASIC_FLOPPY_DMAPTR)
-#define IOASIC_REG_ISDN_X_DMAPTR(base) ((base) + IOASIC_ISDN_X_DMAPTR)
-#define IOASIC_REG_ISDN_X_NEXTPTR(base) ((base) + IOASIC_ISDN_X_NEXTPTR)
-#define IOASIC_REG_ISDN_R_DMAPTR(base) ((base) + IOASIC_ISDN_R_DMAPTR)
-#define IOASIC_REG_ISDN_R_NEXTPTR(base) ((base) + IOASIC_ISDN_R_NEXTPTR)
-#define IOASIC_REG_BUFF0(base) ((base) + IOASIC_BUFF0)
-#define IOASIC_REG_BUFF1(base) ((base) + IOASIC_BUFF1)
-#define IOASIC_REG_BUFF2(base) ((base) + IOASIC_BUFF2)
-#define IOASIC_REG_BUFF3(base) ((base) + IOASIC_BUFF3)
-#define IOASIC_REG_CSR(base) ((base) + IOASIC_CSR)
-#define IOASIC_REG_INTR(base) ((base) + IOASIC_INTR)
-#define IOASIC_REG_IMSK(base) ((base) + IOASIC_IMSK)
-#define IOASIC_REG_CURADDR(base) ((base) + IOASIC_CURADDR)
-#define IOASIC_REG_ISDN_X_DATA(base) ((base) + IOASIC_ISDN_X_DATA)
-#define IOASIC_REG_ISDN_R_DATA(base) ((base) + IOASIC_ISDN_R_DATA)
-#define IOASIC_REG_LANCE_DECODE(base) ((base) + IOASIC_LANCE_DECODE)
-#define IOASIC_REG_SCSI_DECODE(base) ((base) + IOASIC_SCSI_DECODE)
-#define IOASIC_REG_SCC0_DECODE(base) ((base) + IOASIC_SCC0_DECODE)
-#define IOASIC_REG_SCC1_DECODE(base) ((base) + IOASIC_SCC1_DECODE)
-#define IOASIC_REG_FLOPPY_DECODE(base) ((base) + IOASIC_FLOPPY_DECODE)
-#define IOASIC_REG_SCSI_SCR(base) ((base) + IOASIC_SCSI_SCR)
-#define IOASIC_REG_SCSI_SDR0(base) ((base) + IOASIC_SCSI_SDR0)
-#define IOASIC_REG_SCSI_SDR1(base) ((base) + IOASIC_SCSI_SDR1)
-
-/*
- * And slot assignments.
- */
-#define IOASIC_SYS_ETHER_ADDRESS(base) ((base) + IOASIC_SLOT_2_START)
-#define IOASIC_SYS_LANCE(base) ((base) + IOASIC_SLOT_3_START)
diff --git a/sys/arch/alpha/tc/mcclock_ioasic.c b/sys/arch/alpha/tc/mcclock_ioasic.c
index 2709092949d..da7e8e7a4f6 100644
--- a/sys/arch/alpha/tc/mcclock_ioasic.c
+++ b/sys/arch/alpha/tc/mcclock_ioasic.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: mcclock_ioasic.c,v 1.5 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: mcclock_ioasic.c,v 1.3 1996/12/05 01:39:42 cgd Exp $ */
+/* $OpenBSD: mcclock_ioasic.c,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: mcclock_ioasic.c,v 1.9 2000/07/04 02:37:51 nisimura Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -33,10 +33,9 @@
#include <sys/systm.h>
#include <sys/device.h>
-#include <alpha/alpha/clockvar.h>
-#include <alpha/alpha/mcclockvar.h>
+#include <dev/dec/clockvar.h>
+#include <dev/dec/mcclockvar.h>
#include <dev/ic/mc146818reg.h>
-#include <dev/tc/tcreg.h>
#include <dev/tc/tcvar.h>
#include <dev/tc/ioasicvar.h> /* XXX */
@@ -51,11 +50,7 @@ struct mcclock_ioasic_softc {
struct mcclock_ioasic_clockdatum *sc_dp;
};
-#ifdef __BROKEN_INDIRECT_CONFIG
int mcclock_ioasic_match(struct device *, void *, void *);
-#else
-int mcclock_ioasic_match(struct device *, struct cfdata *, void *);
-#endif
void mcclock_ioasic_attach(struct device *, struct device *, void *);
struct cfattach mcclock_ioasic_ca = {
@@ -73,12 +68,7 @@ const struct mcclock_busfns mcclock_ioasic_busfns = {
int
mcclock_ioasic_match(parent, match, aux)
struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *match;
-#else
- struct cfdata *match;
-#endif
- void *aux;
+ void *match, *aux;
{
struct ioasicdev_attach_args *d = aux;
diff --git a/sys/arch/alpha/tc/scc.c b/sys/arch/alpha/tc/scc.c
index bfba120fca3..b1734b53296 100644
--- a/sys/arch/alpha/tc/scc.c
+++ b/sys/arch/alpha/tc/scc.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: scc.c,v 1.14 2002/03/15 01:20:04 millert Exp $ */
-/* $NetBSD: scc.c,v 1.28 1996/12/05 01:39:43 cgd Exp $ */
+/* $OpenBSD: scc.c,v 1.15 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: scc.c,v 1.58 2002/03/17 19:40:27 atatat Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
@@ -11,7 +11,7 @@
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
@@ -64,9 +64,6 @@
* @(#)scc.c 8.2 (Berkeley) 11/30/93
*/
-#include "scc.h"
-
-#if NSCC > 0
/*
* Intel 82530 dual usart chip driver. Supports the serial port(s) on the
* Personal DECstation 5000/xx and DECstation 5000/1xx, plus the keyboard
@@ -81,7 +78,6 @@
#include <sys/tty.h>
#include <sys/proc.h>
#include <sys/buf.h>
-#include <sys/conf.h>
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/kernel.h>
@@ -94,42 +90,27 @@
#include <alpha/tc/sccreg.h>
#include <alpha/tc/sccvar.h>
-#include <machine/autoconf.h> /* For the badaddr() proto */
#include <machine/rpb.h>
+#include <machine/conf.h>
#include <dev/tc/tcvar.h>
-#include <alpha/tc/ioasicreg.h>
+#include <dev/tc/ioasicreg.h>
#include <dev/tc/ioasicvar.h>
#undef SCCDEV
#define SCCDEV 15 /* XXX */
-/*
- * rcons glass-tty console (as used on pmax) needs lk-201 ASCII input
- * support from the tty drivers. This is ugly and broken and won't
- * compile on Alphas.
- */
+#define raster_console() 1 /* Treat test for cn_screen as true */
+#define CONSOLE_ON_UNIT(unit) 0 /* No raster console on Alphas */
#define NSCCLINE (NSCC*2)
#define SCCUNIT(dev) (minor(dev) >> 1)
#define SCCLINE(dev) (minor(dev) & 0x1)
-/* QVSS-compatible in-kernel X input event parser, pointer tracker */
-void (*sccDivertXInput)(int cc); /* X windows keyboard input routine */
-void (*sccMouseEvent)(int); /* X windows mouse motion event routine */
-void (*sccMouseButtons)(int); /* X windows mouse buttons event routine */
#ifdef DEBUG
int debugChar;
#endif
-struct pdma {
- void *p_addr;
- char *p_mem;
- char *p_end;
- int p_arg;
- void (*p_fcn)(struct tty *tp);
-};
-
struct scc_softc {
struct device sc_dv;
struct pdma scc_pdma[2];
@@ -192,11 +173,7 @@ struct speedtab sccspeedtab[] = {
#endif
/* Definition of the driver for autoconfig. */
-#ifdef __BROKEN_INDIRECT_CONFIG
int sccmatch(struct device *, void *, void *);
-#else
-int sccmatch(struct device *, struct cfdata *, void *);
-#endif
void sccattach(struct device *, struct device *, void *);
struct cfattach scc_ca = {
@@ -209,104 +186,46 @@ struct cfdriver scc_cd = {
cdev_decl(scc);
+int sccGetc(dev_t);
+void sccPutc(dev_t, int);
+void sccPollc(dev_t, int);
+int sccparam(struct tty *, struct termios *);
+void sccstart(struct tty *);
+
+int sccmctl(struct scc_softc *, int, int, int);
int cold_sccparam(struct tty *, struct termios *,
- struct scc_softc *sc);
-int sccGetc(dev_t);
-void sccPollc(dev_t, int);
-void sccPutc(dev_t, int);
-int sccintr(void *);
-int sccmctl(dev_t, int, int);
-int sccparam(struct tty *, struct termios *);
-void sccreset(struct scc_softc *);
-void sccstart(struct tty *);
-void scc_alphaintr(int);
-void scc_modem_intr(dev_t);
+ struct scc_softc *sc, int line);
+
#ifdef SCC_DEBUG
-void scc_rr(char *, scc_regmap_t *);
+void rr(char *, scc_regmap_t *);
#endif
+void scc_modem_intr(dev_t);
+void sccreset(struct scc_softc *);
+
+int sccintr(void *);
+void scc_alphaintr(int);
/*
* console variables, for using serial console while still cold and
* autoconfig has not attached the scc device.
*/
scc_regmap_t *scc_cons_addr = 0;
-static struct scc_softc coldcons_softc;
-static struct consdev scccons = {
+struct consdev scccons = {
NULL, NULL, sccGetc, sccPutc, sccPollc, NULL, NODEV, 0
};
-void scc_consinit(dev_t dev, scc_regmap_t *sccaddr);
-void scc_oconsinit(struct scc_softc *, dev_t);
-
-
-/*
- * Set up a given unit as a serial console device.
- * We need console output when cold, and before any device is configured.
- * Should be callable when cold, to reset the chip and set parameters
- * for a remote (serial) console or kgdb line.
- * XXX
- * As most DECstations only bring out one rs-232 lead from an SCC
- * to the bulkhead, and use the other for mouse and keyboard, we
- * only allow one unit per SCC to be console.
- */
-void
-scc_consinit(dev, sccaddr)
- dev_t dev;
- scc_regmap_t *sccaddr;
-{
- struct scc_softc *sc;
- struct termios cterm;
- struct tty ctty;
- int s;
-
- /* Save address in case we're cold. */
- if (cold && scc_cons_addr == 0) {
- scc_cons_addr = sccaddr;
- sc = &coldcons_softc;
- coldcons_softc.scc_pdma[0].p_addr = sccaddr;
- coldcons_softc.scc_pdma[1].p_addr = sccaddr;
- } else {
- /* being called from sccattach() to reset console */
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- }
-
- /* Reset chip. */
- sccreset(sc);
- /* XXX make sure sccreset() called only once for this chip? */
-
- /* set console-line parameters */
- s = spltty();
- ctty.t_dev = dev;
- scccons.cn_dev = dev;
- cterm.c_cflag = CS8;
- cterm.c_ospeed = cterm.c_ispeed = 9600;
- (void) cold_sccparam(&ctty, &cterm, sc);
- *cn_tab = scccons;
- DELAY(1000);
- splx(s);
-}
/*
* Test to see if device is present.
* Return true if found.
*/
int
-#ifdef __BROKEN_INDIRECT_CONFIG
-sccmatch(parent, cfdata, aux)
-#else
-sccmatch(parent, cf, aux)
-#endif
+sccmatch(parent, vcf, aux)
struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *cfdata;
-#else
- struct cfdata *cf;
-#endif
- void *aux;
+ void *vcf, *aux;
{
-#ifdef __BROKEN_INDIRECT_CONFIG
- struct cfdata *cf = cfdata;
-#endif
+ extern struct cfdriver ioasic_cd; /* XXX */
struct ioasicdev_attach_args *d = aux;
+ struct cfdata *cf = vcf;
void *sccaddr;
if (parent->dv_cfdata->cf_driver != &ioasic_cd) {
@@ -321,8 +240,12 @@ sccmatch(parent, cf, aux)
(strncmp(d->iada_modname, "scc", TC_ROM_LLEN)!= 0))
return (0);
- /* XXX MATCH CFLOC */
- if (cf->cf_unit >= NSCC)
+ /*
+ * Check user-specified offset against the ioasic offset.
+ * Allow it to be wildcarded.
+ */
+ if (cf->cf_loc[0] != -1 &&
+ cf->cf_loc[0] != d->iada_offset)
return (0);
/* Get the address, and check it for validity. */
@@ -345,18 +268,18 @@ scc_alphaintr(onoff)
int onoff;
{
if (onoff) {
- *(volatile u_int *)IOASIC_REG_IMSK(ioasic_base) |=
+ *(volatile u_int *)(ioasic_base + IOASIC_IMSK) |=
IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0;
#if !defined(DEC_3000_300) && defined(SCC_DMA)
- *(volatile u_int *)IOASIC_REG_CSR(ioasic_base) |=
+ *(volatile u_int *)(ioasic_base + IOASIC_CSR) |=
IOASIC_CSR_DMAEN_T1 | IOASIC_CSR_DMAEN_R1 |
IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2;
#endif
} else {
- *(volatile u_int *)IOASIC_REG_IMSK(ioasic_base) &=
+ *(volatile u_int *)(ioasic_base + IOASIC_IMSK) &=
~(IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0);
#if !defined(DEC_3000_300) && defined(SCC_DMA)
- *(volatile u_int *)IOASIC_REG_CSR(ioasic_base) &=
+ *(volatile u_int *)(ioasic_base + IOASIC_CSR) &=
~(IOASIC_CSR_DMAEN_T1 | IOASIC_CSR_DMAEN_R1 |
IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2);
#endif
@@ -379,7 +302,9 @@ sccattach(parent, self, aux)
struct termios cterm;
struct tty ctty;
int s;
- extern int cputype;
+ int unit;
+
+ unit = sc->sc_dv.dv_unit;
/* Get the address, and check it for validity. */
sccaddr = (void *)d->iada_addr;
@@ -395,15 +320,9 @@ sccattach(parent, self, aux)
* For a remote console, wait a while for previous output to
* complete.
*/
-#ifdef TK_NOTYET
- if (major(cn_tab.cn_dev) == SCCDEV && cn_tab.cn_screen == 0 &&
- SCCUNIT(cn_tab.cn_dev) == cp->pmax_unit)
- DELAY(10000);
-#else
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0))
DELAY(10000);
-#endif
pdp = &sc->scc_pdma[0];
/* init pseudo DMA structures */
@@ -413,12 +332,12 @@ sccattach(parent, self, aux)
if (cntr == 0)
tty_attach(tp);
pdp->p_arg = (long)tp;
- pdp->p_fcn = (void (*)(struct tty*))0;
+ pdp->p_fcn = (void (*)__P((struct tty*)))0;
tp->t_dev = (dev_t)((sc->sc_dv.dv_unit << 1) | cntr);
pdp++;
}
/* What's the warning here? Defaulting to softCAR on line 2? */
- sc->scc_softCAR = 0x2; /* XXX */
+ sc->scc_softCAR = sc->sc_dv.dv_cfdata->cf_flags | 0x2; /* XXX */
/* reset chip, initialize register-copies in softc */
sccreset(sc);
@@ -426,50 +345,14 @@ sccattach(parent, self, aux)
/*
* Special handling for consoles.
*/
- if (0 /* cn_tab.cn_screen */) {
- if (1 /* cn_tab.cn_kbdgetc == sccGetc */) {
- if (sc->sc_dv.dv_unit == 1) {
- s = spltty();
- ctty.t_dev = makedev(SCCDEV, SCCKBD_PORT);
- cterm.c_cflag = CS8;
- cterm.c_ospeed = cterm.c_ispeed = 4800;
- (void) sccparam(&ctty, &cterm);
- DELAY(10000);
-#ifdef notyet
- /*
- * For some reason doing this hangs the 3min
- * during booting. Fortunately the keyboard
- * works ok without it.
- */
- KBDReset(ctty.t_dev, sccPutc);
-#endif
- DELAY(10000);
- splx(s);
- } else if (sc->sc_dv.dv_unit == 0) {
- s = spltty();
- ctty.t_dev = makedev(SCCDEV, SCCMOUSE_PORT);
- cterm.c_cflag = CS8 | PARENB | PARODD;
- cterm.c_ospeed = cterm.c_ispeed = 4800;
- (void) sccparam(&ctty, &cterm);
-#ifdef TK_NOTYET
- DELAY(10000);
- MouseInit(ctty.t_dev, sccPutc, sccGetc);
- DELAY(10000);
-#endif
- splx(s);
- }
- }
- } else if (1 /* SCCUNIT(cn_tab.cn_dev) == sc->sc_dv.dv_unit */) {
+ if (1 /* SCCUNIT(cn_tab.cn_dev) == sc->sc_dv.dv_unit */) {
s = spltty();
- ctty.t_dev = makedev(SCCDEV,
- sc->sc_dv.dv_unit == 0 ? SCCCOMM2_PORT : SCCCOMM3_PORT);
cterm.c_cflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8;
cterm.c_ospeed = cterm.c_ispeed = 9600;
- (void) sccparam(&ctty, &cterm);
+ (void) cold_sccparam(&ctty, &cterm, sc,
+ SCCLINE((sc->sc_dv.dv_unit == 0) ?
+ SCCCOMM2_PORT : SCCCOMM3_PORT));
DELAY(1000);
-#ifdef TK_NOTYET
- cn_tab.cn_disabled = 0;
-#endif
splx(s);
}
@@ -479,10 +362,12 @@ sccattach(parent, self, aux)
*/
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0)) {
+ if (alpha_donot_kludge_scc)
+ printf("\nSWITCHING TO SERIAL CONSOLE!\n");
cn_tab = &scccons;
cn_tab->cn_dev = makedev(SCCDEV, sc->sc_dv.dv_unit * 2);
- printf(": console\n");
+ printf("%s console\n", alpha_donot_kludge_scc ? "\n***" : ":");
/* wire carrier for console. */
sc->scc_softCAR |= SCCLINE(cn_tab->cn_dev);
@@ -566,6 +451,7 @@ sccopen(dev, flag, mode, p)
register struct tty *tp;
register int unit, line;
int s, error = 0;
+ int firstopen = 0;
unit = SCCUNIT(dev);
if (unit >= scc_cd.cd_ndevs)
@@ -586,8 +472,8 @@ sccopen(dev, flag, mode, p)
tp->t_param = sccparam;
tp->t_dev = dev;
if ((tp->t_state & TS_ISOPEN) == 0) {
- tp->t_state |= TS_WOPEN;
ttychars(tp);
+ firstopen = 1;
#ifndef PORTSELECTOR
if (tp->t_ispeed == 0) {
#endif
@@ -605,19 +491,23 @@ sccopen(dev, flag, mode, p)
ttsetwater(tp);
} else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0)
return (EBUSY);
- (void) sccmctl(dev, DML_DTR, DMSET);
+ (void) sccmctl(sc, SCCLINE(dev), DML_DTR, DMSET);
s = spltty();
while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
!(tp->t_state & TS_CARR_ON)) {
tp->t_state |= TS_WOPEN;
- if ((error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0)) != 0)
+ error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
+ ttopen, 0);
+ tp->t_state &= ~TS_WOPEN;
+ if (error != 0)
break;
}
splx(s);
if (error)
return (error);
- return ((*linesw[tp->t_line].l_open)(dev, tp));
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+
+ return (error);
}
/*ARGSUSED*/
@@ -640,7 +530,7 @@ sccclose(dev, flag, mode, p)
(*linesw[tp->t_line].l_close)(tp, flag);
if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) ||
!(tp->t_state & TS_ISOPEN))
- (void) sccmctl(dev, 0, DMSET);
+ (void) sccmctl(sc, line, 0, DMSET);
return (ttyclose(tp));
}
@@ -722,27 +612,27 @@ sccioctl(dev, cmd, data, flag, p)
break;
case TIOCSDTR:
- (void) sccmctl(dev, DML_DTR|DML_RTS, DMBIS);
+ (void) sccmctl(sc, line, DML_DTR|DML_RTS, DMBIS);
break;
case TIOCCDTR:
- (void) sccmctl(dev, DML_DTR|DML_RTS, DMBIC);
+ (void) sccmctl(sc, line, DML_DTR|DML_RTS, DMBIC);
break;
case TIOCMSET:
- (void) sccmctl(dev, *(int *)data, DMSET);
+ (void) sccmctl(sc, line, *(int *)data, DMSET);
break;
case TIOCMBIS:
- (void) sccmctl(dev, *(int *)data, DMBIS);
+ (void) sccmctl(sc, line, *(int *)data, DMBIS);
break;
case TIOCMBIC:
- (void) sccmctl(dev, *(int *)data, DMBIC);
+ (void) sccmctl(sc, line, *(int *)data, DMBIC);
break;
case TIOCMGET:
- *(int *)data = sccmctl(dev, 0, DMGET);
+ *(int *)data = sccmctl(sc, line, 0, DMGET);
break;
default:
@@ -765,7 +655,7 @@ sccparam(tp, t)
/* Extract the softc and call cold_sccparam to do all the work. */
sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)];
- return cold_sccparam(tp, t, sc);
+ return cold_sccparam(tp, t, sc, SCCLINE(tp->t_dev));
}
@@ -773,13 +663,13 @@ sccparam(tp, t)
* Do what sccparam() (t_param entry point) does, but callable when cold.
*/
int
-cold_sccparam(tp, t, sc)
+cold_sccparam(tp, t, sc, line)
register struct tty *tp;
register struct termios *t;
register struct scc_softc *sc;
+ register int line;
{
register scc_regmap_t *regs;
- register int line;
register u_char value, wvalue;
register int cflag = t->c_cflag;
int ospeed;
@@ -798,27 +688,15 @@ cold_sccparam(tp, t, sc)
/*
* Handle console specially.
*/
-#ifdef HAVE_RCONS
- if (cn_tab->cn_getc == LKgetc) {
- if (minor(tp->t_dev) == SCCKBD_PORT) {
- cflag = CS8;
- ospeed = ttspeedtab(4800, sccspeedtab);
- } else if (minor(tp->t_dev) == SCCMOUSE_PORT) {
- cflag = CS8 | PARENB | PARODD;
- ospeed = ttspeedtab(4800, sccspeedtab);
- }
- } else if (tp->t_dev == cn_tab->cn_dev)
-#endif /*HAVE_RCONS*/
{
cflag = CS8;
ospeed = ttspeedtab(9600, sccspeedtab);
}
if (ospeed == 0) {
- (void) sccmctl(tp->t_dev, 0, DMSET); /* hang up line */
+ (void) sccmctl(sc, line, 0, DMSET); /* hang up line */
return (0);
}
- line = SCCLINE(tp->t_dev);
regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
/*
@@ -903,12 +781,10 @@ cold_sccparam(tp, t, sc)
value = sc->scc_wreg[line].wr14;
SCC_WRITE_REG(regs, line, SCC_WR14, value);
-#ifdef alpha
- if (SCCUNIT(tp->t_dev) == 1) {
+ if (sc->sc_dv.dv_unit == 1) {
/* On unit one, on the flamingo, modem control is floating! */
value = ZSWR15_BREAK_IE;
} else
-#endif
{
value = ZSWR15_BREAK_IE | ZSWR15_CTS_IE | ZSWR15_DCD_IE;
}
@@ -927,9 +803,7 @@ cold_sccparam(tp, t, sc)
SCC_WRITE_REG(regs, line, SCC_WR1, sc->scc_wreg[line].wr1);
tc_mb();
-#ifdef alpha
scc_alphaintr(1); /* XXX XXX XXX */
-#endif /*alpha*/
return (0);
}
@@ -981,10 +855,7 @@ sccintr(xxxsc)
(caddr_t) tp->t_outq.c_cf);
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
}
- if (tp->t_line)
- (*linesw[tp->t_line].l_start)(tp);
- else
- sccstart(tp);
+ (*linesw[tp->t_line].l_start)(tp);
if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {
SCC_READ_REG(regs, chan, SCC_RR15, cc);
cc &= ~ZSWR15_TXUEOM_IE;
@@ -1015,39 +886,6 @@ sccintr(xxxsc)
}
}
- /*
- * Keyboard needs special treatment.
- */
- if (tp == scctty(makedev(SCCDEV, SCCKBD_PORT)) /* && cn_tab.cn_screen */) {
-#ifdef KADB
- if (cc == LK_DO) {
- spl0();
- kdbpanic();
- return 0; /* XXX */
- }
-#endif
-#ifdef DEBUG
- debugChar = cc;
-#endif
- if (sccDivertXInput) {
- (*sccDivertXInput)(cc);
- continue;
- }
-#ifdef TK_NOTYET
- if ((cc = kbdMapChar(cc)) < 0)
- continue;
-#endif
- /*
- * Now for mousey
- */
- } else if (tp == scctty(makedev(SCCDEV, SCCMOUSE_PORT)) &&
- sccMouseButtons) {
-#ifdef HAVE_RCONS
- /*XXX*/
- mouseInput(cc);
-#endif
- continue;
- }
if (!(tp->t_state & TS_ISOPEN)) {
wakeup((caddr_t)&tp->t_rawq);
#ifdef PORTSELECTOR
@@ -1100,7 +938,7 @@ sccstart(tp)
if (tp->t_outq.c_cc == 0)
goto out;
/* handle console specially */
- if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) /* && cn_tab.cn_screen */) {
+ if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) && raster_console()) {
while (tp->t_outq.c_cc > 0) {
cc = getc(&tp->t_outq) & 0x7f;
cnputc(cc);
@@ -1174,18 +1012,15 @@ sccstop(tp, flag)
}
int
-sccmctl(dev, bits, how)
- dev_t dev;
- int bits, how;
+sccmctl(sc, line, bits, how)
+ struct scc_softc *sc;
+ int line, bits, how;
{
- register struct scc_softc *sc;
register scc_regmap_t *regs;
- register int line, mbits;
+ register int mbits;
register u_char value;
int s;
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- line = SCCLINE(dev);
regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
s = spltty();
/*
@@ -1217,7 +1052,7 @@ sccmctl(dev, bits, how)
break;
case DMGET:
- splx(s);
+ (void) splx(s);
return (mbits);
}
if (line == SCC_CHANNEL_B) {
@@ -1230,7 +1065,7 @@ sccmctl(dev, bits, how)
}
if ((mbits & DML_DTR) || (sc->scc_softCAR & (1 << line)))
sc->scc_tty[line]->t_state |= TS_CARR_ON;
- splx(s);
+ (void) splx(s);
return (mbits);
}
@@ -1262,20 +1097,17 @@ scc_modem_intr(dev)
car = value & ZSRR0_DCD;
}
- /*
- * The pmax driver follows carrier-detect. The Alpha does not.
- * XXX Why doesn't the Alpha driver follow carrier-detect?
- * (in the Alpha driver, this is an "#ifdef notdef").
- * Is it related to console handling?
- */
-#ifdef notdef
- if (car) {
- /* carrier present */
- if (!(tp->t_state & TS_CARR_ON))
- (void)(*linesw[tp->t_line].l_modem)(tp, 1);
- } else if (tp->t_state & TS_CARR_ON)
- (void)(*linesw[tp->t_line].l_modem)(tp, 0);
+ /* Break on serial console drops into the debugger */
+ if ((value & ZSRR0_BREAK) && CONSOLE_ON_UNIT(sc->sc_dv.dv_unit)) {
+#ifdef DDB
+ splx(s); /* spl0()? */
+ Debugger();
+ return;
+#else
+ /* XXX maybe fall back to PROM? */
#endif
+ }
+
splx(s);
}
@@ -1302,9 +1134,7 @@ sccGetc(dev)
if (!regs)
return (0);
-
s = splhigh();
-
for (;;) {
SCC_READ_REG(regs, line, SCC_RR0, value);
if (value & ZSRR0_RX_READY) {
@@ -1340,7 +1170,6 @@ sccPutc(dev, c)
int s;
s = splhigh();
-
line = SCCLINE(dev);
if (cold && scc_cons_addr) {
regs = scc_cons_addr;
@@ -1382,7 +1211,7 @@ sccPollc(dev, on)
#ifdef SCC_DEBUG
void
-scc_rr(msg, regs)
+rr(msg, regs)
char *msg;
scc_regmap_t *regs;
{
@@ -1416,4 +1245,3 @@ scc_rr(msg, regs)
r0, r1, r2, r10, r15);
}
#endif /* SCC_DEBUG */
-#endif /* NSCC */
diff --git a/sys/arch/alpha/tc/sccreg.h b/sys/arch/alpha/tc/sccreg.h
index f51a1083921..137a255ff53 100644
--- a/sys/arch/alpha/tc/sccreg.h
+++ b/sys/arch/alpha/tc/sccreg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: sccreg.h,v 1.3 1996/10/30 22:41:12 niklas Exp $ */
-/* $NetBSD: sccreg.h,v 1.2 1995/04/11 03:41:10 mycroft Exp $ */
+/* $OpenBSD: sccreg.h,v 1.4 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: sccreg.h,v 1.3 1997/04/06 22:30:30 cgd Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
diff --git a/sys/arch/alpha/tc/sccvar.h b/sys/arch/alpha/tc/sccvar.h
index b1fae134466..8f24120645a 100644
--- a/sys/arch/alpha/tc/sccvar.h
+++ b/sys/arch/alpha/tc/sccvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: sccvar.h,v 1.4 1997/01/24 19:58:16 niklas Exp $ */
-/* $NetBSD: sccvar.h,v 1.4 1996/11/16 00:40:14 cgd Exp $ */
+/* $OpenBSD: sccvar.h,v 1.5 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: sccvar.h,v 1.7 2001/08/26 16:39:56 simonb Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
@@ -100,6 +100,15 @@ typedef struct {
#define scc_set_datum(d, v) \
do { (d) = (volatile unsigned int)(v) << 8; alpha_mb(); DELAY(5); } while (0)
+/* From <pmax/dev/pdma.h>. */
+struct pdma {
+ void *p_addr;
+ char *p_mem;
+ char *p_end;
+ int p_arg;
+ void (*p_fcn)(struct tty *tp);
+};
+
/*
* Minor device numbers for scc. Weird because B channel comes first and
* the A channels are wired for keyboard/mouse and the B channels for the
@@ -109,3 +118,5 @@ typedef struct {
#define SCCMOUSE_PORT 0x1
#define SCCCOMM3_PORT 0x2
#define SCCKBD_PORT 0x3
+
+int alpha_donot_kludge_scc;
diff --git a/sys/arch/alpha/tc/tc_3000_300.c b/sys/arch/alpha/tc/tc_3000_300.c
index 81341c2842c..fabab7d55c5 100644
--- a/sys/arch/alpha/tc/tc_3000_300.c
+++ b/sys/arch/alpha/tc/tc_3000_300.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_300.c,v 1.8 2002/03/14 03:15:51 millert Exp $ */
-/* $NetBSD: tc_3000_300.c,v 1.12 1996/10/13 03:00:37 christos Exp $ */
+/* $OpenBSD: tc_3000_300.c,v 1.9 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_3000_300.c,v 1.26 2001/07/27 00:25:21 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -31,23 +31,23 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <machine/autoconf.h>
#include <machine/pte.h>
-#ifndef EVCNT_COUNTERS
#include <machine/intrcnt.h>
-#endif
#include <dev/tc/tcvar.h>
+#include <dev/tc/ioasicreg.h>
#include <alpha/tc/tc_conf.h>
#include <alpha/tc/tc_3000_300.h>
-#include <alpha/tc/ioasicreg.h>
-void tc_3000_300_intr_setup(void);
-void tc_3000_300_intr_establish(struct device *, void *,
- tc_intrlevel_t, int (*)(void *), void *);
-void tc_3000_300_intr_disestablish(struct device *, void *);
-void tc_3000_300_iointr(void *, unsigned long);
+#include "wsdisplay.h"
+#include "sfb.h"
+
+#if NSFB > 0
+extern int sfb_cnattach(tc_addr_t);
+#endif
int tc_3000_300_intrnull(void *);
@@ -65,17 +65,19 @@ int tc_3000_300_intrnull(void *);
struct tc_slotdesc tc_3000_300_slots[] = {
{ KV(0x100000000), C(TC_3000_300_DEV_OPT0), }, /* 0 - opt slot 0 */
{ KV(0x120000000), C(TC_3000_300_DEV_OPT1), }, /* 1 - opt slot 1 */
- { KV(0x180000000), C(TC_3000_300_DEV_BOGUS), }, /* 2 - TCDS ASIC */
- { KV(0x1a0000000), C(TC_3000_300_DEV_BOGUS), }, /* 3 - IOCTL ASIC */
- { KV(0x1c0000000), C(TC_3000_300_DEV_CXTURBO), }, /* 4 - CXTurbo */
+ { KV(0x140000000), C(TC_3000_300_DEV_BOGUS), }, /* 2 - unused */
+ { KV(0x160000000), C(TC_3000_300_DEV_BOGUS), }, /* 3 - unused */
+ { KV(0x180000000), C(TC_3000_300_DEV_BOGUS), }, /* 4 - TCDS ASIC */
+ { KV(0x1a0000000), C(TC_3000_300_DEV_BOGUS), }, /* 5 - IOCTL ASIC */
+ { KV(0x1c0000000), C(TC_3000_300_DEV_BOGUS), }, /* 6 - CXTurbo */
};
int tc_3000_300_nslots =
sizeof(tc_3000_300_slots) / sizeof(tc_3000_300_slots[0]);
struct tc_builtin tc_3000_300_builtins[] = {
- { "PMAGB-BA", 4, 0x02000000, C(TC_3000_300_DEV_CXTURBO), },
- { "FLAMG-IO", 3, 0x00000000, C(TC_3000_300_DEV_IOASIC), },
- { "PMAZ-DS ", 2, 0x00000000, C(TC_3000_300_DEV_TCDS), },
+ { "PMAGB-BA", 6, 0x02000000, C(TC_3000_300_DEV_CXTURBO), },
+ { "FLAMG-IO", 5, 0x00000000, C(TC_3000_300_DEV_IOASIC), },
+ { "PMAZ-DS ", 4, 0x00000000, C(TC_3000_300_DEV_TCDS), },
};
int tc_3000_300_nbuiltins =
sizeof(tc_3000_300_builtins) / sizeof(tc_3000_300_builtins[0]);
@@ -83,18 +85,20 @@ int tc_3000_300_nbuiltins =
struct tcintr {
int (*tci_func)(void *);
void *tci_arg;
+ struct evcnt tci_evcnt;
} tc_3000_300_intr[TC_3000_300_NCOOKIES];
void
tc_3000_300_intr_setup()
{
volatile u_int32_t *imskp;
+ char *cp;
u_long i;
/*
* Disable all interrupts that we can (can't disable builtins).
*/
- imskp = (volatile u_int32_t *)IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
+ imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
*imskp &= ~(IOASIC_INTR_300_OPT0 | IOASIC_INTR_300_OPT1);
/*
@@ -103,9 +107,32 @@ tc_3000_300_intr_setup()
for (i = 0; i < TC_3000_300_NCOOKIES; i++) {
tc_3000_300_intr[i].tci_func = tc_3000_300_intrnull;
tc_3000_300_intr[i].tci_arg = (void *)i;
+
+ cp = malloc(12, M_DEVBUF, M_NOWAIT);
+ if (cp == NULL)
+ panic("tc_3000_300_intr_setup");
+ sprintf(cp, "slot %lu", i);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach_dynamic(&tc_3000_300_intr[i].tci_evcnt,
+ EVCNT_TYPE_INTR, NULL, "tc", cp);
+#endif
}
}
+const struct evcnt *
+tc_3000_300_intr_evcnt(tcadev, cookie)
+ struct device *tcadev;
+ void *cookie;
+{
+ u_long dev = (u_long)cookie;
+
+#ifdef DIAGNOSTIC
+ /* XXX bounds-check cookie. */
+#endif
+
+ return (&tc_3000_300_intr[dev].tci_evcnt);
+}
+
void
tc_3000_300_intr_establish(tcadev, cookie, level, func, arg)
struct device *tcadev;
@@ -121,12 +148,12 @@ tc_3000_300_intr_establish(tcadev, cookie, level, func, arg)
#endif
if (tc_3000_300_intr[dev].tci_func != tc_3000_300_intrnull)
- panic("tc_3000_300_intr_establish: cookie %d twice", dev);
+ panic("tc_3000_300_intr_establish: cookie %lu twice", dev);
tc_3000_300_intr[dev].tci_func = func;
tc_3000_300_intr[dev].tci_arg = arg;
- imskp = (volatile u_int32_t *)IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
+ imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
switch (dev) {
case TC_3000_300_DEV_OPT0:
*imskp |= IOASIC_INTR_300_OPT0;
@@ -153,10 +180,10 @@ tc_3000_300_intr_disestablish(tcadev, cookie)
#endif
if (tc_3000_300_intr[dev].tci_func == tc_3000_300_intrnull)
- panic("tc_3000_300_intr_disestablish: cookie %d bad intr",
+ panic("tc_3000_300_intr_disestablish: cookie %lu bad intr",
dev);
- imskp = (volatile u_int32_t *)IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
+ imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
switch (dev) {
case TC_3000_300_DEV_OPT0:
*imskp &= ~IOASIC_INTR_300_OPT0;
@@ -183,8 +210,8 @@ tc_3000_300_intrnull(val)
}
void
-tc_3000_300_iointr(framep, vec)
- void *framep;
+tc_3000_300_iointr(arg, vec)
+ void *arg;
unsigned long vec;
{
u_int32_t tcir, ioasicir, ioasicimr;
@@ -207,9 +234,9 @@ tc_3000_300_iointr(framep, vec)
/* find out what interrupts/errors occurred */
tcir = *(volatile u_int32_t *)TC_3000_300_IR;
ioasicir = *(volatile u_int32_t *)
- IOASIC_REG_INTR(DEC_3000_300_IOASIC_ADDR);
+ (DEC_3000_300_IOASIC_ADDR + IOASIC_INTR);
ioasicimr = *(volatile u_int32_t *)
- IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
+ (DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
tc_mb();
/* Ignore interrupts that aren't enabled out. */
@@ -223,11 +250,10 @@ tc_3000_300_iointr(framep, vec)
ifound = 0;
#ifdef EVCNT_COUNTERS
- /* No interrupt counting via evcnt counters */
- XXX BREAK HERE XXX
-#else /* !EVCNT_COUNTERS */
+#define INCRINTRCNT(slot) tc_3000_300_intr[slot].tci_evcnt.ev_count++
+#else
#define INCRINTRCNT(slot) intrcnt[INTRCNT_KN16 + slot]++
-#endif /* EVCNT_COUNTERS */
+#endif
#define CHECKINTR(slot, flag) \
if (flag) { \
@@ -264,3 +290,34 @@ tc_3000_300_iointr(framep, vec)
#endif
} while (ifound);
}
+
+#if NWSDISPLAY > 0
+/*
+ * tc_3000_300_fb_cnattach --
+ * Attempt to map the CTB output device to a slot and attach the
+ * framebuffer as the output side of the console.
+ */
+int
+tc_3000_300_fb_cnattach(turbo_slot)
+ u_int64_t turbo_slot;
+{
+ u_int32_t output_slot;
+
+ output_slot = turbo_slot & 0xffffffff;
+
+ if (output_slot >= tc_3000_300_nslots) {
+ return EINVAL;
+ }
+
+ if (output_slot == 0) {
+#if NSFB > 0
+ sfb_cnattach(KV(0x1c0000000) + 0x02000000);
+ return 0;
+#else
+ return ENXIO;
+#endif
+ }
+
+ return tc_fb_cnattach(tc_3000_300_slots[output_slot-1].tcs_addr);
+}
+#endif /* NWSDISPLAY */
diff --git a/sys/arch/alpha/tc/tc_3000_300.h b/sys/arch/alpha/tc/tc_3000_300.h
index 475eefad00b..b91f26b087f 100644
--- a/sys/arch/alpha/tc/tc_3000_300.h
+++ b/sys/arch/alpha/tc/tc_3000_300.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_300.h,v 1.4 1996/10/30 22:41:17 niklas Exp $ */
-/* $NetBSD: tc_3000_300.h,v 1.2 1995/12/20 00:43:28 cgd Exp $ */
+/* $OpenBSD: tc_3000_300.h,v 1.5 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_3000_300.h,v 1.4 1998/10/22 01:03:09 briggs Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -60,3 +60,5 @@
#define TC_3000_300_DEV_BOGUS -1
#define TC_3000_300_NCOOKIES 5
+
+extern int tc_3000_300_fb_cnattach(u_int64_t);
diff --git a/sys/arch/alpha/tc/tc_3000_500.c b/sys/arch/alpha/tc/tc_3000_500.c
index 79c987a8b27..a1e03986559 100644
--- a/sys/arch/alpha/tc/tc_3000_500.c
+++ b/sys/arch/alpha/tc/tc_3000_500.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_500.c,v 1.9 2002/03/14 03:15:51 millert Exp $ */
-/* $NetBSD: tc_3000_500.c,v 1.12 1996/11/15 23:59:00 cgd Exp $ */
+/* $OpenBSD: tc_3000_500.c,v 1.10 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_3000_500.c,v 1.24 2001/07/27 00:25:21 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -31,17 +31,24 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <machine/autoconf.h>
#include <machine/pte.h>
-#ifndef EVCNT_COUNTERS
+#include <machine/rpb.h>
#include <machine/intrcnt.h>
-#endif
#include <dev/tc/tcvar.h>
#include <alpha/tc/tc_conf.h>
#include <alpha/tc/tc_3000_500.h>
+#include "wsdisplay.h"
+#include "sfb.h"
+
+#if NSFB > 0
+extern int sfb_cnattach(tc_addr_t);
+#endif
+
void tc_3000_500_intr_setup(void);
void tc_3000_500_intr_establish(struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *);
@@ -49,6 +56,7 @@ void tc_3000_500_intr_disestablish(struct device *, void *);
void tc_3000_500_iointr(void *, unsigned long);
int tc_3000_500_intrnull(void *);
+int tc_3000_500_fb_cnattach(u_int64_t);
#define C(x) ((void *)(u_long)x)
#define KV(x) (ALPHA_PHYS_TO_K0SEG(x))
@@ -96,6 +104,7 @@ u_int32_t tc_3000_500_intrbits[TC_3000_500_NCOOKIES] = {
struct tcintr {
int (*tci_func)(void *);
void *tci_arg;
+ struct evcnt tci_evcnt;
} tc_3000_500_intr[TC_3000_500_NCOOKIES];
u_int32_t tc_3000_500_imask; /* intrs we want to ignore; mirrors IMR. */
@@ -103,6 +112,7 @@ u_int32_t tc_3000_500_imask; /* intrs we want to ignore; mirrors IMR. */
void
tc_3000_500_intr_setup()
{
+ char *cp;
u_long i;
/*
@@ -121,9 +131,32 @@ tc_3000_500_intr_setup()
for (i = 0; i < TC_3000_500_NCOOKIES; i++) {
tc_3000_500_intr[i].tci_func = tc_3000_500_intrnull;
tc_3000_500_intr[i].tci_arg = (void *)i;
+
+ cp = malloc(12, M_DEVBUF, M_NOWAIT);
+ if (cp == NULL)
+ panic("tc_3000_500_intr_setup");
+ sprintf(cp, "slot %lu", i);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach_dynamic(&tc_3000_500_intr[i].tci_evcnt,
+ EVCNT_TYPE_INTR, NULL, "tc", cp);
+#endif
}
}
+const struct evcnt *
+tc_3000_500_intr_evcnt(tcadev, cookie)
+ struct device *tcadev;
+ void *cookie;
+{
+ u_long dev = (u_long)cookie;
+
+#ifdef DIAGNOSTIC
+ /* XXX bounds-check cookie. */
+#endif
+
+ return (&tc_3000_500_intr[dev].tci_evcnt);
+}
+
void
tc_3000_500_intr_establish(tcadev, cookie, level, func, arg)
struct device *tcadev;
@@ -138,7 +171,7 @@ tc_3000_500_intr_establish(tcadev, cookie, level, func, arg)
#endif
if (tc_3000_500_intr[dev].tci_func != tc_3000_500_intrnull)
- panic("tc_3000_500_intr_establish: cookie %d twice", dev);
+ panic("tc_3000_500_intr_establish: cookie %lu twice", dev);
tc_3000_500_intr[dev].tci_func = func;
tc_3000_500_intr[dev].tci_arg = arg;
@@ -160,7 +193,7 @@ tc_3000_500_intr_disestablish(tcadev, cookie)
#endif
if (tc_3000_500_intr[dev].tci_func == tc_3000_500_intrnull)
- panic("tc_3000_500_intr_disestablish: cookie %d bad intr",
+ panic("tc_3000_500_intr_disestablish: cookie %lu bad intr",
dev);
tc_3000_500_imask |= tc_3000_500_intrbits[dev];
@@ -181,8 +214,8 @@ tc_3000_500_intrnull(val)
}
void
-tc_3000_500_iointr(framep, vec)
- void *framep;
+tc_3000_500_iointr(arg, vec)
+ void *arg;
unsigned long vec;
{
u_int32_t ir;
@@ -209,11 +242,10 @@ tc_3000_500_iointr(framep, vec)
ifound = 0;
#ifdef EVCNT_COUNTERS
- /* No interrupt counting via evcnt counters */
- XXX BREAK HERE XXX
-#else /* !EVCNT_COUNTERS */
+#define INCRINTRCNT(slot) tc_3000_500_intr[slot].tci_evcnt.ev_count++
+#else
#define INCRINTRCNT(slot) intrcnt[INTRCNT_KN15 + slot]++
-#endif /* EVCNT_COUNTERS */
+#endif
#define CHECKINTR(slot) \
if (ir & tc_3000_500_intrbits[slot]) { \
@@ -257,6 +289,47 @@ tc_3000_500_iointr(framep, vec)
} while (ifound);
}
+#if NWSDISPLAY > 0
+/*
+ * tc_3000_500_fb_cnattach --
+ * Attempt to map the CTB output device to a slot and attach the
+ * framebuffer as the output side of the console.
+ */
+int
+tc_3000_500_fb_cnattach(turbo_slot)
+ u_int64_t turbo_slot;
+{
+ u_int32_t output_slot;
+
+ output_slot = turbo_slot & 0xffffffff;
+
+ if (output_slot >= tc_3000_500_nslots) {
+ return EINVAL;
+ }
+
+ if (hwrpb->rpb_variation & SV_GRAPHICS) {
+ if (output_slot == 0) {
+#if NSFB > 0
+ sfb_cnattach(KV(0x1e0000000) + 0x02000000);
+ return 0;
+#else
+ return ENXIO;
+#endif
+ }
+ } else {
+ /*
+ * Slots 0-2 in the tc_3000_500_slots array are only
+ * on the 500 models that also have the CXTurbo
+ * (500/800/900) and a total of 6 TC slots. For the
+ * 400/600/700, slots 0-2 are in table locations 3-5, so
+ * offset the CTB slot by 3 to get the address in our table.
+ */
+ output_slot += 3;
+ }
+ return tc_fb_cnattach(tc_3000_500_slots[output_slot-1].tcs_addr);
+}
+#endif /* NWSDISPLAY */
+
#if 0
/*
* tc_3000_500_ioslot --
diff --git a/sys/arch/alpha/tc/tc_3000_500.h b/sys/arch/alpha/tc/tc_3000_500.h
index b9249b9a857..b1c6dbe7c36 100644
--- a/sys/arch/alpha/tc/tc_3000_500.h
+++ b/sys/arch/alpha/tc/tc_3000_500.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_500.h,v 1.4 1996/10/30 22:41:19 niklas Exp $ */
-/* $NetBSD: tc_3000_500.h,v 1.2 1995/12/20 00:43:31 cgd Exp $ */
+/* $OpenBSD: tc_3000_500.h,v 1.5 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_3000_500.h,v 1.4 1998/10/22 01:03:09 briggs Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -104,3 +104,5 @@
#define TC_3000_500_DEV_BOGUS -1
#define TC_3000_500_NCOOKIES 9
+
+extern int tc_3000_500_fb_cnattach(u_int64_t);
diff --git a/sys/arch/alpha/tc/tc_bus_mem.c b/sys/arch/alpha/tc/tc_bus_mem.c
index 951990eaf44..759c9e4a295 100644
--- a/sys/arch/alpha/tc/tc_bus_mem.c
+++ b/sys/arch/alpha/tc/tc_bus_mem.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_bus_mem.c,v 1.12 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: tc_bus_mem.c,v 1.13 1996/12/02 22:19:34 cgd Exp $ */
+/* $OpenBSD: tc_bus_mem.c,v 1.13 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_bus_mem.c,v 1.25 2001/09/04 05:31:28 thorpej Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -37,11 +37,14 @@
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
+
#include <uvm/uvm_extern.h>
#include <machine/bus.h>
#include <dev/tc/tcvar.h>
+#define __C(A,B) __CONCAT(A,B)
+
/* mapping/unmapping */
int tc_mem_map(void *, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
@@ -136,32 +139,16 @@ void tc_mem_set_region_8(void *, bus_space_handle_t,
bus_size_t, u_int64_t, bus_size_t);
/* copy */
-void tc_mem_copy_1(void *, bus_space_handle_t,
+void tc_mem_copy_region_1(void *, bus_space_handle_t,
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
-void tc_mem_copy_2(void *, bus_space_handle_t,
+void tc_mem_copy_region_2(void *, bus_space_handle_t,
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
-void tc_mem_copy_4(void *, bus_space_handle_t,
+void tc_mem_copy_region_4(void *, bus_space_handle_t,
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
-void tc_mem_copy_8(void *, bus_space_handle_t,
+void tc_mem_copy_region_8(void *, bus_space_handle_t,
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
-/* read multiple raw */
-void tc_mem_read_raw_multi_2(void *, bus_space_handle_t,
- bus_size_t, u_int8_t *, bus_size_t);
-void tc_mem_read_raw_multi_4(void *, bus_space_handle_t,
- bus_size_t, u_int8_t *, bus_size_t);
-void tc_mem_read_raw_multi_8(void *, bus_space_handle_t,
- bus_size_t, u_int8_t *, bus_size_t);
-
-/* write multiple raw */
-void tc_mem_write_raw_multi_2(void *, bus_space_handle_t,
- bus_size_t, const u_int8_t *, bus_size_t);
-void tc_mem_write_raw_multi_4(void *, bus_space_handle_t,
- bus_size_t, const u_int8_t *, bus_size_t);
-void tc_mem_write_raw_multi_8(void *, bus_space_handle_t,
- bus_size_t, const u_int8_t *, bus_size_t);
-
-static struct alpha_bus_space tc_mem_space = {
+struct alpha_bus_space tc_mem_space = {
/* cookie */
NULL,
@@ -226,20 +213,10 @@ static struct alpha_bus_space tc_mem_space = {
tc_mem_set_region_8,
/* copy */
- tc_mem_copy_1,
- tc_mem_copy_2,
- tc_mem_copy_4,
- tc_mem_copy_8,
-
- /* write multiple raw */
- tc_mem_read_raw_multi_2,
- tc_mem_read_raw_multi_4,
- tc_mem_read_raw_multi_8,
-
- /* write multiple raw*/
- tc_mem_write_raw_multi_2,
- tc_mem_write_raw_multi_4,
- tc_mem_write_raw_multi_8,
+ tc_mem_copy_region_1,
+ tc_mem_copy_region_2,
+ tc_mem_copy_region_4,
+ tc_mem_copy_region_8,
};
bus_space_tag_t
@@ -252,6 +229,7 @@ tc_bus_mem_init(memv)
return (h);
}
+/* ARGSUSED */
int
tc_mem_map(v, memaddr, memsize, cacheable, memhp)
void *v;
@@ -270,6 +248,7 @@ tc_mem_map(v, memaddr, memsize, cacheable, memhp)
return (0);
}
+/* ARGSUSED */
void
tc_mem_unmap(v, memh, memsize)
void *v;
@@ -300,11 +279,11 @@ tc_mem_subregion(v, memh, offset, size, nmemh)
}
int
-tc_mem_alloc(v, rstart, rend, size, align, boundary, cacheable, addrp, bshp)
+tc_mem_alloc(v, rstart, rend, size, align, boundary, flags, addrp, bshp)
void *v;
bus_addr_t rstart, rend, *addrp;
bus_size_t size, align, boundary;
- int cacheable;
+ int flags;
bus_space_handle_t *bshp;
{
@@ -331,9 +310,9 @@ tc_mem_barrier(v, h, o, l, f)
int f;
{
- if ((f & BUS_BARRIER_READ) != 0)
+ if ((f & BUS_SPACE_BARRIER_READ) != 0)
alpha_mb();
- else if ((f & BUS_BARRIER_WRITE) != 0)
+ else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
alpha_wmb();
}
@@ -408,7 +387,7 @@ tc_mem_read_8(v, memh, off)
#define tc_mem_read_multi_N(BYTES,TYPE) \
void \
-__abs_c(tc_mem_read_multi_,BYTES)(v, h, o, a, c) \
+__C(tc_mem_read_multi_,BYTES)(v, h, o, a, c) \
void *v; \
bus_space_handle_t h; \
bus_size_t o, c; \
@@ -416,8 +395,8 @@ __abs_c(tc_mem_read_multi_,BYTES)(v, h, o, a, c) \
{ \
\
while (c-- > 0) { \
- tc_mem_barrier(v, h, o, sizeof *a, BUS_BARRIER_READ); \
- *a++ = __abs_c(tc_mem_read_,BYTES)(v, h, o); \
+ tc_mem_barrier(v, h, o, sizeof *a, BUS_SPACE_BARRIER_READ); \
+ *a++ = __C(tc_mem_read_,BYTES)(v, h, o); \
} \
}
tc_mem_read_multi_N(1,u_int8_t)
@@ -427,7 +406,7 @@ tc_mem_read_multi_N(8,u_int64_t)
#define tc_mem_read_region_N(BYTES,TYPE) \
void \
-__abs_c(tc_mem_read_region_,BYTES)(v, h, o, a, c) \
+__C(tc_mem_read_region_,BYTES)(v, h, o, a, c) \
void *v; \
bus_space_handle_t h; \
bus_size_t o, c; \
@@ -435,7 +414,7 @@ __abs_c(tc_mem_read_region_,BYTES)(v, h, o, a, c) \
{ \
\
while (c-- > 0) { \
- *a++ = __abs_c(tc_mem_read_,BYTES)(v, h, o); \
+ *a++ = __C(tc_mem_read_,BYTES)(v, h, o); \
o += sizeof *a; \
} \
}
@@ -541,7 +520,7 @@ tc_mem_write_8(v, memh, off, val)
#define tc_mem_write_multi_N(BYTES,TYPE) \
void \
-__abs_c(tc_mem_write_multi_,BYTES)(v, h, o, a, c) \
+__C(tc_mem_write_multi_,BYTES)(v, h, o, a, c) \
void *v; \
bus_space_handle_t h; \
bus_size_t o, c; \
@@ -549,8 +528,8 @@ __abs_c(tc_mem_write_multi_,BYTES)(v, h, o, a, c) \
{ \
\
while (c-- > 0) { \
- __abs_c(tc_mem_write_,BYTES)(v, h, o, *a++); \
- tc_mem_barrier(v, h, o, sizeof *a, BUS_BARRIER_WRITE); \
+ __C(tc_mem_write_,BYTES)(v, h, o, *a++); \
+ tc_mem_barrier(v, h, o, sizeof *a, BUS_SPACE_BARRIER_WRITE); \
} \
}
tc_mem_write_multi_N(1,u_int8_t)
@@ -560,7 +539,7 @@ tc_mem_write_multi_N(8,u_int64_t)
#define tc_mem_write_region_N(BYTES,TYPE) \
void \
-__abs_c(tc_mem_write_region_,BYTES)(v, h, o, a, c) \
+__C(tc_mem_write_region_,BYTES)(v, h, o, a, c) \
void *v; \
bus_space_handle_t h; \
bus_size_t o, c; \
@@ -568,7 +547,7 @@ __abs_c(tc_mem_write_region_,BYTES)(v, h, o, a, c) \
{ \
\
while (c-- > 0) { \
- __abs_c(tc_mem_write_,BYTES)(v, h, o, *a++); \
+ __C(tc_mem_write_,BYTES)(v, h, o, *a++); \
o += sizeof *a; \
} \
}
@@ -579,7 +558,7 @@ tc_mem_write_region_N(8,u_int64_t)
#define tc_mem_set_multi_N(BYTES,TYPE) \
void \
-__abs_c(tc_mem_set_multi_,BYTES)(v, h, o, val, c) \
+__C(tc_mem_set_multi_,BYTES)(v, h, o, val, c) \
void *v; \
bus_space_handle_t h; \
bus_size_t o, c; \
@@ -587,8 +566,8 @@ __abs_c(tc_mem_set_multi_,BYTES)(v, h, o, val, c) \
{ \
\
while (c-- > 0) { \
- __abs_c(tc_mem_write_,BYTES)(v, h, o, val); \
- tc_mem_barrier(v, h, o, sizeof val, BUS_BARRIER_WRITE); \
+ __C(tc_mem_write_,BYTES)(v, h, o, val); \
+ tc_mem_barrier(v, h, o, sizeof val, BUS_SPACE_BARRIER_WRITE); \
} \
}
tc_mem_set_multi_N(1,u_int8_t)
@@ -598,7 +577,7 @@ tc_mem_set_multi_N(8,u_int64_t)
#define tc_mem_set_region_N(BYTES,TYPE) \
void \
-__abs_c(tc_mem_set_region_,BYTES)(v, h, o, val, c) \
+__C(tc_mem_set_region_,BYTES)(v, h, o, val, c) \
void *v; \
bus_space_handle_t h; \
bus_size_t o, c; \
@@ -606,7 +585,7 @@ __abs_c(tc_mem_set_region_,BYTES)(v, h, o, val, c) \
{ \
\
while (c-- > 0) { \
- __abs_c(tc_mem_write_,BYTES)(v, h, o, val); \
+ __C(tc_mem_write_,BYTES)(v, h, o, val); \
o += sizeof val; \
} \
}
@@ -615,84 +594,33 @@ tc_mem_set_region_N(2,u_int16_t)
tc_mem_set_region_N(4,u_int32_t)
tc_mem_set_region_N(8,u_int64_t)
-#define tc_mem_copy_N(BYTES) \
+#define tc_mem_copy_region_N(BYTES) \
void \
-__abs_c(tc_mem_copy_,BYTES)(v, h1, o1, h2, o2, c) \
+__C(tc_mem_copy_region_,BYTES)(v, h1, o1, h2, o2, c) \
void *v; \
bus_space_handle_t h1, h2; \
bus_size_t o1, o2, c; \
{ \
- bus_size_t i, o; \
+ bus_size_t o; \
\
if ((h1 & TC_SPACE_SPARSE) != 0 && \
(h2 & TC_SPACE_SPARSE) != 0) { \
- bcopy((void *)(h1 + o1), (void *)(h2 + o2), c * BYTES); \
+ bcopy((void *)(h1 + o1), (void *)(h2 + o2), c * BYTES); \
return; \
} \
\
- /* Circumvent a common case of overlapping problems */ \
- if (h1 == h2 && o2 > o1) \
- for (i = 0, o = (c - 1) * BYTES; i < c; i++, o -= BYTES)\
- __abs_c(tc_mem_write_,BYTES)(v, h2, o2 + o, \
- __abs_c(tc_mem_read_,BYTES)(v, h1, o1 + o));\
+ if (h1 + o1 >= h2 + o2) \
+ /* src after dest: copy forward */ \
+ for (o = 0; c > 0; c--, o += BYTES) \
+ __C(tc_mem_write_,BYTES)(v, h2, o2 + o, \
+ __C(tc_mem_read_,BYTES)(v, h1, o1 + o)); \
else \
- for (i = 0, o = 0; i < c; i++, o += BYTES) \
- __abs_c(tc_mem_write_,BYTES)(v, h2, o2 + o, \
- __abs_c(tc_mem_read_,BYTES)(v, h1, o1 + o));\
-}
-tc_mem_copy_N(1)
-tc_mem_copy_N(2)
-tc_mem_copy_N(4)
-tc_mem_copy_N(8)
-
-#define tc_mem_read_raw_multi_N(BYTES,TYPE) \
-void \
-__abs_c(tc_mem_read_raw_multi_,BYTES)(v, h, o, a, c) \
- void *v; \
- bus_space_handle_t h; \
- bus_size_t o, c; \
- u_int8_t *a; \
-{ \
- TYPE temp; \
- int i; \
- \
- while (c > 0) { \
- tc_mem_barrier(v, h, o, BYTES, BUS_BARRIER_READ); \
- temp = __abs_c(tc_mem_read_,BYTES)(v, h, o); \
- for (i = 0; i < BYTES; i++) { \
- *a++ = temp & 0xff; \
- temp >>= 8; \
- } \
- c -= BYTES; \
- } \
-}
-tc_mem_read_raw_multi_N(2,u_int16_t)
-tc_mem_read_raw_multi_N(4,u_int32_t)
-tc_mem_read_raw_multi_N(8,u_int64_t)
-
-#define tc_mem_write_raw_multi_N(BYTES,TYPE) \
-void \
-__abs_c(tc_mem_write_raw_multi_,BYTES)(v, h, o, a, c) \
- void *v; \
- bus_space_handle_t h; \
- bus_size_t o, c; \
- const u_int8_t *a; \
-{ \
- TYPE temp; \
- int i; \
- \
- while (c > 0) { \
- temp = 0; \
- for (i = BYTES - 1; i >= 0; i--) { \
- temp <<= 8; \
- temp |= *(a + i); \
- } \
- __abs_c(tc_mem_write_,BYTES)(v, h, o, temp); \
- tc_mem_barrier(v, h, o, BYTES, BUS_BARRIER_WRITE); \
- c -= BYTES; \
- a += BYTES; \
- } \
+ /* dest after src: copy backwards */ \
+ for (o = (c - 1) * BYTES; c > 0; c--, o -= BYTES) \
+ __C(tc_mem_write_,BYTES)(v, h2, o2 + o, \
+ __C(tc_mem_read_,BYTES)(v, h1, o1 + o)); \
}
-tc_mem_write_raw_multi_N(2,u_int16_t)
-tc_mem_write_raw_multi_N(4,u_int32_t)
-tc_mem_write_raw_multi_N(8,u_int64_t)
+tc_mem_copy_region_N(1)
+tc_mem_copy_region_N(2)
+tc_mem_copy_region_N(4)
+tc_mem_copy_region_N(8)
diff --git a/sys/arch/alpha/tc/tc_conf.h b/sys/arch/alpha/tc/tc_conf.h
index a1c30c00cb2..ec70762c9f9 100644
--- a/sys/arch/alpha/tc/tc_conf.h
+++ b/sys/arch/alpha/tc/tc_conf.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_conf.h,v 1.6 2002/03/14 03:15:51 millert Exp $ */
-/* $NetBSD: tc_conf.h,v 1.3 1996/11/15 23:59:01 cgd Exp $ */
+/* $OpenBSD: tc_conf.h,v 1.7 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_conf.h,v 1.10 2000/06/04 19:14:29 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -33,9 +33,13 @@
*/
#ifdef DEC_3000_500
+#include <alpha/tc/tc_dma_3000_500.h>
+
extern void tc_3000_500_intr_setup(void);
extern void tc_3000_500_iointr(void *, unsigned long);
+extern const struct evcnt *
+ tc_3000_500_intr_evcnt(struct device *, void *);
extern void tc_3000_500_intr_establish(struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *);
extern void tc_3000_500_intr_disestablish(struct device *, void *);
@@ -49,9 +53,13 @@ extern struct tc_builtin tc_3000_500_nographics_builtins[];
#endif /* DEC_3000_500 */
#ifdef DEC_3000_300
+#include <alpha/tc/tc_dma_3000_300.h>
+
extern void tc_3000_300_intr_setup(void);
extern void tc_3000_300_iointr(void *, unsigned long);
+extern const struct evcnt *
+ tc_3000_300_intr_evcnt(struct device *, void *);
extern void tc_3000_300_intr_establish(struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *);
extern void tc_3000_300_intr_disestablish(struct device *, void *);
@@ -61,3 +69,6 @@ extern struct tc_slotdesc tc_3000_300_slots[];
extern int tc_3000_300_nbuiltins;
extern struct tc_builtin tc_3000_300_builtins[];
#endif /* DEC_3000_300 */
+
+extern int tc_fb_cnattach(tc_addr_t);
+
diff --git a/sys/arch/alpha/tc/tc_dma.c b/sys/arch/alpha/tc/tc_dma.c
new file mode 100644
index 00000000000..5de443eaaa5
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_dma.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: tc_dma.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_dma.c,v 1.10 2001/07/19 06:40:02 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#define _ALPHA_BUS_DMA_PRIVATE
+
+#include <sys/param.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <dev/tc/tcvar.h>
+
+struct alpha_bus_dma_tag tc_dmat_direct = {
+ NULL, /* _cookie */
+ 0, /* _wbase */
+ 0, /* _wsize */
+ NULL, /* _next_window */
+ 0, /* _boundary */
+ NULL, /* _sgmap */
+ NULL, /* _get_tag */
+ _bus_dmamap_create,
+ _bus_dmamap_destroy,
+ _bus_dmamap_load_direct,
+ _bus_dmamap_load_mbuf_direct,
+ _bus_dmamap_load_uio_direct,
+ _bus_dmamap_load_raw_direct,
+ _bus_dmamap_unload,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
+};
+
+void
+tc_dma_init()
+{
+
+ /* XXX XXX BEGIN XXX XXX */
+ { /* XXX */
+ extern paddr_t alpha_XXX_dmamap_or; /* XXX */
+ alpha_XXX_dmamap_or = 0; /* XXX */
+ } /* XXX */
+ /* XXX XXX END XXX XXX */
+}
diff --git a/sys/arch/alpha/tc/tc_dma_3000_300.c b/sys/arch/alpha/tc/tc_dma_3000_300.c
new file mode 100644
index 00000000000..e010cacf141
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_dma_3000_300.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: tc_dma_3000_300.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_dma_3000_300.c,v 1.3 1997/09/02 13:20:29 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/param.h>
+
+#include <machine/bus.h>
+
+#include <alpha/tc/tc_dma_3000_300.h>
+
+/*
+ * Return the DMA tag for the given slot.
+ */
+bus_dma_tag_t
+tc_dma_get_tag_3000_300(slot)
+ int slot;
+{
+ extern struct alpha_bus_dma_tag tc_dmat_direct;
+
+ /* Pelicans don't have SGMAPs. */
+ return (&tc_dmat_direct);
+}
diff --git a/sys/arch/alpha/tc/tc_dma_3000_300.h b/sys/arch/alpha/tc/tc_dma_3000_300.h
new file mode 100644
index 00000000000..34050ec5fc3
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_dma_3000_300.h
@@ -0,0 +1,41 @@
+/* $OpenBSD: tc_dma_3000_300.h,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_dma_3000_300.h,v 1.2 1997/06/07 00:02:17 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+bus_dma_tag_t tc_dma_get_tag_3000_300(int);
diff --git a/sys/arch/alpha/tc/tc_dma_3000_500.c b/sys/arch/alpha/tc/tc_dma_3000_500.c
new file mode 100644
index 00000000000..49732d62ec9
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_dma_3000_500.c
@@ -0,0 +1,247 @@
+/* $OpenBSD: tc_dma_3000_500.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_dma_3000_500.c,v 1.13 2001/07/19 06:40:03 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#define _ALPHA_BUS_DMA_PRIVATE
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+
+#include <dev/tc/tcvar.h>
+#include <alpha/tc/tc_sgmap.h>
+#include <alpha/tc/tc_dma_3000_500.h>
+
+struct alpha_bus_dma_tag tc_dmat_sgmap = {
+ NULL, /* _cookie */
+ 0, /* _wbase */
+ 0, /* _wsize */
+ NULL, /* _next_window */
+ 0, /* _boundary */
+ NULL, /* _sgmap */
+ NULL, /* _get_tag */
+ tc_bus_dmamap_create_sgmap,
+ tc_bus_dmamap_destroy_sgmap,
+ tc_bus_dmamap_load_sgmap,
+ tc_bus_dmamap_load_mbuf_sgmap,
+ tc_bus_dmamap_load_uio_sgmap,
+ tc_bus_dmamap_load_raw_sgmap,
+ tc_bus_dmamap_unload_sgmap,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
+};
+
+struct tc_dma_slot_info {
+ struct alpha_sgmap tdsi_sgmap; /* sgmap for slot */
+ struct alpha_bus_dma_tag tdsi_dmat; /* dma tag for slot */
+};
+struct tc_dma_slot_info *tc_dma_slot_info;
+
+void
+tc_dma_init_3000_500(nslots)
+ int nslots;
+{
+ extern struct alpha_bus_dma_tag tc_dmat_direct;
+ size_t sisize;
+ int i;
+
+ /* Allocate per-slot DMA info. */
+ sisize = nslots * sizeof(struct tc_dma_slot_info);
+ tc_dma_slot_info = malloc(sisize, M_DEVBUF, M_NOWAIT);
+ if (tc_dma_slot_info == NULL)
+ panic("tc_dma_init: can't allocate per-slot DMA info");
+ memset(tc_dma_slot_info, 0, sisize);
+
+ /* Default all slots to direct-mapped. */
+ for (i = 0; i < nslots; i++)
+ memcpy(&tc_dma_slot_info[i].tdsi_dmat, &tc_dmat_direct,
+ sizeof(tc_dma_slot_info[i].tdsi_dmat));
+}
+
+/*
+ * Return the DMA tag for the given slot.
+ */
+bus_dma_tag_t
+tc_dma_get_tag_3000_500(slot)
+ int slot;
+{
+
+ return (&tc_dma_slot_info[slot].tdsi_dmat);
+}
+
+/*
+ * Create a TurboChannel SGMAP-mapped DMA map.
+ */
+int
+tc_bus_dmamap_create_sgmap(t, size, nsegments, maxsegsz, boundary,
+ flags, dmamp)
+ bus_dma_tag_t t;
+ bus_size_t size;
+ int nsegments;
+ bus_size_t maxsegsz;
+ bus_size_t boundary;
+ int flags;
+ bus_dmamap_t *dmamp;
+{
+ bus_dmamap_t map;
+ int error;
+
+ error = _bus_dmamap_create(t, size, nsegments, maxsegsz,
+ boundary, flags, dmamp);
+ if (error)
+ return (error);
+
+ map = *dmamp;
+
+ /* XXX BUS_DMA_ALLOCNOW */
+
+ return (error);
+}
+
+/*
+ * Destroy a TurboChannel SGMAP-mapped DMA map.
+ */
+void
+tc_bus_dmamap_destroy_sgmap(t, map)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+{
+
+ KASSERT(map->dm_mapsize == 0);
+
+ _bus_dmamap_destroy(t, map);
+}
+
+/*
+ * Load a TurboChannel SGMAP-mapped DMA map with a linear buffer.
+ */
+int
+tc_bus_dmamap_load_sgmap(t, map, buf, buflen, p, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ void *buf;
+ bus_size_t buflen;
+ struct proc *p;
+ int flags;
+{
+ struct tc_dma_slot_info *tdsi = t->_cookie;
+
+ return (tc_sgmap_load(t, map, buf, buflen, p, flags,
+ &tdsi->tdsi_sgmap));
+}
+
+/*
+ * Load a TurboChannel SGMAP-mapped DMA map with an mbuf chain.
+ */
+int
+tc_bus_dmamap_load_mbuf_sgmap(t, map, m, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct mbuf *m;
+ int flags;
+{
+ struct tc_dma_slot_info *tdsi = t->_cookie;
+
+ return (tc_sgmap_load_mbuf(t, map, m, flags, &tdsi->tdsi_sgmap));
+}
+
+/*
+ * Load a TurboChannel SGMAP-mapped DMA map with a uio.
+ */
+int
+tc_bus_dmamap_load_uio_sgmap(t, map, uio, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ struct uio *uio;
+ int flags;
+{
+ struct tc_dma_slot_info *tdsi = t->_cookie;
+
+ return (tc_sgmap_load_uio(t, map, uio, flags, &tdsi->tdsi_sgmap));
+}
+
+/*
+ * Load a TurboChannel SGMAP-mapped DMA map with raw memory.
+ */
+int
+tc_bus_dmamap_load_raw_sgmap(t, map, segs, nsegs, size, flags)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ bus_size_t size;
+ int flags;
+{
+ struct tc_dma_slot_info *tdsi = t->_cookie;
+
+ return (tc_sgmap_load_raw(t, map, segs, nsegs, size, flags,
+ &tdsi->tdsi_sgmap));
+}
+
+/*
+ * Unload a TurboChannel SGMAP-mapped DMA map.
+ */
+void
+tc_bus_dmamap_unload_sgmap(t, map)
+ bus_dma_tag_t t;
+ bus_dmamap_t map;
+{
+ struct tc_dma_slot_info *tdsi = t->_cookie;
+
+ /*
+ * Invalidate any SGMAP page table entries used by this
+ * mapping.
+ */
+ tc_sgmap_unload(t, map, &tdsi->tdsi_sgmap);
+
+ /*
+ * Do the generic bits of the unload.
+ */
+ _bus_dmamap_unload(t, map);
+}
diff --git a/sys/arch/alpha/tc/tc_dma_3000_500.h b/sys/arch/alpha/tc/tc_dma_3000_500.h
new file mode 100644
index 00000000000..de52194fc69
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_dma_3000_500.h
@@ -0,0 +1,55 @@
+/* $OpenBSD: tc_dma_3000_500.h,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_dma_3000_500.h,v 1.2 1997/06/07 00:02:19 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+void tc_dma_init_3000_500(int);
+bus_dma_tag_t tc_dma_get_tag_3000_500(int);
+
+int tc_bus_dmamap_create_sgmap(bus_dma_tag_t, bus_size_t, int,
+ bus_size_t, bus_size_t, int, bus_dmamap_t *);
+void tc_bus_dmamap_destroy_sgmap(bus_dma_tag_t, bus_dmamap_t);
+int tc_bus_dmamap_load_sgmap(bus_dma_tag_t, bus_dmamap_t, void *,
+ bus_size_t, struct proc *, int);
+int tc_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t, bus_dmamap_t,
+ struct mbuf *, int);
+int tc_bus_dmamap_load_uio_sgmap(bus_dma_tag_t, bus_dmamap_t,
+ struct uio *, int);
+int tc_bus_dmamap_load_raw_sgmap(bus_dma_tag_t, bus_dmamap_t,
+ bus_dma_segment_t *, int, bus_size_t, int);
+void tc_bus_dmamap_unload_sgmap(bus_dma_tag_t, bus_dmamap_t);
diff --git a/sys/arch/alpha/tc/tc_machdep.h b/sys/arch/alpha/tc/tc_machdep.h
deleted file mode 100644
index 3c26c5c8f85..00000000000
--- a/sys/arch/alpha/tc/tc_machdep.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $OpenBSD: tc_machdep.h,v 1.5 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: tc_machdep.h,v 1.3 1996/10/22 21:34:22 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/*
- * Machine-specific definitions for TurboChannel support.
- *
- * This file must typedef the following types:
- *
- * tc_addr_t TurboChannel bus address
- * tc_offset_t TurboChannel bus address difference (offset)
- *
- * This file must prototype or define the following functions
- * or macros (one or more of which may be no-ops):
- *
- * tc_mb() read/write memory barrier (any CPU<->memory
- * reads/writes before must complete before any
- * CPU<->memory reads/writes after).
- * tc_wmb() write memory barrier (any CPU<->memory writes
- * before must complete before any CPU<->memory
- * writes after).
- * tc_syncbus() sync TC bus; make sure CPU writes are
- * propagated across the TurboChannel bus.
- * tc_badaddr() return non-zero if the given address is invalid.
- * TC_DENSE_TO_SPARSE()
- * convert the given physical address in
- * TurboChannel dense space to the corresponding
- * address in TurboChannel sparse space.
- * TC_PHYS_TO_UNCACHED()
- * convert the given system memory physical address
- * to the physical address of the corresponding
- * region that is not cached.
- */
-
-typedef u_int64_t tc_addr_t;
-typedef int32_t tc_offset_t;
-
-#define tc_mb() alpha_mb()
-#define tc_wmb() alpha_wmb()
-
-/*
- * A junk address to read from, to make sure writes are complete. See
- * System Programmer's Manual, section 9.3 (p. 9-4), and sacrifice a
- * chicken.
- */
-#define tc_syncbus() \
- do { \
- volatile u_int32_t no_optimize; \
- no_optimize = \
- *(volatile u_int32_t *)ALPHA_PHYS_TO_K0SEG(0x00000001f0080220); \
- } while (0)
-
-#define tc_badaddr(tcaddr) \
- badaddr((void *)(tcaddr), sizeof (u_int32_t))
-
-#define TC_SPACE_IND 0xffffffffe0000003
-#define TC_SPACE_DENSE 0x0000000000000000
-#define TC_SPACE_DENSE_OFFSET 0x0000000007fffffc
-#define TC_SPACE_SPARSE 0x0000000010000000
-#define TC_SPACE_SPARSE_OFFSET 0x000000000ffffff8
-
-#define TC_DENSE_TO_SPARSE(addr) \
- (((addr) & TC_SPACE_IND) | TC_SPACE_SPARSE | \
- (((addr) & TC_SPACE_DENSE_OFFSET) << 1))
-
-#define TC_PHYS_TO_UNCACHED(addr) \
- (addr)
-
-bus_space_tag_t tc_bus_mem_init(void *memv);;
diff --git a/sys/arch/alpha/tc/tc_sgmap.c b/sys/arch/alpha/tc/tc_sgmap.c
new file mode 100644
index 00000000000..71bc8f2bab0
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_sgmap.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: tc_sgmap.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_sgmap.c,v 1.5 2001/07/19 06:40:03 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/proc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+
+#include <alpha/tc/tc_sgmap.h>
+
+#include <alpha/dev/sgmap_typedep.c>
diff --git a/sys/arch/alpha/tc/tc_sgmap.h b/sys/arch/alpha/tc/tc_sgmap.h
new file mode 100644
index 00000000000..39392db3870
--- /dev/null
+++ b/sys/arch/alpha/tc/tc_sgmap.h
@@ -0,0 +1,60 @@
+/* $OpenBSD: tc_sgmap.h,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_sgmap.h,v 1.2 1997/06/07 00:02:20 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#define SGMAP_TYPE tc_sgmap
+#define SGMAP_PTE_TYPE u_int32_t
+#define SGMAP_PTE_SPACING 2
+
+/*
+ * A TurboChannel SGMAP page table entry looks like this:
+ *
+ * 31 23 22 21 20 4 3 0
+ * | Discarded | V | F | P | Page address | UNP |
+ *
+ * The page address is bits <29:13> of the physical address of the
+ * page. The V bit is set if the PTE holds a valid mapping.
+ * The F (funny) bit forces a parity error. The P bit is a
+ * hardware-generated parity bit.
+ */
+#define SGPTE_PGADDR_SHIFT 9
+#define SGPTE_VALID 0x00800000
+
+#include <alpha/dev/sgmapvar.h>
+#include <alpha/dev/sgmap_typedep.h>
diff --git a/sys/arch/alpha/tc/tcasic.c b/sys/arch/alpha/tc/tcasic.c
index fe63afca03f..7ea036a533f 100644
--- a/sys/arch/alpha/tc/tcasic.c
+++ b/sys/arch/alpha/tc/tcasic.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcasic.c,v 1.9 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: tcasic.c,v 1.14 1996/12/05 01:39:45 cgd Exp $ */
+/* $OpenBSD: tcasic.c,v 1.10 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tcasic.c,v 1.36 2001/08/23 01:16:52 nisimura Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -34,16 +34,13 @@
#include <machine/autoconf.h>
#include <machine/rpb.h>
+#include <machine/cpu.h>
#include <dev/tc/tcvar.h>
#include <alpha/tc/tc_conf.h>
/* Definition of the driver for autoconfig. */
-#ifdef __BROKEN_INDIRECT_CONFIG
int tcasicmatch(struct device *, void *, void *);
-#else
-int tcasicmatch(struct device *, struct cfdata *, void *);
-#endif
void tcasicattach(struct device *, struct device *, void *);
struct cfattach tcasic_ca = {
@@ -54,9 +51,8 @@ struct cfdriver tcasic_cd = {
NULL, "tcasic", DV_DULL,
};
-int tcasicprint(void *, const char *);
-extern int cputype;
+int tcasicprint(void *, const char *);
/* There can be only one. */
int tcasicfound;
@@ -64,12 +60,7 @@ int tcasicfound;
int
tcasicmatch(parent, cfdata, aux)
struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *cfdata;
-#else
- struct cfdata *cfdata;
-#endif
- void *aux;
+ void *cfdata, *aux;
{
struct mainbus_attach_args *ma = aux;
@@ -107,7 +98,6 @@ tcasicattach(parent, self, aux)
intr_setup = tc_3000_500_intr_setup;
iointr = tc_3000_500_iointr;
- tba.tba_busname = "tc";
tba.tba_speed = TC_SPEED_25_MHZ;
tba.tba_nslots = tc_3000_500_nslots;
tba.tba_slots = tc_3000_500_slots;
@@ -118,8 +108,13 @@ tcasicattach(parent, self, aux)
tba.tba_nbuiltins = tc_3000_500_nographics_nbuiltins;
tba.tba_builtins = tc_3000_500_nographics_builtins;
}
+ tba.tba_intr_evcnt = tc_3000_500_intr_evcnt;
tba.tba_intr_establish = tc_3000_500_intr_establish;
tba.tba_intr_disestablish = tc_3000_500_intr_disestablish;
+ tba.tba_get_dma_tag = tc_dma_get_tag_3000_500;
+
+ /* Do 3000/500-specific DMA setup now. */
+ tc_dma_init_3000_500(tc_3000_500_nslots);
break;
#endif /* DEC_3000_500 */
@@ -129,14 +124,15 @@ tcasicattach(parent, self, aux)
intr_setup = tc_3000_300_intr_setup;
iointr = tc_3000_300_iointr;
- tba.tba_busname = "tc";
tba.tba_speed = TC_SPEED_12_5_MHZ;
tba.tba_nslots = tc_3000_300_nslots;
tba.tba_slots = tc_3000_300_slots;
tba.tba_nbuiltins = tc_3000_300_nbuiltins;
tba.tba_builtins = tc_3000_300_builtins;
+ tba.tba_intr_evcnt = tc_3000_300_intr_evcnt;
tba.tba_intr_establish = tc_3000_300_intr_establish;
tba.tba_intr_disestablish = tc_3000_300_intr_disestablish;
+ tba.tba_get_dma_tag = tc_dma_get_tag_3000_300;
break;
#endif /* DEC_3000_300 */
@@ -144,14 +140,10 @@ tcasicattach(parent, self, aux)
panic("tcasicattach: bad cputype");
}
+ tba.tba_busname = "tc";
tba.tba_memt = tc_bus_mem_init(NULL);
-
- /* XXX XXX BEGIN XXX XXX */
- { /* XXX */
- extern vm_offset_t alpha_XXX_dmamap_or; /* XXX */
- alpha_XXX_dmamap_or = 0; /* XXX */
- } /* XXX */
- /* XXX XXX END XXX XXX */
+
+ tc_dma_init();
(*intr_setup)();
set_iointr(iointr);
@@ -170,3 +162,82 @@ tcasicprint(aux, pnp)
printf("tc at %s", pnp);
return (UNCONF);
}
+
+#include "wsdisplay.h"
+
+#if NWSDISPLAY > 0
+
+#include "sfb.h"
+#include "sfbp.h"
+#include "cfb.h"
+#include "mfb.h"
+#include "tfb.h"
+#include "px.h"
+#include "pxg.h"
+
+extern void sfb_cnattach(tc_addr_t);
+extern void sfbp_cnattach(tc_addr_t);
+extern void cfb_cnattach(tc_addr_t);
+extern void mfb_cnattach(tc_addr_t);
+extern void tfb_cnattach(tc_addr_t);
+extern void px_cnattach(tc_addr_t);
+extern void pxg_cnattach(tc_addr_t);
+extern int tc_checkslot(tc_addr_t, char *);
+
+struct cnboards {
+ const char *cb_tcname;
+ void (*cb_cnattach)(tc_addr_t);
+} static const cnboards[] = {
+#if NSFB > 0
+ { "PMAGB-BA", sfb_cnattach },
+#endif
+#if NSFBP > 0
+ { "PMAGD ", sfbp_cnattach },
+#endif
+#if NCFB > 0
+ { "PMAG-BA ", cfb_cnattach },
+#endif
+#if NMFB > 0
+ { "PMAG-AA ", mfb_cnattach },
+#endif
+#if NTFB > 0
+ { "PMAG-JA ", tfb_cnattach },
+#endif
+#if NPX > 0
+ { "PMAG-CA ", px_cnattach },
+#endif
+#if NPXG > 0
+ { "PMAG-DA ", pxg_cnattach },
+ { "PMAG-FA ", pxg_cnattach },
+ { "PMAG-FB ", pxg_cnattach },
+ { "PMAGB-FA", pxg_cnattach },
+ { "PMAGB-FB", pxg_cnattach },
+#endif
+};
+
+/*
+ * tc_fb_cnattach --
+ * Attempt to attach the appropriate display driver to the
+ * output console.
+ */
+int
+tc_fb_cnattach(tcaddr)
+ tc_addr_t tcaddr;
+{
+ char tcname[TC_ROM_LLEN];
+ int i;
+
+ if (tc_badaddr(tcaddr) || (tc_checkslot(tcaddr, tcname) == 0))
+ return (EINVAL);
+
+ for (i = 0; i < sizeof(cnboards) / sizeof(cnboards[0]); i++)
+ if (strncmp(tcname, cnboards[i].cb_tcname, TC_ROM_LLEN) == 0)
+ break;
+
+ if (i == sizeof(cnboards) / sizeof(cnboards[0]))
+ return (ENXIO);
+
+ (cnboards[i].cb_cnattach)(tcaddr);
+ return (0);
+}
+#endif /* if NWSDISPLAY > 0 */
diff --git a/sys/arch/alpha/tc/tcds.c b/sys/arch/alpha/tc/tcds.c
deleted file mode 100644
index 1f3f2f815cd..00000000000
--- a/sys/arch/alpha/tc/tcds.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/* $OpenBSD: tcds.c,v 1.9 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: tcds.c,v 1.16 1996/12/05 01:39:45 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Keith Bostic, Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-
-#include <machine/pte.h>
-#include <machine/rpb.h>
-#ifndef EVCNT_COUNTERS
-#include <machine/intrcnt.h>
-#endif
-
-#include <dev/tc/tcreg.h>
-#include <dev/tc/tcvar.h>
-#include <alpha/tc/tcdsreg.h>
-#include <alpha/tc/tcdsvar.h>
-
-struct tcds_softc {
- struct device sc_dv;
- tc_addr_t sc_base;
- void *sc_cookie;
-
- volatile u_int32_t *sc_cir;
- volatile u_int32_t *sc_imer;
-
- struct tcds_slotconfig sc_slots[2];
-};
-
-/* Definition of the driver for autoconfig. */
-#ifdef __BROKEN_INDIRECT_CONFIG
-int tcdsmatch(struct device *, void *, void *);
-#else
-int tcdsmatch(struct device *, struct cfdata *, void *);
-#endif
-void tcdsattach(struct device *, struct device *, void *);
-int tcdsprint(void *, const char *);
-
-struct cfattach tcds_ca = {
- sizeof(struct tcds_softc), tcdsmatch, tcdsattach,
-};
-
-struct cfdriver tcds_cd = {
- NULL, "tcds", DV_DULL,
-};
-
-/*static*/ int tcds_intr(void *);
-/*static*/ int tcds_intrnull(void *);
-
-int
-tcdsmatch(parent, cfdata, aux)
- struct device *parent;
-#ifdef __BROKEN_INDIRECT_CONFIG
- void *cfdata;
-#else
- struct cfdata *cfdata;
-#endif
- void *aux;
-{
- struct tc_attach_args *ta = aux;
- extern int cputype;
-
- /* Make sure that we're looking for this type of device. */
- if (strncmp("PMAZ-DS ", ta->ta_modname, TC_ROM_LLEN))
- return (0);
- /* PMAZ-FS? */
-
- /* Check that it can actually exist. */
- if ((cputype != ST_DEC_3000_500) && (cputype != ST_DEC_3000_300))
- panic("tcdsmatch: how did we get here?");
-
- return (1);
-}
-
-void
-tcdsattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- struct tcds_softc *sc = (struct tcds_softc *)self;
- struct tc_attach_args *ta = aux;
- struct tcdsdev_attach_args tcdsdev;
- struct tcds_slotconfig *slotc;
- int i;
- extern int cputype;
-
- printf("\n");
-
- sc->sc_base = ta->ta_addr;
- sc->sc_cookie = ta->ta_cookie;
-
- sc->sc_cir = TCDS_REG(sc->sc_base, TCDS_CIR);
- sc->sc_imer = TCDS_REG(sc->sc_base, TCDS_IMER);
-
- tc_intr_establish(parent, sc->sc_cookie, TC_IPL_BIO, tcds_intr, sc);
-
- /*
- * XXX
- * IMER apparently has some random (or, not so random, but still
- * not useful) bits set in it when the system boots. Clear it.
- */
- *sc->sc_imer = 0;
- alpha_mb();
-
- /* XXX Initial contents of CIR? */
-
- /*
- * Set up the per-slot defintions for later use.
- */
-
- /* fill in common information first */
- for (i = 0; i < 2; i++) {
- slotc = &sc->sc_slots[i];
-
- bzero(slotc, sizeof *slotc); /* clear everything */
-
- slotc->sc_slot = i;
- slotc->sc_tcds = sc;
- slotc->sc_esp = NULL;
- slotc->sc_intrhand = tcds_intrnull;
- slotc->sc_intrarg = (void *)(long)i;
- }
-
- /* information for slot 0 */
- slotc = &sc->sc_slots[0];
- slotc->sc_resetbits = TCDS_CIR_SCSI0_RESET;
- slotc->sc_intrmaskbits =
- TCDS_IMER_SCSI0_MASK | TCDS_IMER_SCSI0_ENB;
- slotc->sc_intrbits = TCDS_CIR_SCSI0_INT;
- slotc->sc_dmabits = TCDS_CIR_SCSI0_DMAENA;
- slotc->sc_errorbits = 0; /* XXX */
- slotc->sc_sda = TCDS_REG(sc->sc_base, TCDS_SCSI0_DMA_ADDR);
- slotc->sc_dic = TCDS_REG(sc->sc_base, TCDS_SCSI0_DMA_INTR);
- slotc->sc_dud0 = TCDS_REG(sc->sc_base, TCDS_SCSI0_DMA_DUD0);
- slotc->sc_dud1 = TCDS_REG(sc->sc_base, TCDS_SCSI0_DMA_DUD1);
-
- /* information for slot 1 */
- slotc = &sc->sc_slots[1];
- slotc->sc_resetbits = TCDS_CIR_SCSI1_RESET;
- slotc->sc_intrmaskbits =
- TCDS_IMER_SCSI1_MASK | TCDS_IMER_SCSI1_ENB;
- slotc->sc_intrbits = TCDS_CIR_SCSI1_INT;
- slotc->sc_dmabits = TCDS_CIR_SCSI1_DMAENA;
- slotc->sc_errorbits = 0; /* XXX */
- slotc->sc_sda = TCDS_REG(sc->sc_base, TCDS_SCSI1_DMA_ADDR);
- slotc->sc_dic = TCDS_REG(sc->sc_base, TCDS_SCSI1_DMA_INTR);
- slotc->sc_dud0 = TCDS_REG(sc->sc_base, TCDS_SCSI1_DMA_DUD0);
- slotc->sc_dud1 = TCDS_REG(sc->sc_base, TCDS_SCSI1_DMA_DUD1);
-
- /* find the hardware attached to the TCDS ASIC */
- strncpy(tcdsdev.tcdsda_modname, "PMAZ-AA ", TC_ROM_LLEN);
- tcdsdev.tcdsda_slot = 0;
- tcdsdev.tcdsda_offset = 0;
- tcdsdev.tcdsda_addr = (tc_addr_t)
- TC_DENSE_TO_SPARSE(sc->sc_base + TCDS_SCSI0_OFFSET);
- tcdsdev.tcdsda_cookie = (void *)(long)0;
- tcdsdev.tcdsda_sc = &sc->sc_slots[0];
- tcdsdev.tcdsda_id = 7; /* XXX */
- tcdsdev.tcdsda_freq = 25000000; /* XXX */
-
- tcds_scsi_reset(tcdsdev.tcdsda_sc);
-
- config_found(self, &tcdsdev, tcdsprint);
-
- /* the second SCSI chip isn't present on the 3000/300 series. */
- if (cputype != ST_DEC_3000_300) {
- strncpy(tcdsdev.tcdsda_modname, "PMAZ-AA ",
- TC_ROM_LLEN);
- tcdsdev.tcdsda_slot = 1;
- tcdsdev.tcdsda_offset = 0;
- tcdsdev.tcdsda_addr = (tc_addr_t)
- TC_DENSE_TO_SPARSE(sc->sc_base + TCDS_SCSI1_OFFSET);
- tcdsdev.tcdsda_cookie = (void *)(long)1;
- tcdsdev.tcdsda_sc = &sc->sc_slots[1];
- tcdsdev.tcdsda_id = 7; /* XXX */
- tcdsdev.tcdsda_freq = 25000000; /* XXX */
-
- tcds_scsi_reset(tcdsdev.tcdsda_sc);
-
- config_found(self, &tcdsdev, tcdsprint);
- }
-}
-
-int
-tcdsprint(aux, pnp)
- void *aux;
- const char *pnp;
-{
- struct tc_attach_args *ta = aux;
-
- if (pnp)
- printf("%s at %s", ta->ta_modname, pnp);
- printf(" slot %d", ta->ta_slot);
- return (UNCONF);
-}
-
-void
-tcds_intr_establish(tcds, cookie, level, func, arg)
- struct device *tcds;
- void *cookie, *arg;
- tc_intrlevel_t level;
- int (*func)(void *);
-{
- struct tcds_softc *sc = (struct tcds_softc *)tcds;
- u_long slot;
-
- slot = (u_long)cookie;
-#ifdef DIAGNOSTIC
- /* XXX check cookie. */
-#endif
-
- if (sc->sc_slots[slot].sc_intrhand != tcds_intrnull)
- panic("tcds_intr_establish: cookie %d twice", slot);
-
- sc->sc_slots[slot].sc_intrhand = func;
- sc->sc_slots[slot].sc_intrarg = arg;
- tcds_scsi_reset(&sc->sc_slots[slot]);
-}
-
-void
-tcds_intr_disestablish(tcds, cookie)
- struct device *tcds;
- void *cookie;
-{
- struct tcds_softc *sc = (struct tcds_softc *)tcds;
- u_long slot;
-
- slot = (u_long)cookie;
-#ifdef DIAGNOSTIC
- /* XXX check cookie. */
-#endif
-
- if (sc->sc_slots[slot].sc_intrhand == tcds_intrnull)
- panic("tcds_intr_disestablish: cookie %d missing intr",
- slot);
-
- sc->sc_slots[slot].sc_intrhand = tcds_intrnull;
- sc->sc_slots[slot].sc_intrarg = (void *)slot;
-
- tcds_dma_enable(&sc->sc_slots[slot], 0);
- tcds_scsi_enable(&sc->sc_slots[slot], 0);
-}
-
-int
-tcds_intrnull(val)
- void *val;
-{
-
- panic("tcds_intrnull: uncaught TCDS intr for cookie %ld",
- (u_long)val);
-}
-
-void
-tcds_scsi_reset(sc)
- struct tcds_slotconfig *sc;
-{
-
- tcds_dma_enable(sc, 0);
- tcds_scsi_enable(sc, 0);
-
- TCDS_CIR_CLR(*sc->sc_tcds->sc_cir, sc->sc_resetbits);
- alpha_mb();
- DELAY(1);
- TCDS_CIR_SET(*sc->sc_tcds->sc_cir, sc->sc_resetbits);
- alpha_mb();
-
- tcds_scsi_enable(sc, 1);
- tcds_dma_enable(sc, 1);
-}
-
-void
-tcds_scsi_enable(sc, on)
- struct tcds_slotconfig *sc;
- int on;
-{
-
- if (on)
- *sc->sc_tcds->sc_imer |= sc->sc_intrmaskbits;
- else
- *sc->sc_tcds->sc_imer &= ~sc->sc_intrmaskbits;
- alpha_mb();
-}
-
-void
-tcds_dma_enable(sc, on)
- struct tcds_slotconfig *sc;
- int on;
-{
-
- /* XXX Clear/set IOSLOT/PBS bits. */
- if (on)
- TCDS_CIR_SET(*sc->sc_tcds->sc_cir, sc->sc_dmabits);
- else
- TCDS_CIR_CLR(*sc->sc_tcds->sc_cir, sc->sc_dmabits);
- alpha_mb();
-}
-
-int
-tcds_scsi_isintr(sc, clear)
- struct tcds_slotconfig *sc;
- int clear;
-{
-
- if ((*sc->sc_tcds->sc_cir & sc->sc_intrbits) != 0) {
- if (clear) {
- TCDS_CIR_CLR(*sc->sc_tcds->sc_cir, sc->sc_intrbits);
- alpha_mb();
- }
- return (1);
- } else
- return (0);
-}
-
-int
-tcds_scsi_iserr(sc)
- struct tcds_slotconfig *sc;
-{
-
- return ((*sc->sc_tcds->sc_cir & sc->sc_errorbits) != 0);
-}
-
-int
-tcds_intr(val)
- void *val;
-{
- struct tcds_softc *sc;
- u_int32_t ir;
-
- sc = val;
-
- /*
- * XXX
- * Copy and clear (gag!) the interrupts.
- */
- ir = *sc->sc_cir;
- alpha_mb();
- TCDS_CIR_CLR(*sc->sc_cir, TCDS_CIR_ALLINTR);
- alpha_mb();
- tc_syncbus();
- alpha_mb();
-
-#ifdef EVCNT_COUNTERS
- /* No interrupt counting via evcnt counters */
- XXX BREAK HERE XXX
-#else
-#define INCRINTRCNT(slot) intrcnt[INTRCNT_TCDS + slot]++
-#endif
-
-#define CHECKINTR(slot) \
- if (ir & sc->sc_slots[slot].sc_intrbits) { \
- INCRINTRCNT(slot); \
- (void)(*sc->sc_slots[slot].sc_intrhand) \
- (sc->sc_slots[slot].sc_intrarg); \
- }
- CHECKINTR(0);
- CHECKINTR(1);
-#undef CHECKINTR
-
-#ifdef DIAGNOSTIC
- /*
- * Interrupts not currently handled, but would like to know if they
- * occur.
- *
- * XXX
- * Don't know if we have to set the interrupt mask and enable bits
- * in the IMER to allow some of them to happen?
- */
-#define PRINTINTR(msg, bits) \
- if (ir & bits) \
- printf(msg);
- PRINTINTR("SCSI0 DREQ interrupt.\n", TCDS_CIR_SCSI0_DREQ);
- PRINTINTR("SCSI1 DREQ interrupt.\n", TCDS_CIR_SCSI1_DREQ);
- PRINTINTR("SCSI0 prefetch interrupt.\n", TCDS_CIR_SCSI0_PREFETCH);
- PRINTINTR("SCSI1 prefetch interrupt.\n", TCDS_CIR_SCSI1_PREFETCH);
- PRINTINTR("SCSI0 DMA error.\n", TCDS_CIR_SCSI0_DMA);
- PRINTINTR("SCSI1 DMA error.\n", TCDS_CIR_SCSI1_DMA);
- PRINTINTR("SCSI0 DB parity error.\n", TCDS_CIR_SCSI0_DB);
- PRINTINTR("SCSI1 DB parity error.\n", TCDS_CIR_SCSI1_DB);
- PRINTINTR("SCSI0 DMA buffer parity error.\n", TCDS_CIR_SCSI0_DMAB_PAR);
- PRINTINTR("SCSI1 DMA buffer parity error.\n", TCDS_CIR_SCSI1_DMAB_PAR);
- PRINTINTR("SCSI0 DMA read parity error.\n", TCDS_CIR_SCSI0_DMAR_PAR);
- PRINTINTR("SCSI1 DMA read parity error.\n", TCDS_CIR_SCSI1_DMAR_PAR);
- PRINTINTR("TC write parity error.\n", TCDS_CIR_TCIOW_PAR);
- PRINTINTR("TC I/O address parity error.\n", TCDS_CIR_TCIOA_PAR);
-#undef PRINTINTR
-#endif
-
- /*
- * XXX
- * The MACH source had this, with the comment:
- * This is wrong, but machine keeps dying.
- */
- DELAY(1);
-
- return (1);
-}
diff --git a/sys/arch/alpha/tc/tcds_dma.c b/sys/arch/alpha/tc/tcds_dma.c
deleted file mode 100644
index 9453aeab1d3..00000000000
--- a/sys/arch/alpha/tc/tcds_dma.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* $OpenBSD: tcds_dma.c,v 1.7 2000/11/08 16:01:26 art Exp $ */
-/* $NetBSD: tcds_dma.c,v 1.15 1996/12/04 22:35:08 mycroft Exp $ */
-
-/*
- * Copyright (c) 1994 Peter Galbavy. 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 Peter Galbavy.
- * 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.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/device.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-
-#include <dev/tc/tcvar.h>
-#include <alpha/tc/tcdsreg.h>
-#include <alpha/tc/tcdsvar.h>
-#include <alpha/tc/ascreg.h>
-#include <alpha/tc/ascvar.h>
-
-void
-tcds_dma_reset(sc)
- struct tcds_slotconfig *sc;
-{
- /* TCDS SCSI disable/reset/enable. */
- tcds_scsi_reset(sc); /* XXX */
-
- sc->sc_active = 0; /* and of course we aren't */
-}
-
-int
-tcds_dma_isintr(sc)
- struct tcds_slotconfig *sc;
-{
- int x;
-
- x = tcds_scsi_isintr(sc, 1);
-
- /* XXX */
- return x;
-}
-
-/*
- * Pseudo (chained) interrupt from the esp driver to kick the
- * current running DMA transfer. I am replying on espintr() to
- * pickup and clean errors for now
- *
- * return 1 if it was a DMA continue.
- */
-int
-tcds_dma_intr(sc)
- struct tcds_slotconfig *sc;
-{
- u_int32_t dud;
- int trans = 0, resid = 0;
- u_int32_t *addr, dudmask;
- u_char tcl, tcm, tch;
-
- ESP_DMA(("tcds_dma %d: intr", sc->sc_slot));
-
- if (tcds_scsi_iserr(sc))
- return (0);
-
- /* This is an "assertion" :) */
- if (sc->sc_active == 0)
- panic("dmaintr: DMA wasn't active");
-
- /* DMA has stopped */
- tcds_dma_enable(sc, 0);
- sc->sc_active = 0;
-
- if (sc->sc_dmasize == 0) {
- /* A "Transfer Pad" operation completed */
- tcl = ESP_READ_REG(sc->sc_esp, ESP_TCL);
- tcm = ESP_READ_REG(sc->sc_esp, ESP_TCM);
- ESP_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
- tcl | (tcm << 8), tcl, tcm));
- return 0;
- }
-
- if (!sc->sc_iswrite &&
- (resid = (ESP_READ_REG(sc->sc_esp, ESP_FFLAG) & ESPFIFO_FF)) != 0) {
- ESPCMD(sc->sc_esp, ESPCMD_FLUSH);
- DELAY(1);
- }
-
- resid += (tcl = ESP_READ_REG(sc->sc_esp, ESP_TCL));
- resid += (tcm = ESP_READ_REG(sc->sc_esp, ESP_TCM)) << 8;
- if (sc->sc_esp->sc_rev == ESP200)
- resid += (tch = ESP_READ_REG(sc->sc_esp, ESP_TCH)) << 16;
- else
- tch = 0;
-
- if (resid == 0 && (sc->sc_esp->sc_rev <= ESP100A) &&
- (sc->sc_esp->sc_espstat & ESPSTAT_TC) == 0)
- resid = 65536;
-
- trans = sc->sc_dmasize - resid;
- if (trans < 0) { /* transferred < 0 ? */
- printf("tcds_dma %d: xfer (%d) > req (%ld)\n",
- sc->sc_slot, trans, sc->sc_dmasize);
- trans = sc->sc_dmasize;
- }
-
- ESP_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
- tcl, tcm, tch, trans, resid));
-
- /*
- * Clean up unaligned DMAs into main memory.
- */
- if (sc->sc_iswrite) {
- /* Handle unaligned starting address, length. */
- dud = *sc->sc_dud0;
- if ((dud & TCDS_DUD0_VALIDBITS) != 0) {
- addr = (u_int32_t *)
- ((vm_offset_t)sc->sc_dmaaddr & ~0x3);
- dudmask = 0;
- if (dud & TCDS_DUD0_VALID00)
- panic("tcds_dma: dud0 byte 0 valid");
- if (dud & TCDS_DUD0_VALID01)
- dudmask |= TCDS_DUD_BYTE01;
- if (dud & TCDS_DUD0_VALID10)
- dudmask |= TCDS_DUD_BYTE10;
-#ifdef DIAGNOSTIC
- if (dud & TCDS_DUD0_VALID11)
- dudmask |= TCDS_DUD_BYTE11;
-#endif
- ESP_DMA(("dud0 at 0x%p dudmask 0x%x\n",
- addr, dudmask));
- addr = (u_int32_t *)ALPHA_PHYS_TO_K0SEG((vm_offset_t)addr);
- *addr = (*addr & ~dudmask) | (dud & dudmask);
- }
- dud = *sc->sc_dud1;
- if ((dud & TCDS_DUD1_VALIDBITS) != 0) {
-
- addr = (u_int32_t *)
- ((vm_offset_t)*sc->sc_sda << 2);
- dudmask = 0;
- if (dud & TCDS_DUD1_VALID00)
- dudmask |= TCDS_DUD_BYTE00;
- if (dud & TCDS_DUD1_VALID01)
- dudmask |= TCDS_DUD_BYTE01;
- if (dud & TCDS_DUD1_VALID10)
- dudmask |= TCDS_DUD_BYTE10;
-#ifdef DIAGNOSTIC
- if (dud & TCDS_DUD1_VALID11)
- panic("tcds_dma: dud1 byte 3 valid");
-#endif
- ESP_DMA(("dud1 at 0x%p dudmask 0x%x\n",
- addr, dudmask));
- addr = (u_int32_t *)ALPHA_PHYS_TO_K0SEG((vm_offset_t)addr);
- *addr = (*addr & ~dudmask) | (dud & dudmask);
- }
- /* XXX deal with saved residual byte? */
- }
-
- *sc->sc_dmalen -= trans;
- *sc->sc_dmaaddr += trans;
-
-#if 0 /* this is not normal operation just yet */
- if (*sc->sc_dmalen == 0 ||
- sc->sc_esp->sc_phase != sc->sc_esp->sc_prevphase)
- return 0;
-
- /* and again */
- dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, sc->sc_iswrite);
- return 1;
-#endif
- return 0;
-}
-
-#define DMAMAX(a) (0x02000 - ((a) & 0x1fff))
-
-/*
- * start a dma transfer or keep it going
- */
-int
-tcds_dma_setup(sc, addr, len, datain, dmasize)
- struct tcds_slotconfig *sc;
- caddr_t *addr;
- size_t *len, *dmasize;
- int datain; /* DMA into main memory */
-{
- u_int32_t dic;
- size_t size;
-
- sc->sc_dmaaddr = addr;
- sc->sc_dmalen = len;
- sc->sc_iswrite = datain;
-
- ESP_DMA(("tcds_dma %d: start %ld@%p,%d\n", sc->sc_slot, *sc->sc_dmalen, *sc->sc_dmaaddr, sc->sc_iswrite));
-
- /*
- * the rules say we cannot transfer more than the limit
- * of this DMA chip (64k) and we cannot cross a 8k boundary.
- */
-
- size = min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
- *dmasize = sc->sc_dmasize = size;
-
- ESP_DMA(("dma_start: dmasize = %ld\n", sc->sc_dmasize));
-
- /* Load address, set/clear unaligned transfer and read/write bits. */
- /* XXX PICK AN ADDRESS TYPE, AND STICK TO IT! */
- if ((u_long)*addr > VM_MIN_KERNEL_ADDRESS) {
- *sc->sc_sda = vtophys((u_long)*addr) >> 2;
- } else {
- *sc->sc_sda = ALPHA_K0SEG_TO_PHYS((u_long)*addr) >> 2;
- }
- alpha_mb();
- dic = *sc->sc_dic;
- dic &= ~TCDS_DIC_ADDRMASK;
- dic |= (vm_offset_t)*addr & TCDS_DIC_ADDRMASK;
- if (datain)
- dic |= TCDS_DIC_WRITE;
- else
- dic &= ~TCDS_DIC_WRITE;
- *sc->sc_dic = dic;
- alpha_mb();
-
- return (0);
-}
-
-void
-tcds_dma_go(sc)
- struct tcds_slotconfig *sc;
-{
-
- /* mark unit as DMA-active */
- sc->sc_active = 1;
-
- /* Start DMA */
- tcds_dma_enable(sc, 1);
-}
-
-int
-tcds_dma_isactive(sc)
- struct tcds_slotconfig *sc;
-{
-
- return (sc->sc_active);
-}
diff --git a/sys/arch/alpha/tc/tcdsreg.h b/sys/arch/alpha/tc/tcdsreg.h
deleted file mode 100644
index 02cfdba2102..00000000000
--- a/sys/arch/alpha/tc/tcdsreg.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $OpenBSD: tcdsreg.h,v 1.4 2002/03/14 01:26:28 millert Exp $ */
-/* $NetBSD: tcdsreg.h,v 1.2 1996/07/09 00:55:42 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Authors: Keith Bostic, Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/*
- * Offsets to the SCSI chips
- */
-#define TCDS_SCSI0_OFFSET 0x080000
-#define TCDS_SCSI1_OFFSET 0x080100
-
-/*
- * TCDS register offsets, bit masks.
- */
-#define TCDS_CIR 0x040000 /* CIR offset */
-
-/*
- * TCDS CIR control bits.
- */
-#define TCDS_CIR_GPO_0 0x00000001 /* Not used */
-#define TCDS_CIR_GPO_1 0x00000002 /* Not used */
-#define TCDS_CIR_GPO_2 0x00000004 /* Not used */
-#define TCDS_CIR_STD 0x00000008 /* Serial transmit disable */
-#define TCDS_CIR_GPI_0 0x00000010 /* Not used */
-#define TCDS_CIR_GPI_1 0x00000020 /* Not used */
-#define TCDS_CIR_GPI_2 0x00000040 /* Not used */
-#define TCDS_CIR_GPI_3 0x00000080 /* Not used */
-#define TCDS_CIR_SCSI0_DMAENA 0x00000100 /* SCSI 0 DMA enable */
-#define TCDS_CIR_SCSI1_DMAENA 0x00000200 /* SCSI 1 DMA enable */
-#define TCDS_CIR_SCSI0_RESET 0x00000400 /* SCSI 0 reset */
-#define TCDS_CIR_SCSI1_RESET 0x00000800 /* SCSI 1 reset */
-#define TCDS_CIR_SCSI0_DMA_TEST 0x00001000 /* SCSI 0 DMA buf parity test */
-#define TCDS_CIR_SCSI1_DMA_TEST 0x00002000 /* SCSI 1 DMA buf parity test */
-#define TCDS_CIR_DB_PAR 0x00004000 /* DB parity test mode */
-#define TCDS_CIR_TC_PAR 0x00008000 /* TC parity test mode */
-#define TCDS_CIR_ALLCONTROL 0x0000ffff /* all control bits */
-
-/* TCDS CIR interrupt bits. */
-#define TCDS_CIR_SCSI0_DREQ 0x00010000 /* SCSI 0 DREQ */
-#define TCDS_CIR_SCSI1_DREQ 0x00020000 /* SCSI 1 DREQ */
-#define TCDS_CIR_SCSI0_INT 0x00040000 /* SCSI 0 interrupt */
-#define TCDS_CIR_SCSI1_INT 0x00080000 /* SCSI 1 interrupt */
-#define TCDS_CIR_SCSI0_PREFETCH 0x00100000 /* SCSI 0 prefetch */
-#define TCDS_CIR_SCSI1_PREFETCH 0x00200000 /* SCSI 1 prefetch */
-#define TCDS_CIR_SCSI0_DMA 0x00400000 /* SCSI 0 DMA error */
-#define TCDS_CIR_SCSI1_DMA 0x00800000 /* SCSI 1 DMA error */
-#define TCDS_CIR_SCSI0_DB 0x01000000 /* SCSI 0 DB parity */
-#define TCDS_CIR_SCSI1_DB 0x02000000 /* SCSI 1 DB parity */
-#define TCDS_CIR_SCSI0_DMAB_PAR 0x04000000 /* SCSI 0 DMA buffer parity */
-#define TCDS_CIR_SCSI1_DMAB_PAR 0x08000000 /* SCSI 1 DMA buffer parity */
-#define TCDS_CIR_SCSI0_DMAR_PAR 0x10000000 /* SCSI 0 DMA read parity */
-#define TCDS_CIR_SCSI1_DMAR_PAR 0x20000000 /* SCSI 1 DMA read parity */
-#define TCDS_CIR_TCIOW_PAR 0x40000000 /* TC I/O write parity */
-#define TCDS_CIR_TCIOA_PAR 0x80000000 /* TC I/O address parity */
-#define TCDS_CIR_ALLINTR 0xffff0000 /* all interrupt bits */
-
-#define TCDS_CIR_CLR(c, b) c = ((c | TCDS_CIR_ALLINTR) & ~b)
-#define TCDS_CIR_SET(c, b) c = ((c | TCDS_CIR_ALLINTR) | b)
-
-/* TCDS IMER masks and enables, for interrupts in the CIR. */
-#define TCDS_IMER_SCSI0_MASK 0x04 /* SCSI 0 intr/enable mask */
-#define TCDS_IMER_SCSI1_MASK 0x08 /* SCSI 1 intr/enable mask */
-#define TCDS_IMER_SCSI0_ENB (TCDS_IMER_SCSI0_MASK << 16)
-#define TCDS_IMER_SCSI1_ENB (TCDS_IMER_SCSI1_MASK << 16)
-#define TCDS_IMER 0x040004 /* IMER offset */
-
-#define TCDS_SCSI0_DMA_ADDR 0x041000 /* DMA address */
-#define TCDS_SCSI0_DMA_INTR 0x041004 /* DMA interrupt control */
-#define TCDS_SCSI0_DMA_DUD0 0x041008 /* DMA unaligned data[0] */
-#define TCDS_SCSI0_DMA_DUD1 0x04100c /* DMA unaligned data[1] */
-
-#define TCDS_SCSI1_DMA_ADDR 0x041100 /* DMA address */
-#define TCDS_SCSI1_DMA_INTR 0x041104 /* DMA interrupt control */
-#define TCDS_SCSI1_DMA_DUD0 0x041108 /* DMA unaligned data[0] */
-#define TCDS_SCSI1_DMA_DUD1 0x04110c /* DMA unaligned data[1] */
-
-#define TCDS_DIC_ADDRMASK 0x03 /* DMA address bits <1:0> */
-#define TCDS_DIC_READ_PREFETCH 0x40 /* DMA read prefetch enable */
-#define TCDS_DIC_WRITE 0x80 /* DMA write */
-
-#define TCDS_DUD0_VALID00 0x00000001 /* byte 00 valid mask (zero) */
-#define TCDS_DUD0_VALID01 0x00000002 /* byte 01 valid mask */
-#define TCDS_DUD0_VALID10 0x00000004 /* byte 10 valid mask */
-#define TCDS_DUD0_VALID11 0x00000008 /* byte 11 valid mask */
-#define TCDS_DUD0_VALIDBITS 0x0000000f /* bits that show valid bytes */
-
-#define TCDS_DUD1_VALID00 0x01000000 /* byte 00 valid mask */
-#define TCDS_DUD1_VALID01 0x02000000 /* byte 01 valid mask */
-#define TCDS_DUD1_VALID10 0x04000000 /* byte 10 valid mask */
-#define TCDS_DUD1_VALID11 0x08000000 /* byte 11 valid mask (zero) */
-#define TCDS_DUD1_VALIDBITS 0x0f000000 /* bits that show valid bytes */
-
-#define TCDS_DUD_BYTE00 0x000000ff /* byte 00 mask */
-#define TCDS_DUD_BYTE01 0x0000ff00 /* byte 01 mask */
-#define TCDS_DUD_BYTE10 0x00ff0000 /* byte 10 mask */
-#define TCDS_DUD_BYTE11 0xff000000 /* byte 11 mask */
-
-#if 0
-int tcds_scsi_iserr(struct dma_softc *);
-int tcds_scsi_isintr(int, int);
-void tcds_dma_disable(int);
-void tcds_dma_enable(int);
-void tcds_dma_init(struct dma_softc *, int);
-void tcds_scsi_disable(int);
-void tcds_scsi_enable(int);
-void tcds_scsi_reset(int);
-
-/*
- * XXX
- * Start of MACH #defines, minimal changes to port to {Net/Open}BSD.
- *
- * The following register is the SCSI control interrupt register. It
- * starts, stops and resets scsi DMA. It takes over the SCSI funtions
- * that were handled by the ASIC on the 3min.
- */
-#define KN15AA_SYS_SCSI 0x1d0000000
-#define KN15AA_REG_SCSI_CIR (KN15AA_SYS_SCSI + 0x80000)
-#define SCSI_CIR_AIOPAR 0x80000000 /* TC IO Address parity error */
-#define SCSI_CIR_WDIOPAR 0x40000000 /* TC IO write data parity error */
-#define SCSI_CIR_DMARPAR1 0x20000000 /* SCSI[1] TC DMA read data parity */
-#define SCSI_CIR_DMARPAR0 0x10000000 /* SCSI[0] TC DMA read data parity */
-#define SCSI_CIR_DMABUFPAR1 0x08000000 /* SCSI[1] DMA buffer parity error */
-#define SCSI_CIR_DMABUFPAR0 0x04000000 /* SCSI[0] DMA buffer parity error */
-#define SCSI_CIR_DBPAR1 0x02000000 /* SCSI[1] DB parity error */
-#define SCSI_CIR_DBPAR0 0x01000000 /* SCSI[0] DB parity error */
-#define SCSI_CIR_DMAERR1 0x00800000 /* SCSI[1] DMA error */
-#define SCSI_CIR_DMAERR0 0x00400000 /* SCSI[0] DMA error */
-#if fmm50
-#define SCSI_CIR_xxx0 0x00200000 /* RESERVED */
-#define SCSI_CIR_xxx1 0x00100000 /* RESERVED */
-#else
-#define SCSI_CIR_PREF1 0x00200000 /* 53C94 prefetch interupt */
-#define SCSI_CIR_PREF0 0x00100000 /* 53C94 prefetch interupt */
-#endif
-#define SCSI_CIR_53C94_INT1 0x00080000 /* SCSI[1] 53C94 Interupt */
-#define SCSI_CIR_53C94_INT0 0x00040000 /* SCSI[0] 53C94 Interupt */
-#define SCSI_CIR_53C94_DREQ1 0x00020000 /* SCSI[1] 53C94 DREQ */
-#define SCSI_CIR_53C94_DREQ0 0x00010000 /* SCSI[0] 53C94 DREQ */
-#define SCSI_CIR_TC_PAR_TEST 0x00008000 /* TC parity test mode */
-#define SCSI_CIR_DB_PAR_TEST 0x00004000 /* DB parity test mode */
-#define SCSI_CIR_DBUF_PAR_TEST1 0x00002000 /* SCSI[1] DMA buffer parity test */
-#define SCSI_CIR_DBUF_PAR_TEST0 0x00001000 /* SCSI[0] DMA buffer parity test */
-#define SCSI_CIR_RESET1 0x00000800 /* SCSI[1] ~Reset,enable(0)/disable(1) */
-#define SCSI_CIR_RESET0 0x00000400 /* SCSI[0] ~Reset,enable(0)/disable(1) */
-#define SCSI_CIR_DMAENA1 0x00000200 /* SCSI[1] DMA enable */
-#define SCSI_CIR_DMAENA0 0x00000100 /* SCSI[1] DMA enable */
-#define SCSI_CIR_GPI3 0x00000080 /* General purpose input <3> */
-#define SCSI_CIR_GPI2 0x00000040 /* General purpose input <2> */
-#define SCSI_CIR_GPI1 0x00000020 /* General purpose input <1> */
-#define SCSI_CIR_GPI0 0x00000010 /* General purpose input <0> */
-#define SCSI_CIR_TXDIS 0x00000008 /* TXDIS- serial transmit disable */
-#define SCSI_CIR_GPO2 0x00000004 /* General purpose output <2> */
-#define SCSI_CIR_GPO1 0x00000002 /* General purpose output <1> */
-#define SCSI_CIR_GPO0 0x00000001 /* General purpose output <0> */
-#define SCSI_CIR_ERROR (SCSI_CIR_AIOPAR | SCSI_CIR_WDIOPAR | SCSI_CIR_DMARPAR1 | SCSI_CIR_DMARPAR0 | SCSI_CIR_DMABUFPAR1 | SCSI_CIR_DMABUFPAR0 | SCSI_CIR_DBPAR1 |SCSI_CIR_DBPAR0 | SCSI_CIR_DMAERR1 | SCSI_CIR_DMAERR0 )
-
-#define KN15AA_REG_SCSI_DMAPTR0 (KN15AA_SYS_SCSI + 0x82000)
-#define KN15AA_REG_SCSI_DMAPTR1 (KN15AA_SYS_SCSI + 0x82200)
-
-#define KN15AA_REG_SCSI_DIC0 (KN15AA_SYS_SCSI + 0x82008)
-#define KN15AA_REG_SCSI_DIC1 (KN15AA_SYS_SCSI + 0x82208)
-#define SCSI_DIC_DMADIR 0x00000080 /* DMA direction read(0)/write(1) */
-#define SCSI_DIC_PREFENA 0x00000040 /* DMA read prefetch dis(0)/ena(1) */
-#define SCSI_DIC_DMAADDR1 0x00000002 /* DMA address <1> */
-#define SCSI_DIC_DMAADDR0 0x00000001 /* DMA address <0> */
-#define SCSI_DIC_ADDR_MASK (SCSI_DIC_DMAADDR0 |SCSI_DIC_DMAADDR1)
-
-#define KN15AA_REG_SCSI_94REG0 (KN15AA_SYS_SCSI + 0x100000)
-#define KN15AA_REG_SCSI_94REG1 (KN15AA_SYS_SCSI + 0x100200)
-
-#define KN15AA_REG_SCSI_IMER (KN15AA_SYS_SCSI + 0x80008)
-
-/* these are the bits that were unalligned at the beginning of the dma */
-#define KN15AA_REG_SCSI_DUDB0 (KN15AA_SYS_SCSI + 0x82010)
-#define KN15AA_REG_SCSI_DUDB1 (KN15AA_SYS_SCSI + 0x82210)
-# define SCSI_DUDB_MASK01 0x00000001 /* Mask bit for byte[01] */
-# define SCSI_DUDB_MASK10 0x00000002 /* Mask bit for byte[10] */
-# define SCSI_DUDB_MASK11 0x00000004 /* Mask bit for byte[11] */
-
-/* these are the bits that were unalligned at the end of the dma */
-#define KN15AA_REG_SCSI_DUDE0 (KN15AA_SYS_SCSI + 0x82018)
-#define KN15AA_REG_SCSI_DUDE1 (KN15AA_SYS_SCSI + 0x82218)
-# define SCSI_DUDE_MASK00 0x1000000 /* Mask bit for byte[00] */
-# define SCSI_DUDE_MASK01 0x2000000 /* Mask bit for byte[01] */
-# define SCSI_DUDE_MASK10 0x4000000 /* Mask bit for byte[10] */
-
-#define SCSI_CIR ALPHA_PHYS_TO_K0SEG(KN15AA_REG_SCSI_CIR)
-#define SCSI_IMER ALPHA_PHYS_TO_K0SEG(KN15AA_REG_SCSI_IMER)
-
-#endif
diff --git a/sys/arch/alpha/tc/tcdsvar.h b/sys/arch/alpha/tc/tcdsvar.h
deleted file mode 100644
index 5c73d575a94..00000000000
--- a/sys/arch/alpha/tc/tcdsvar.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* $OpenBSD: tcdsvar.h,v 1.8 2002/03/15 01:20:04 millert Exp $ */
-/* $NetBSD: tcdsvar.h,v 1.5 1996/11/13 21:13:38 cgd Exp $ */
-
-/*
- * Copyright (c) 1995, 1996 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-struct tcds_slotconfig {
- /*
- * Bookkeeping information
- */
- int sc_slot;
- struct tcds_softc *sc_tcds; /* to frob TCDS regs */
- struct esp_softc *sc_esp; /* to frob child's regs */
- int (*sc_intrhand)(void *); /* intr. handler */
- void *sc_intrarg; /* intr. handler arg. */
-
- /*
- * Sets of bits in TCDS CIR and IMER that enable/check
- * various things.
- */
- u_int32_t sc_resetbits;
- u_int32_t sc_intrmaskbits;
- u_int32_t sc_intrbits;
- u_int32_t sc_dmabits;
- u_int32_t sc_errorbits;
-
- /*
- * Pointers to slot-specific DMA resources.
- */
- volatile u_int32_t *sc_sda;
- volatile u_int32_t *sc_dic;
- volatile u_int32_t *sc_dud0;
- volatile u_int32_t *sc_dud1;
-
- /*
- * DMA bookkeeping information.
- */
- int sc_active; /* DMA active ? */
- int sc_iswrite; /* DMA into main memory? */
- size_t sc_dmasize;
- caddr_t *sc_dmaaddr;
- size_t *sc_dmalen;
-};
-
-struct tcdsdev_attach_args {
- struct tc_attach_args tcdsda_ta;
- struct tcds_slotconfig *tcdsda_sc;
- u_int tcdsda_id;
- u_int tcdsda_freq;
-};
-#define tcdsda_modname tcdsda_ta.ta_modname
-#define tcdsda_slot tcdsda_ta.ta_slot
-#define tcdsda_offset tcdsda_ta.ta_offset
-#define tcdsda_addr tcdsda_ta.ta_addr
-#define tcdsda_cookie tcdsda_ta.ta_cookie
-
-#define TCDS_REG(base, off) \
- (volatile u_int32_t *)TC_DENSE_TO_SPARSE((base) + (off))
-
-/*
- * TCDS functions.
- */
-void tcds_intr_establish(struct device *, void *, tc_intrlevel_t,
- int (*)(void *), void *);
-void tcds_intr_disestablish(struct device *, void *);
-void tcds_dma_enable(struct tcds_slotconfig *, int);
-void tcds_scsi_enable(struct tcds_slotconfig *, int);
-int tcds_scsi_iserr(struct tcds_slotconfig *);
-int tcds_scsi_isintr(struct tcds_slotconfig *, int);
-void tcds_scsi_reset(struct tcds_slotconfig *);
-int tcds_scsi_iserr(struct tcds_slotconfig *);
-
-/*
- * TCDS DMA functions (used the the 53c94 driver)
- */
-int tcds_dma_isintr(struct tcds_slotconfig *);
-void tcds_dma_reset(struct tcds_slotconfig *);
-int tcds_dma_intr(struct tcds_slotconfig *);
-int tcds_dma_setup(struct tcds_slotconfig *, caddr_t *, size_t *,
- int, size_t *);
-void tcds_dma_go(struct tcds_slotconfig *);
-int tcds_dma_isactive(struct tcds_slotconfig *);
-
-/*
- * The TCDS (bus) cfdriver, so that subdevices can more
- * easily tell what bus they're on.
- */
-extern struct cfdriver tcds_cd;