summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2002-05-02 22:56:08 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2002-05-02 22:56:08 +0000
commitf69ff2bae348f49f6e5fccbf1594b839e98792ef (patch)
tree984c07207f03eebcb847988db98df196a848c27e
parentd7aff648af7518e317842f78e06a3d197eca9629 (diff)
Big TURBOchannel support catchup from NetBSD, part 1.
A few local changes and tweaks remain. This bring DEC 3000 machines back in the game, but framebuffers are still not supported at the moment. Thanks to ericj@ and nate@ for supplying me a DEC 3000 for testing.
-rw-r--r--sys/arch/alpha/alpha/dec_3000_300.c6
-rw-r--r--sys/arch/alpha/alpha/dec_3000_500.c6
-rw-r--r--sys/arch/alpha/conf/GENERIC20
-rw-r--r--sys/arch/alpha/conf/RAMDISK4
-rw-r--r--sys/arch/alpha/conf/RAMDISKB4
-rw-r--r--sys/arch/alpha/conf/RAMDISKBIG12
-rw-r--r--sys/arch/alpha/conf/files.alpha47
-rw-r--r--sys/arch/alpha/include/tc_machdep.h (renamed from sys/arch/alpha/tc/tc_machdep.h)24
-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_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/dev/dec/clockvar.h63
-rw-r--r--sys/dev/dec/files.dec13
-rw-r--r--sys/dev/dec/if_le_dec.c (renamed from sys/dev/tc/if_le_dec.c)19
-rw-r--r--sys/dev/dec/mcclockvar.h42
-rw-r--r--sys/dev/tc/asc.c127
-rw-r--r--sys/dev/tc/asc_tc.c330
-rw-r--r--sys/dev/tc/asc_tcds.c495
-rw-r--r--sys/dev/tc/ascvar.h24
-rw-r--r--sys/dev/tc/devlist2h.awk4
-rw-r--r--sys/dev/tc/files.tc45
-rw-r--r--sys/dev/tc/if_le_ioasic.c300
-rw-r--r--sys/dev/tc/if_le_tc.c14
-rw-r--r--sys/dev/tc/if_levar.h6
-rw-r--r--sys/dev/tc/ioasic_subr.c86
-rw-r--r--sys/dev/tc/ioasicreg.h204
-rw-r--r--sys/dev/tc/ioasicvar.h51
-rw-r--r--sys/dev/tc/tc.c58
-rw-r--r--sys/dev/tc/tcdevs42
-rw-r--r--sys/dev/tc/tcdevs.h62
-rw-r--r--sys/dev/tc/tcdevs_data.h78
-rw-r--r--sys/dev/tc/tcds.c602
-rw-r--r--sys/dev/tc/tcdsreg.h (renamed from sys/arch/alpha/tc/tcdsreg.h)11
-rw-r--r--sys/dev/tc/tcdsvar.h (renamed from sys/arch/alpha/tc/tcdsvar.h)75
-rw-r--r--sys/dev/tc/tcreg.h2
-rw-r--r--sys/dev/tc/tcvar.h77
58 files changed, 3782 insertions, 4544 deletions
diff --git a/sys/arch/alpha/alpha/dec_3000_300.c b/sys/arch/alpha/alpha/dec_3000_300.c
index e223ee20dc5..b600615230d 100644
--- a/sys/arch/alpha/alpha/dec_3000_300.c
+++ b/sys/arch/alpha/alpha/dec_3000_300.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dec_3000_300.c,v 1.9 2002/03/14 01:26:26 millert Exp $ */
+/* $OpenBSD: dec_3000_300.c,v 1.10 2002/05/02 22:56:06 miod Exp $ */
/* $NetBSD: dec_3000_300.c,v 1.30 2000/05/22 20:13:32 thorpej Exp $ */
/*
@@ -44,7 +44,7 @@
#include <machine/cpuconf.h>
#include <dev/tc/tcvar.h>
-#include <alpha/tc/tcdsvar.h>
+#include <dev/tc/tcdsvar.h>
#include <alpha/tc/tc_3000_300.h>
#ifndef NEW_SCC_DRIVER
#include <alpha/tc/sccvar.h>
@@ -213,7 +213,7 @@ dec_3000_300_device_register(dev, aux)
if (parent != (struct device *)tcdsdev)
return;
- if (ta->tcdsda_slot != b->channel)
+ if (ta->tcdsda_chip != b->channel)
return;
scsidev = dev;
diff --git a/sys/arch/alpha/alpha/dec_3000_500.c b/sys/arch/alpha/alpha/dec_3000_500.c
index 06236b957d3..210dcb03e8e 100644
--- a/sys/arch/alpha/alpha/dec_3000_500.c
+++ b/sys/arch/alpha/alpha/dec_3000_500.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dec_3000_500.c,v 1.9 2002/03/14 01:26:26 millert Exp $ */
+/* $OpenBSD: dec_3000_500.c,v 1.10 2002/05/02 22:56:06 miod Exp $ */
/* $NetBSD: dec_3000_500.c,v 1.29 2000/05/22 20:13:32 thorpej Exp $ */
/*
@@ -43,7 +43,7 @@
#include <machine/cpuconf.h>
#include <dev/tc/tcvar.h>
-#include <alpha/tc/tcdsvar.h>
+#include <dev/tc/tcdsvar.h>
#include <alpha/tc/tc_3000_500.h>
#ifndef NEW_SCC_DRIVER
#include <alpha/tc/sccvar.h>
@@ -232,7 +232,7 @@ dec_3000_500_device_register(dev, aux)
if (parent != (struct device *)tcdsdev)
return;
- if (ta->tcdsda_slot != b->channel)
+ if (ta->tcdsda_chip != b->channel)
return;
scsidev = dev;
diff --git a/sys/arch/alpha/conf/GENERIC b/sys/arch/alpha/conf/GENERIC
index e6ed538b0be..0554e38ec4d 100644
--- a/sys/arch/alpha/conf/GENERIC
+++ b/sys/arch/alpha/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.105 2002/04/26 20:13:11 matthieu Exp $
+# $OpenBSD: GENERIC,v 1.106 2002/05/02 22:56:06 miod Exp $
# $NetBSD: GENERIC,v 1.31 1996/12/03 17:25:29 cgd Exp $
machine alpha
@@ -82,24 +82,24 @@ ugen* at uhub? port ? configuration ? # USB Generic driver
# EV6 Tsunami Core Logic
tsc* at mainbus0
-# TurboChannel host bus adapter support
+# TURBOchannel host bus adapter support
tcasic* at mainbus0
-# TurboChannel bus support
+# TURBOchannel bus support
tc* at tcasic?
-# TurboChannel devices
+# TURBOchannel devices
ioasic* at tc? slot ? offset ?
mcclock* at ioasic? offset ?
le* at ioasic? offset ?
scc0 at ioasic? offset ?
scc1 at ioasic? offset ?
-tcds0 at tc? slot ? offset ?
-asc0 at tcds? slot ?
-asc1 at tcds? slot ?
+tcds* at tc? slot ? offset ?
+asc* at tcds? chip ?
scsibus* at asc?
-cfb* at tc? slot ? offset ?
-sfb* at tc? slot ? offset ?
+asc* at tc? slot ? offset ?
+#cfb* at tc? slot ? offset ?
+#sfb* at tc? slot ? offset ?
le* at tc? slot ? offset ?
fta* at tc? slot ? offset ? # DEC DEFTA FDDI cards
@@ -298,8 +298,8 @@ audio* at uaudio?
# Workstation Console attachments
#wsdisplay* at cfb?
-wsdisplay* at vga?
#wsdisplay* at sfb?
+#wsdisplay* at vga?
wsdisplay* at tga?
wskbd* at pckbd?
wsmouse* at pms?
diff --git a/sys/arch/alpha/conf/RAMDISK b/sys/arch/alpha/conf/RAMDISK
index 231d1c8a513..45fb5915704 100644
--- a/sys/arch/alpha/conf/RAMDISK
+++ b/sys/arch/alpha/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.56 2002/04/28 20:55:14 pvalchev Exp $
+# $OpenBSD: RAMDISK,v 1.57 2002/05/02 22:56:06 miod Exp $
# $NetBSD: RAMDISK,v 1.9 1996/12/03 17:25:33 cgd Exp $
machine alpha # architecture, used by config; REQUIRED
@@ -137,9 +137,7 @@ sd* at scsibus? target ? lun ? # SCSI disk drives
#st* at scsibus? target ? lun ? # SCSI tape drives
# Workstation Console attachments
-#wsdisplay* at cfb?
wsdisplay* at vga?
-#wsdisplay* at sfb?
wsdisplay* at tga?
wskbd* at pckbd?
diff --git a/sys/arch/alpha/conf/RAMDISKB b/sys/arch/alpha/conf/RAMDISKB
index d32a646f415..93e37dcd853 100644
--- a/sys/arch/alpha/conf/RAMDISKB
+++ b/sys/arch/alpha/conf/RAMDISKB
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISKB,v 1.19 2002/04/28 20:55:14 pvalchev Exp $
+# $OpenBSD: RAMDISKB,v 1.20 2002/05/02 22:56:06 miod Exp $
# $NetBSD: RAMDISK,v 1.9 1996/12/03 17:25:33 cgd Exp $
machine alpha # architecture, used by config; REQUIRED
@@ -138,9 +138,7 @@ sd* at scsibus? target ? lun ? # SCSI disk drives
#st* at scsibus? target ? lun ? # SCSI tape drives
# Workstation Console attachments
-#wsdisplay* at cfb?
wsdisplay* at vga?
-#wsdisplay* at sfb?
wsdisplay* at tga?
wskbd* at pckbd?
diff --git a/sys/arch/alpha/conf/RAMDISKBIG b/sys/arch/alpha/conf/RAMDISKBIG
index fc4d1cba8c2..c77a5faddfe 100644
--- a/sys/arch/alpha/conf/RAMDISKBIG
+++ b/sys/arch/alpha/conf/RAMDISKBIG
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISKBIG,v 1.25 2002/04/28 20:55:14 pvalchev Exp $
+# $OpenBSD: RAMDISKBIG,v 1.26 2002/05/02 22:56:06 miod Exp $
# $NetBSD: GENERIC,v 1.31 1996/12/03 17:25:29 cgd Exp $
#
# Generic Alpha kernel. Enough to get booted, etc., but not much more.
@@ -102,12 +102,12 @@ mcclock* at ioasic? offset ?
le* at ioasic? offset ?
scc0 at ioasic? offset ?
scc1 at ioasic? offset ?
-tcds0 at tc? slot ? offset ?
-asc0 at tcds? slot ?
-asc1 at tcds? slot ?
+tcds* at tc? slot ? offset ?
+asc* at tcds? chip ?
+asc* at tc? slot ? offset ?
scsibus* at asc?
-cfb* at tc? slot ? offset ?
-sfb* at tc? slot ? offset ?
+#cfb* at tc? slot ? offset ?
+#sfb* at tc? slot ? offset ?
le* at tc? slot ? offset ?
fta* at tc? slot ? offset ? # DEC DEFTA FDDI cards
diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha
index 5249e2ecadd..8d6c26e4f3c 100644
--- a/sys/arch/alpha/conf/files.alpha
+++ b/sys/arch/alpha/conf/files.alpha
@@ -1,4 +1,4 @@
-# $OpenBSD: files.alpha,v 1.57 2002/04/28 20:55:14 pvalchev Exp $
+# $OpenBSD: files.alpha,v 1.58 2002/05/02 22:56:06 miod Exp $
# $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $
#
# alpha-specific configuration info
@@ -60,55 +60,50 @@ include "dev/wsfont/files.wsfont"
include "dev/wscons/files.wscons"
#
-# TurboChannel Devices
+# Bus-independent support for DEC devices
+#
+include "dev/dec/files.dec"
+
+#
+# TURBOchannel Devices
#
include "dev/tc/files.tc"
+# TC attachment is MD
+attach tc at tcbus
+
device tcasic: tcbus
attach tcasic at mainbus
file arch/alpha/tc/tcasic.c tcasic
file arch/alpha/tc/tc_bus_mem.c tcasic
+file arch/alpha/tc/tc_dma.c tcasic
+file arch/alpha/tc/tc_dma_3000_300.c tcasic & dec_3000_300
+file arch/alpha/tc/tc_dma_3000_500.c tcasic & dec_3000_500
+file arch/alpha/tc/tc_sgmap.c tcasic & dec_3000_500
file arch/alpha/tc/tc_3000_500.c tcasic & dec_3000_500
file arch/alpha/tc/tc_3000_300.c tcasic & dec_3000_300
-# the TurboChannel IOCTL ASIC
-device ioasic { offset = -1 }
-attach ioasic at tc
+# the TURBOchannel IOCTL ASIC
+# IOASIC device and attachment defined in sys/dev/tc/files.tc
file arch/alpha/tc/ioasic.c ioasic
-# Color Frame buffer
+# PMAG-B CX
device cfb: wsemuldisplaydev, wsrasteremulops
attach cfb at tc
-file arch/alpha/tc/cfb.c cfb
+file arch/alpha/tc/cfb.c cfb needs-flag
-# Smart Frame buffer
+# PMAGB-B HX or CXT
device sfb: wsemuldisplaydev, wsrasteremulops
attach sfb at tc
-file arch/alpha/tc/sfb.c sfb
+file arch/alpha/tc/sfb.c sfb needs-flag
# 8530 UARTs
device scc
attach scc at ioasic
file arch/alpha/tc/scc.c scc needs-count
-# the TCDS ASIC
-device tcds { slot = -1 }
-attach tcds at tc
-file arch/alpha/tc/tcds.c tcds needs-count
-
-# 53C[F]90 SCSI
-device asc: scsi
-attach asc at tcds
-file arch/alpha/tc/asc.c asc needs-count
-file arch/alpha/tc/tcds_dma.c asc
-
-# Baseboard Lance ethernet.
-attach le at ioasic with le_ioasic
-attach le at tc with le_tc
-file dev/tc/if_le_dec.c (le_ioasic | le_tc)
-file dev/tc/if_le_ioasic.c le_ioasic needs-flag #for le_iomem
-file dev/tc/if_le_tc.c le_tc
+# TC and baseboard ioasic Lance ethernet are in files.tc
#
# ISA Bus support
diff --git a/sys/arch/alpha/tc/tc_machdep.h b/sys/arch/alpha/include/tc_machdep.h
index 3c26c5c8f85..c286497698a 100644
--- a/sys/arch/alpha/tc/tc_machdep.h
+++ b/sys/arch/alpha/include/tc_machdep.h
@@ -1,5 +1,5 @@
-/* $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 $ */
+/* $OpenBSD: tc_machdep.h,v 1.3 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_machdep.h,v 1.4 2000/06/01 00:04:50 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -92,4 +92,22 @@ typedef int32_t tc_offset_t;
#define TC_PHYS_TO_UNCACHED(addr) \
(addr)
-bus_space_tag_t tc_bus_mem_init(void *memv);;
+/*
+ * These functions are private, and may not be called by
+ * machine-independent code.
+ */
+bus_space_tag_t tc_bus_mem_init(void *memv);
+void tc_dma_init(void);
+
+/*
+ * Address of scatter/gather SRAM on the 3000/500-series.
+ *
+ * There is room for 32K entries, yielding 256M of sgva space.
+ * The page table is readable in both dense and sparse space.
+ * The page table is writable only in sparse space.
+ *
+ * In sparse space, the 32-bit PTEs are followed by 32-bits
+ * of pad.
+ */
+#define TC_SGSRAM_DENSE 0x0000001c2800000UL
+#define TC_SGSRAM_SPARSE 0x0000001d5000000UL
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_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/dev/dec/clockvar.h b/sys/dev/dec/clockvar.h
new file mode 100644
index 00000000000..b314d74fe45
--- /dev/null
+++ b/sys/dev/dec/clockvar.h
@@ -0,0 +1,63 @@
+/* $OpenBSD: clockvar.h,v 1.1 2002/05/02 22:56:02 miod Exp $ */
+/* $NetBSD: clockvar.h,v 1.4 1997/06/22 08:02:18 jonathan 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.
+ */
+
+/*
+ * Definitions for cpu-independent clock handling for the alpha and pmax.
+ */
+
+/*
+ * clocktime structure:
+ *
+ * structure passed to TOY clocks when setting them. broken out this
+ * way, so that the time_t -> field conversion can be shared.
+ */
+struct clocktime {
+ int year; /* year - 1900 */
+ int mon; /* month (1 - 12) */
+ int day; /* day (1 - 31) */
+ int hour; /* hour (0 - 23) */
+ int min; /* minute (0 - 59) */
+ int sec; /* second (0 - 59) */
+ int dow; /* day of week (0 - 6; 0 = Sunday) */
+};
+
+/*
+ * clockfns structure:
+ *
+ * function switch used by chip-independent clock code, to access
+ * chip-dependent routines.
+ */
+struct clockfns {
+ void (*cf_init)(struct device *);
+ void (*cf_get)(struct device *, time_t, struct clocktime *);
+ void (*cf_set)(struct device *, struct clocktime *);
+};
+
+void clockattach(struct device *, const struct clockfns *);
diff --git a/sys/dev/dec/files.dec b/sys/dev/dec/files.dec
new file mode 100644
index 00000000000..16b94890e61
--- /dev/null
+++ b/sys/dev/dec/files.dec
@@ -0,0 +1,13 @@
+# $OpenBSD: files.dec,v 1.1 2002/05/02 22:56:02 miod Exp $
+# $NetBSD: files.dec,v 1.7 2002/03/13 15:18:22 ad Exp $
+#
+# Config file and device description for machine-independent
+# code for devices for Digital Equipment Corp. systems.
+# Included by ports that need it.
+
+# Attribute for DEC lance padded-DMA copy functions. Lance attachments
+# which need it should specify the le_de_subr attribute.
+define le_dec_subr
+
+# DMA copy functions. Lance attachments qhich Decices
+file dev/dec/if_le_dec.c le_dec_subr
diff --git a/sys/dev/tc/if_le_dec.c b/sys/dev/dec/if_le_dec.c
index 68a96fbeb6f..67e1720f20c 100644
--- a/sys/dev/tc/if_le_dec.c
+++ b/sys/dev/dec/if_le_dec.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: if_le_dec.c,v 1.5 2002/03/14 01:27:03 millert Exp $ */
-/* $NetBSD: if_le_dec.c,v 1.3 1996/10/13 01:38:38 christos Exp $ */
+/* $OpenBSD: if_le_dec.c,v 1.1 2002/05/02 22:56:02 miod Exp $ */
+/* $NetBSD: if_le_dec.c,v 1.12 2001/11/13 12:49:45 lukem Exp $ */
/*-
+ * Copyright (c) 1997 Jonathan Stone. All rights reserved.
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -40,8 +41,6 @@
* @(#)if_le.c 8.2 (Berkeley) 11/16/93
*/
-#include "bpfilter.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@@ -63,13 +62,15 @@
#include <dev/tc/if_levar.h>
#include <dev/tc/tcvar.h>
+#include <machine/bus.h>
+
/* access LANCE registers */
void le_dec_writereg(volatile u_short *regptr, u_short val);
#define LERDWR(cntl, src, dst) { (dst) = (src); tc_mb(); }
#define LEWREG(src, dst) le_dec_writereg(&(dst), (src))
-hide void le_dec_wrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
-hide u_int16_t le_dec_rdcsr(struct am7990_softc *, u_int16_t);
+void le_dec_wrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
+u_int16_t le_dec_rdcsr(struct am7990_softc *, u_int16_t);
void
dec_le_common_attach(sc, eap)
@@ -97,7 +98,7 @@ dec_le_common_attach(sc, eap)
am7990_config(sc);
}
-hide void
+void
le_dec_wrcsr(sc, port, val)
struct am7990_softc *sc;
u_int16_t port, val;
@@ -108,7 +109,7 @@ le_dec_wrcsr(sc, port, val)
LERDWR(port, val, ler1->ler1_rdp);
}
-hide u_int16_t
+u_int16_t
le_dec_rdcsr(sc, port)
struct am7990_softc *sc;
u_int16_t port;
@@ -152,7 +153,7 @@ le_dec_writereg(regptr, val)
* 3 ways:
* - contiguous (for the 3max and turbochannel option card)
* - gap2, which means shorts (2 bytes) interspersed with short (2 byte)
- * spaces (for the pmax)
+ * spaces (for the pmax, vax 3400, and ioasic LANCE descriptors)
* - gap16, which means 16bytes interspersed with 16byte spaces
* for buffers which must begin on a 32byte boundary (for 3min, maxine,
* and alpha)
diff --git a/sys/dev/dec/mcclockvar.h b/sys/dev/dec/mcclockvar.h
new file mode 100644
index 00000000000..c12584c6bdb
--- /dev/null
+++ b/sys/dev/dec/mcclockvar.h
@@ -0,0 +1,42 @@
+/* $OpenBSD: mcclockvar.h,v 1.1 2002/05/02 22:56:02 miod Exp $ */
+/* $NetBSD: mcclockvar.h,v 1.4 1997/06/22 08:02:19 jonathan Exp $ */
+
+/*
+ * Copyright (c) 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 mcclock_softc {
+ struct device sc_dev;
+ const struct mcclock_busfns *sc_busfns;
+};
+
+struct mcclock_busfns {
+ void (*mc_bf_write)(struct mcclock_softc *, u_int, u_int);
+ u_int (*mc_bf_read)(struct mcclock_softc *, u_int);
+};
+
+void mcclock_attach(struct mcclock_softc *,
+ const struct mcclock_busfns *);
diff --git a/sys/dev/tc/asc.c b/sys/dev/tc/asc.c
new file mode 100644
index 00000000000..b9fd2d5e692
--- /dev/null
+++ b/sys/dev/tc/asc.c
@@ -0,0 +1,127 @@
+/* $OpenBSD: asc.c,v 1.21 2002/05/02 22:56:06 miod Exp $ */
+
+/*-
+ * Copyright (c) 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 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/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+#include <dev/tc/ascvar.h>
+
+struct cfdriver asc_cd = {
+ NULL, "asc", DV_DULL,
+};
+
+struct scsi_adapter asc_switch = {
+ ncr53c9x_scsi_cmd,
+ minphys, /* no max at this level; handled by DMA code */
+ NULL,
+ NULL,
+};
+
+struct scsi_device asc_dev = {
+ NULL, /* Use default error handler */
+ NULL, /* have a queue, served by this */
+ NULL, /* have no async handler */
+ NULL, /* Use default `done' routine */
+};
+
+/*
+ * Glue functions
+ */
+u_char
+asc_read_reg(sc, reg)
+ struct ncr53c9x_softc *sc;
+ int reg;
+{
+ struct asc_softc *asc = (struct asc_softc *)sc;
+ u_char v;
+
+ v = bus_space_read_4(asc->sc_bst, asc->sc_bsh,
+ reg * sizeof(u_int32_t)) & 0xff;
+
+ return (v);
+}
+
+void
+asc_write_reg(sc, reg, val)
+ struct ncr53c9x_softc *sc;
+ int reg;
+ u_char val;
+{
+ struct asc_softc *asc = (struct asc_softc *)sc;
+
+ bus_space_write_4(asc->sc_bst, asc->sc_bsh,
+ reg * sizeof(u_int32_t), val);
+}
+
diff --git a/sys/dev/tc/asc_tc.c b/sys/dev/tc/asc_tc.c
new file mode 100644
index 00000000000..df417243dba
--- /dev/null
+++ b/sys/dev/tc/asc_tc.c
@@ -0,0 +1,330 @@
+/* $OpenBSD: asc_tc.c,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: asc_tc.c,v 1.19 2001/11/15 09:48:19 lukem Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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/device.h>
+#include <sys/buf.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <scsi/scsi_message.h>
+
+#include <machine/bus.h>
+
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+#include <dev/tc/ascvar.h>
+
+#include <dev/tc/tcvar.h>
+
+struct asc_tc_softc {
+ struct asc_softc asc;
+
+ /* XXX XXX XXX */
+ caddr_t sc_base, sc_bounce, sc_target;
+};
+
+int asc_tc_match(struct device *, void *, void *);
+void asc_tc_attach(struct device *, struct device *, void *);
+
+struct cfattach asc_tc_ca = {
+ sizeof(struct asc_tc_softc), asc_tc_match, asc_tc_attach
+};
+
+extern struct scsi_adapter asc_switch;
+extern struct scsi_device asc_dev;
+
+int asc_dma_isintr(struct ncr53c9x_softc *);
+void asc_tc_reset(struct ncr53c9x_softc *);
+int asc_tc_intr(struct ncr53c9x_softc *);
+int asc_tc_setup(struct ncr53c9x_softc *, caddr_t *,
+ size_t *, int, size_t *);
+void asc_tc_go(struct ncr53c9x_softc *);
+void asc_tc_stop(struct ncr53c9x_softc *);
+int asc_dma_isactive(struct ncr53c9x_softc *);
+void asc_clear_latched_intr(struct ncr53c9x_softc *);
+
+struct ncr53c9x_glue asc_tc_glue = {
+ asc_read_reg,
+ asc_write_reg,
+ asc_dma_isintr,
+ asc_tc_reset,
+ asc_tc_intr,
+ asc_tc_setup,
+ asc_tc_go,
+ asc_tc_stop,
+ asc_dma_isactive,
+ asc_clear_latched_intr,
+};
+
+/*
+ * Parameters specific to PMAZ-A TC option card.
+ */
+#define PMAZ_OFFSET_53C94 0x0 /* from module base */
+#define PMAZ_OFFSET_DMAR 0x40000 /* DMA Address Register */
+#define PMAZ_OFFSET_RAM 0x80000 /* 128KB SRAM buffer */
+#define PMAZ_OFFSET_ROM 0xc0000 /* diagnostic ROM */
+
+#define PMAZ_RAM_SIZE 0x20000 /* 128k (32k*32) */
+#define PER_TGT_DMA_SIZE ((PMAZ_RAM_SIZE/7) & ~(sizeof(int)-1))
+
+#define PMAZ_DMAR_WRITE 0x80000000 /* DMA direction bit */
+#define PMAZ_DMAR_MASK 0x1ffff /* 17 bits, 128k */
+#define PMAZ_DMA_ADDR(x) ((unsigned long)(x) & PMAZ_DMAR_MASK)
+
+int
+asc_tc_match(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata, *aux;
+{
+ struct tc_attach_args *d = aux;
+
+ if (strncmp("PMAZ-AA ", d->ta_modname, TC_ROM_LLEN))
+ return (0);
+
+ return (1);
+}
+
+void
+asc_tc_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct tc_attach_args *ta = aux;
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)self;
+ struct ncr53c9x_softc *sc = &asc->asc.sc_ncr53c9x;
+
+ /*
+ * Set up glue for MI code early; we use some of it here.
+ */
+ sc->sc_glue = &asc_tc_glue;
+ asc->asc.sc_bst = ta->ta_memt;
+ asc->asc.sc_dmat = ta->ta_dmat;
+ if (bus_space_map(asc->asc.sc_bst, ta->ta_addr,
+ PMAZ_OFFSET_RAM + PMAZ_RAM_SIZE, 0, &asc->asc.sc_bsh)) {
+ printf("%s: unable to map device\n", sc->sc_dev.dv_xname);
+ return;
+ }
+ asc->sc_base = (caddr_t)ta->ta_addr; /* XXX XXX XXX */
+
+ tc_intr_establish(parent, ta->ta_cookie, IPL_BIO, ncr53c9x_intr, sc);
+
+ sc->sc_id = 7;
+ sc->sc_freq = (ta->ta_busspeed) ? 25000000 : 12500000;
+
+ /* gimme Mhz */
+ sc->sc_freq /= 1000000;
+
+ /*
+ * XXX More of this should be in ncr53c9x_attach(), but
+ * XXX should we really poke around the chip that much in
+ * XXX the MI code? Think about this more...
+ */
+
+ /*
+ * Set up static configuration info.
+ */
+ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
+ sc->sc_cfg2 = NCRCFG2_SCSI2;
+ sc->sc_cfg3 = 0;
+ sc->sc_rev = NCR_VARIANT_NCR53C94;
+
+ /*
+ * XXX minsync and maxxfer _should_ be set up in MI code,
+ * XXX but it appears to have some dependency on what sort
+ * XXX of DMA we're hooked up to, etc.
+ */
+
+ /*
+ * This is the value used to start sync negotiations
+ * Note that the NCR 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) * 5 / 4;
+
+ sc->sc_maxxfer = 64 * 1024;
+
+ /* Do the common parts of attachment. */
+ ncr53c9x_attach(sc, &asc_switch, &asc_dev);
+}
+
+void
+asc_tc_reset(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
+
+ asc->asc.sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
+}
+
+int
+asc_tc_intr(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
+ int trans, resid;
+
+ resid = 0;
+ if ((asc->asc.sc_flags & ASC_ISPULLUP) == 0 &&
+ (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+ NCR_DMA(("asc_tc_intr: empty FIFO of %d ", resid));
+ DELAY(1);
+ }
+
+ resid += NCR_READ_REG(sc, NCR_TCL);
+ resid += NCR_READ_REG(sc, NCR_TCM) << 8;
+
+ trans = asc->asc.sc_dmasize - resid;
+
+ if (asc->asc.sc_flags & ASC_ISPULLUP)
+ memcpy(asc->sc_target, asc->sc_bounce, trans);
+ *asc->asc.sc_dmalen -= trans;
+ *asc->asc.sc_dmaaddr += trans;
+ asc->asc.sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
+
+ return (0);
+}
+
+int
+asc_tc_setup(sc, addr, len, datain, dmasize)
+ struct ncr53c9x_softc *sc;
+ caddr_t *addr;
+ size_t *len;
+ int datain;
+ size_t *dmasize;
+{
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
+ u_int32_t tc_dmar;
+ size_t size;
+
+ asc->asc.sc_dmaaddr = addr;
+ asc->asc.sc_dmalen = len;
+ asc->asc.sc_flags = (datain) ? ASC_ISPULLUP : 0;
+
+ NCR_DMA(("asc_tc_setup: start %ld@%p, %s\n", (long)*asc->asc.sc_dmalen,
+ *asc->asc.sc_dmaaddr, datain ? "IN" : "OUT"));
+
+ size = *dmasize;
+ if (size > PER_TGT_DMA_SIZE)
+ size = PER_TGT_DMA_SIZE;
+ *dmasize = asc->asc.sc_dmasize = size;
+
+ NCR_DMA(("asc_tc_setup: dmasize = %ld\n", (long)asc->asc.sc_dmasize));
+
+ asc->sc_bounce = asc->sc_base + PMAZ_OFFSET_RAM;
+ asc->sc_bounce += PER_TGT_DMA_SIZE *
+ sc->sc_nexus->xs->sc_link->target;
+ asc->sc_target = *addr;
+
+ if ((asc->asc.sc_flags & ASC_ISPULLUP) == 0)
+ memcpy(asc->sc_bounce, asc->sc_target, size);
+
+#if 1
+ if (asc->asc.sc_flags & ASC_ISPULLUP)
+ tc_dmar = PMAZ_DMA_ADDR(asc->sc_bounce);
+ else
+ tc_dmar = PMAZ_DMAR_WRITE | PMAZ_DMA_ADDR(asc->sc_bounce);
+ bus_space_write_4(asc->asc.sc_bst, asc->asc.sc_bsh, PMAZ_OFFSET_DMAR,
+ tc_dmar);
+ asc->asc.sc_flags |= ASC_MAPLOADED|ASC_DMAACTIVE;
+#endif
+ return (0);
+}
+
+void
+asc_tc_go(sc)
+ struct ncr53c9x_softc *sc;
+{
+#if 0
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
+ u_int32_t tc_dmar;
+
+ if (asc->asc.sc_flags & ASC_ISPULLUP)
+ tc_dmar = PMAZ_DMA_ADDR(asc->sc_bounce);
+ else
+ tc_dmar = PMAZ_DMAR_WRITE | PMAZ_DMA_ADDR(asc->sc_bounce);
+ bus_space_write_4(asc->asc.sc_bst, asc->asc.sc_bsh, PMAZ_OFFSET_DMAR,
+ tc_dmar);
+ asc->asc.sc_flags |= ASC_DMAACTIVE;
+#endif
+}
+
+/* NEVER CALLED BY MI 53C9x ENGINE INDEED */
+void
+asc_tc_stop(sc)
+ struct ncr53c9x_softc *sc;
+{
+#if 0
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
+
+ if (asc->asc.sc_flags & ASC_ISPULLUP)
+ memcpy(asc->sc_target, asc->sc_bounce, asc->sc_dmasize);
+ asc->asc.sc_flags &= ~ASC_DMAACTIVE;
+#endif
+}
+
+/*
+ * Glue functions.
+ */
+int
+asc_dma_isintr(sc)
+ struct ncr53c9x_softc *sc;
+{
+ return !!(NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT);
+}
+
+int
+asc_dma_isactive(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
+
+ return !!(asc->asc.sc_flags & ASC_DMAACTIVE);
+}
+
+void
+asc_clear_latched_intr(sc)
+ struct ncr53c9x_softc *sc;
+{
+}
diff --git a/sys/dev/tc/asc_tcds.c b/sys/dev/tc/asc_tcds.c
new file mode 100644
index 00000000000..aecbef78109
--- /dev/null
+++ b/sys/dev/tc/asc_tcds.c
@@ -0,0 +1,495 @@
+/* $OpenBSD: asc_tcds.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: asc_tcds.c,v 1.5 2001/11/15 09:48:19 lukem Exp $ */
+
+/*-
+ * Copyright (c) 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 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/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+#include <dev/tc/ascvar.h>
+
+#include <machine/bus.h>
+
+#include <dev/tc/tcvar.h>
+#include <dev/tc/tcdsreg.h>
+#include <dev/tc/tcdsvar.h>
+
+struct asc_tcds_softc {
+ struct asc_softc asc;
+
+ struct tcds_slotconfig *sc_tcds;
+};
+
+int asc_tcds_match (struct device *, void *, void *);
+void asc_tcds_attach(struct device *, struct device *, void *);
+
+/* Linkup to the rest of the kernel */
+struct cfattach asc_tcds_ca = {
+ sizeof(struct asc_tcds_softc), asc_tcds_match, asc_tcds_attach
+};
+
+/*
+ * Functions and the switch for the MI code.
+ */
+int tcds_dma_isintr(struct ncr53c9x_softc *);
+void tcds_dma_reset(struct ncr53c9x_softc *);
+int tcds_dma_intr(struct ncr53c9x_softc *);
+int tcds_dma_setup(struct ncr53c9x_softc *, caddr_t *,
+ size_t *, int, size_t *);
+void tcds_dma_go(struct ncr53c9x_softc *);
+void tcds_dma_stop(struct ncr53c9x_softc *);
+int tcds_dma_isactive(struct ncr53c9x_softc *);
+void tcds_clear_latched_intr(struct ncr53c9x_softc *);
+
+struct ncr53c9x_glue asc_tcds_glue = {
+ asc_read_reg,
+ asc_write_reg,
+ tcds_dma_isintr,
+ tcds_dma_reset,
+ tcds_dma_intr,
+ tcds_dma_setup,
+ tcds_dma_go,
+ tcds_dma_stop,
+ tcds_dma_isactive,
+ tcds_clear_latched_intr,
+};
+
+extern struct scsi_adapter asc_switch;
+extern struct scsi_device asc_dev;
+
+int
+asc_tcds_match(parent, cf, aux)
+ struct device *parent;
+ void *cf, *aux;
+{
+
+ /* We always exist. */
+ return 1;
+}
+
+#define DMAMAX(a) (NBPG - ((a) & (NBPG - 1)))
+
+/*
+ * Attach this instance, and then all the sub-devices
+ */
+void
+asc_tcds_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct tcdsdev_attach_args *tcdsdev = aux;
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)self;
+ struct ncr53c9x_softc *sc = &asc->asc.sc_ncr53c9x;
+ int error;
+
+ /*
+ * Set up glue for MI code early; we use some of it here.
+ */
+ sc->sc_glue = &asc_tcds_glue;
+
+ asc->asc.sc_bst = tcdsdev->tcdsda_bst;
+ asc->asc.sc_bsh = tcdsdev->tcdsda_bsh;
+ asc->sc_tcds = tcdsdev->tcdsda_sc;
+
+ /*
+ * The TCDS ASIC cannot DMA across 8k boundaries, and this
+ * driver is written such that each DMA segment gets a new
+ * call to tcds_dma_setup(). Thus, the DMA map only needs
+ * to support 8k transfers.
+ */
+ asc->asc.sc_dmat = tcdsdev->tcdsda_dmat;
+ if ((error = bus_dmamap_create(asc->asc.sc_dmat, NBPG, 1, NBPG,
+ NBPG, BUS_DMA_NOWAIT, &asc->asc.sc_dmamap)) < 0) {
+ printf("failed to create dma map, error = %d\n", error);
+ }
+
+ sc->sc_id = tcdsdev->tcdsda_id;
+ sc->sc_freq = tcdsdev->tcdsda_freq;
+
+ /* gimme Mhz */
+ sc->sc_freq /= 1000000;
+
+ tcds_intr_establish(parent, tcdsdev->tcdsda_chip, ncr53c9x_intr, sc);
+
+ /*
+ * XXX More of this should be in ncr53c9x_attach(), but
+ * XXX should we really poke around the chip that much in
+ * XXX the MI code? Think about this more...
+ */
+
+ /*
+ * Set up static configuration info.
+ */
+ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
+ sc->sc_cfg2 = NCRCFG2_SCSI2;
+ sc->sc_cfg3 = NCRCFG3_CDB;
+ if (sc->sc_freq > 25)
+ sc->sc_cfg3 |= NCRF9XCFG3_FCLK;
+ sc->sc_rev = tcdsdev->tcdsda_variant;
+ if (tcdsdev->tcdsda_fast) {
+ sc->sc_features |= NCR_F_FASTSCSI;
+ sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI;
+ }
+
+ /*
+ * XXX minsync and maxxfer _should_ be set up in MI code,
+ * XXX but it appears to have some dependency on what sort
+ * XXX of DMA we're hooked up to, etc.
+ */
+
+ /*
+ * This is the value used to start sync negotiations
+ * Note that the NCR 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) * tcdsdev->tcdsda_period / 4;
+
+ sc->sc_maxxfer = 64 * 1024;
+
+ /* Do the common parts of attachment. */
+ ncr53c9x_attach(sc, &asc_switch, &asc_dev);
+}
+
+void
+tcds_dma_reset(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+
+ /* TCDS SCSI disable/reset/enable. */
+ tcds_scsi_reset(asc->sc_tcds); /* XXX */
+
+ if (asc->asc.sc_flags & ASC_MAPLOADED)
+ bus_dmamap_unload(asc->asc.sc_dmat, asc->asc.sc_dmamap);
+ asc->asc.sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
+}
+
+/*
+ * start a dma transfer or keep it going
+ */
+int
+tcds_dma_setup(sc, addr, len, ispullup, dmasize)
+ struct ncr53c9x_softc *sc;
+ caddr_t *addr;
+ size_t *len, *dmasize;
+ int ispullup; /* DMA into main memory */
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+ struct tcds_slotconfig *tcds = asc->sc_tcds;
+ size_t size;
+ u_int32_t dic;
+
+ NCR_DMA(("tcds_dma %d: start %d@%p,%s\n", tcds->sc_slot,
+ (int)*asc->asc.sc_dmalen, *asc->asc.sc_dmaaddr,
+ (ispullup) ? "IN" : "OUT"));
+
+ /*
+ * 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)*addr));
+ asc->asc.sc_dmaaddr = addr;
+ asc->asc.sc_dmalen = len;
+ asc->asc.sc_flags = (ispullup) ? ASC_ISPULLUP : 0;
+ *dmasize = asc->asc.sc_dmasize = size;
+
+ NCR_DMA(("dma_start: dmasize = %d\n", (int)size));
+
+ if (size == 0)
+ return 0;
+
+ if (bus_dmamap_load(asc->asc.sc_dmat, asc->asc.sc_dmamap, *addr, size,
+ NULL, BUS_DMA_NOWAIT | (ispullup ? BUS_DMA_READ : BUS_DMA_WRITE))) {
+ /*
+ * XXX Should return an error, here, but the upper-layer
+ * XXX doesn't check the return value!
+ */
+ panic("tcds_dma_setup: dmamap load failed");
+ }
+
+ /* synchronize dmamap contents with memory image */
+ bus_dmamap_sync(asc->asc.sc_dmat, asc->asc.sc_dmamap, 0, size,
+ (ispullup) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
+ /* load address, set/clear unaligned transfer and read/write bits. */
+ bus_space_write_4(tcds->sc_bst, tcds->sc_bsh, tcds->sc_sda,
+ asc->asc.sc_dmamap->dm_segs[0].ds_addr >> 2);
+ dic = bus_space_read_4(tcds->sc_bst, tcds->sc_bsh, tcds->sc_dic);
+ dic &= ~TCDS_DIC_ADDRMASK;
+ dic |= asc->asc.sc_dmamap->dm_segs[0].ds_addr & TCDS_DIC_ADDRMASK;
+ if (ispullup)
+ dic |= TCDS_DIC_WRITE;
+ else
+ dic &= ~TCDS_DIC_WRITE;
+ bus_space_write_4(tcds->sc_bst, tcds->sc_bsh, tcds->sc_dic, dic);
+
+ asc->asc.sc_flags |= ASC_MAPLOADED;
+ return 0;
+}
+
+void
+tcds_dma_go(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+
+ /* mark unit as DMA-active */
+ asc->asc.sc_flags |= ASC_DMAACTIVE;
+
+ /* start DMA */
+ tcds_dma_enable(asc->sc_tcds, 1);
+}
+
+void
+tcds_dma_stop(sc)
+ struct ncr53c9x_softc *sc;
+{
+#if 0
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+#endif
+
+ /*
+ * XXX STOP DMA HERE!
+ */
+}
+
+/*
+ * Pseudo (chained) interrupt from the asc driver to kick the
+ * current running DMA transfer. Called from ncr53c9x_intr()
+ * for now.
+ *
+ * return 1 if it was a DMA continue.
+ */
+int
+tcds_dma_intr(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+ struct tcds_slotconfig *tcds = asc->sc_tcds;
+ int trans, resid;
+ u_int32_t tcl, tcm;
+ u_int32_t dud, dudmask, *addr;
+ bus_addr_t pa;
+
+ NCR_DMA(("tcds_dma %d: intr", tcds->sc_slot));
+
+ if (tcds_scsi_iserr(tcds))
+ return 0;
+
+ /* This is an "assertion" :) */
+ if ((asc->asc.sc_flags & ASC_DMAACTIVE) == 0)
+ panic("tcds_dma_intr: DMA wasn't active");
+
+ /* DMA has stopped */
+ tcds_dma_enable(tcds, 0);
+ asc->asc.sc_flags &= ~ASC_DMAACTIVE;
+
+ if (asc->asc.sc_dmasize == 0) {
+ /* A "Transfer Pad" operation completed */
+ tcl = NCR_READ_REG(sc, NCR_TCL);
+ tcm = NCR_READ_REG(sc, NCR_TCM);
+ NCR_DMA(("dma_intr: discarded %d bytes (tcl=%d, tcm=%d)\n",
+ tcl | (tcm << 8), tcl, tcm));
+ return 0;
+ }
+
+ resid = 0;
+ if ((asc->asc.sc_flags & ASC_ISPULLUP) == 0 &&
+ (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+ NCR_DMA(("dma_intr: empty esp FIFO of %d ", resid));
+ DELAY(1);
+ }
+
+ resid += (tcl = NCR_READ_REG(sc, NCR_TCL));
+ resid += (tcm = NCR_READ_REG(sc, NCR_TCM)) << 8;
+
+ trans = asc->asc.sc_dmasize - resid;
+ if (trans < 0) { /* transferred < 0 ? */
+ printf("tcds_dma %d: xfer (%d) > req (%d)\n",
+ tcds->sc_slot, trans, (int)asc->asc.sc_dmasize);
+ trans = asc->asc.sc_dmasize;
+ }
+
+ NCR_DMA(("dma_intr: tcl=%d, tcm=%d; trans=%d, resid=%d\n",
+ tcl, tcm, trans, resid));
+
+ *asc->asc.sc_dmalen -= trans;
+ *asc->asc.sc_dmaaddr += trans;
+
+ bus_dmamap_sync(asc->asc.sc_dmat, asc->asc.sc_dmamap,
+ 0, asc->asc.sc_dmamap->dm_mapsize,
+ (asc->asc.sc_flags & ASC_ISPULLUP)
+ ? BUS_DMASYNC_POSTREAD
+ : BUS_DMASYNC_POSTWRITE);
+
+ /*
+ * Clean up unaligned DMAs into main memory.
+ */
+ if (asc->asc.sc_flags & ASC_ISPULLUP) {
+ /* Handle unaligned starting address, length. */
+ dud = bus_space_read_4(tcds->sc_bst,
+ tcds->sc_bsh, tcds->sc_dud0);
+ if ((dud & TCDS_DUD0_VALIDBITS) != 0) {
+ addr = (u_int32_t *)
+ ((paddr_t)*asc->asc.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
+ NCR_DMA(("dud0 at 0x%p dudmask 0x%x\n",
+ addr, dudmask));
+ *addr = (*addr & ~dudmask) | (dud & dudmask);
+ }
+ dud = bus_space_read_4(tcds->sc_bst,
+ tcds->sc_bsh, tcds->sc_dud1);
+ if ((dud & TCDS_DUD1_VALIDBITS) != 0) {
+ pa = bus_space_read_4(tcds->sc_bst, tcds->sc_bsh,
+ tcds->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
+ NCR_DMA(("dud1 at 0x%lx dudmask 0x%x\n",
+ pa, dudmask));
+ /* XXX Fix TC_PHYS_TO_UNCACHED() */
+#if defined(__alpha__)
+ addr = (u_int32_t *)ALPHA_PHYS_TO_K0SEG(pa);
+#elif defined(__mips__)
+ addr = (u_int32_t *)MIPS_PHYS_TO_KSEG1(pa);
+#else
+#error TURBOchannel only exists on DECs, folks...
+#endif
+ *addr = (*addr & ~dudmask) | (dud & dudmask);
+ }
+ /* XXX deal with saved residual byte? */
+ }
+
+ bus_dmamap_unload(asc->asc.sc_dmat, asc->asc.sc_dmamap);
+ asc->asc.sc_flags &= ~ASC_MAPLOADED;
+
+ return 0;
+}
+
+/*
+ * Glue functions.
+ */
+int
+tcds_dma_isintr(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+ int x;
+
+ x = tcds_scsi_isintr(asc->sc_tcds, 1);
+
+ /* XXX */
+ return x;
+}
+
+int
+tcds_dma_isactive(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+
+ return !!(asc->asc.sc_flags & ASC_DMAACTIVE);
+}
+
+void
+tcds_clear_latched_intr(sc)
+ struct ncr53c9x_softc *sc;
+{
+ struct asc_tcds_softc *asc = (struct asc_tcds_softc *)sc;
+
+ /* Clear the TCDS interrupt bit. */
+ (void)tcds_scsi_isintr(asc->sc_tcds, 1);
+}
diff --git a/sys/dev/tc/ascvar.h b/sys/dev/tc/ascvar.h
new file mode 100644
index 00000000000..f69e770dc5d
--- /dev/null
+++ b/sys/dev/tc/ascvar.h
@@ -0,0 +1,24 @@
+/* $OpenBSD: ascvar.h,v 1.9 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: ascvar.h,v 1.7 2000/10/31 15:16:26 simonb Exp $ */
+
+/*
+ * State kept for each active SCSI host interface (53C94).
+ */
+
+struct asc_softc {
+ struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
+ bus_space_tag_t sc_bst; /* bus space tag */
+ bus_space_handle_t sc_bsh; /* ASC register handle */
+ bus_dma_tag_t sc_dmat; /* bus dma tag */
+ bus_dmamap_t sc_dmamap; /* bus dmamap */
+ caddr_t *sc_dmaaddr;
+ size_t *sc_dmalen;
+ size_t sc_dmasize;
+ unsigned sc_flags;
+#define ASC_ISPULLUP 0x01
+#define ASC_DMAACTIVE 0x02
+#define ASC_MAPLOADED 0x04
+};
+
+u_char asc_read_reg(struct ncr53c9x_softc *, int);
+void asc_write_reg(struct ncr53c9x_softc *, int, u_char);
diff --git a/sys/dev/tc/devlist2h.awk b/sys/dev/tc/devlist2h.awk
index 9164d87ac26..bf189844e04 100644
--- a/sys/dev/tc/devlist2h.awk
+++ b/sys/dev/tc/devlist2h.awk
@@ -1,5 +1,5 @@
#! /usr/bin/awk -f
-# $OpenBSD: devlist2h.awk,v 1.3 1996/12/08 01:03:03 niklas Exp $
+# $OpenBSD: devlist2h.awk,v 1.4 2002/05/02 22:56:06 miod Exp $
# $NetBSD: devlist2h.awk,v 1.3 1996/06/05 18:32:19 cgd Exp $
#
# Copyright (c) 1995, 1996 Christopher G. Demetriou
@@ -39,6 +39,7 @@ NR == 1 {
VERSION = $0
gsub("\\$", "", VERSION)
+ printf("/*\t\$OpenBSD\$\t*/\n\n") > dfile
printf("/*\n") > dfile
printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
> dfile
@@ -47,6 +48,7 @@ NR == 1 {
printf(" *\t%s\n", VERSION) > dfile
printf(" */\n") > dfile
+ printf("/*\t\$OpenBSD\$\t*/\n\n") > hfile
printf("/*\n") > hfile
printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
> hfile
diff --git a/sys/dev/tc/files.tc b/sys/dev/tc/files.tc
index 38490a44ab8..5c8b0895d6e 100644
--- a/sys/dev/tc/files.tc
+++ b/sys/dev/tc/files.tc
@@ -1,21 +1,42 @@
-# $OpenBSD: files.tc,v 1.5 1996/05/26 00:27:52 deraadt Exp $
-# $NetBSD: files.tc,v 1.5 1996/05/20 00:45:02 thorpej Exp $
+# $OpenBSD: files.tc,v 1.6 2002/05/02 22:56:06 miod Exp $
+# $NetBSD: files.tc,v 1.26 2001/11/28 10:21:24 lukem Exp $
#
-# Config.new file and device description for machine-independent
-# TurboChannel code. Included by ports that need it.
+# Config file and device description for machine-independent
+# TURBOchannel code. Included by ports that need it.
device tc {[slot = -1], [offset = -1]}
-attach tc at tcbus
+#attach tc at tcbus
file dev/tc/tc.c tc needs-flag
-# device defined in sys/conf/files
-# attach le at ioasic with le_ioasic
-# attach le at tc with le_tc
-# file dev/tc/if_le_dec.c (le_ioasic | le_tc)
-# file dev/tc/if_le_ioasic.c le_ioasic needs-flag # for le_iomem
-# file dev/tc/if_le_tc.c le_tc
+# IOCTL ASIC
+device ioasic { offset = -1 }
+attach ioasic at tc
+file dev/tc/ioasic_subr.c ioasic
-# DEC DEFTA TC FDDI Controller
+# LANCE attachments.
+# lance device defined in sys/conf/files
+# le_dec_subr attribute defined in sys/dev/dec/files.dec
+
+attach le at ioasic with le_ioasic: le_dec_subr
+file dev/tc/if_le_ioasic.c le_ioasic
+
+attach le at tc with le_tc: le_dec_subr
+file dev/tc/if_le_tc.c le_tc
+
+# DEFTA FDDI controller
device fta: pdq, fddi, ifnet
attach fta at tc
file dev/tc/if_fta.c fta
+
+# TCDS dual channel SCSI
+device tcds { chip = -1 }
+attach tcds at tc
+file dev/tc/tcds.c tcds
+
+# 53C[F]90 PMAZ single channel SCSI
+device asc: ncr53c9x, scsi
+file dev/tc/asc.c asc
+attach asc at tc with asc_tc
+file dev/tc/asc_tc.c asc_tc
+attach asc at tcds with asc_tcds
+file dev/tc/asc_tcds.c asc_tcds
diff --git a/sys/dev/tc/if_le_ioasic.c b/sys/dev/tc/if_le_ioasic.c
index 2ff91977d17..9eab3788dc2 100644
--- a/sys/dev/tc/if_le_ioasic.c
+++ b/sys/dev/tc/if_le_ioasic.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_le_ioasic.c,v 1.10 2002/03/14 01:27:03 millert Exp $ */
-/* $NetBSD: if_le_ioasic.c,v 1.2 1996/05/07 02:24:56 thorpej Exp $ */
+/* $OpenBSD: if_le_ioasic.c,v 1.11 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: if_le_ioasic.c,v 1.18 2001/11/13 06:26:10 lukem Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -42,8 +42,6 @@
#include <net/if.h>
#include <net/if_media.h>
-#include <uvm/uvm_extern.h>
-
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
@@ -54,26 +52,35 @@
#include <dev/tc/if_levar.h>
#include <dev/tc/tcvar.h>
+#include <dev/tc/ioasicreg.h>
#include <dev/tc/ioasicvar.h>
-int le_ioasic_match(struct device *, void *, void *);
-void le_ioasic_attach(struct device *, struct device *, void *);
+struct le_ioasic_softc {
+ struct am7990_softc sc_am7990; /* glue to MI code */
+ struct lereg1 *sc_r1; /* LANCE registers */
+ /* XXX must match with le_softc of if_levar.h XXX */
-hide void le_ioasic_copytobuf_gap2(struct am7990_softc *, void *,
- int, int);
-hide void le_ioasic_copyfrombuf_gap2(struct am7990_softc *, void *,
- int, int);
+ bus_dma_tag_t sc_dmat; /* bus dma tag */
+ bus_dmamap_t sc_dmamap; /* bus dmamap */
+};
-hide void le_ioasic_copytobuf_gap16(struct am7990_softc *, void *,
- int, int);
-hide void le_ioasic_copyfrombuf_gap16(struct am7990_softc *, void *,
- int, int);
-hide void le_ioasic_zerobuf_gap16(struct am7990_softc *, int, int);
+int le_ioasic_match(struct device *, void *, void *);
+void le_ioasic_attach(struct device *, struct device *, void *);
struct cfattach le_ioasic_ca = {
sizeof(struct le_softc), le_ioasic_match, le_ioasic_attach
};
+void le_ioasic_copytobuf_gap2(struct am7990_softc *, void *,
+ int, int);
+void le_ioasic_copyfrombuf_gap2(struct am7990_softc *, void *,
+ int, int);
+void le_ioasic_copytobuf_gap16(struct am7990_softc *, void *,
+ int, int);
+void le_ioasic_copyfrombuf_gap16(struct am7990_softc *, void *,
+ int, int);
+void le_ioasic_zerobuf_gap16(struct am7990_softc *, int, int);
+
int
le_ioasic_match(parent, match, aux)
struct device *parent;
@@ -81,67 +88,92 @@ le_ioasic_match(parent, match, aux)
{
struct ioasicdev_attach_args *d = aux;
- if (!ioasic_submatch(match, aux))
- return (0);
- if (strncmp("lance", d->iada_modname, TC_ROM_LLEN))
- return (0);
+ if (strncmp("PMAD-BA ", d->iada_modname, TC_ROM_LLEN) != 0)
+ return 0;
- return (1);
+ return 1;
}
-#define LE_IOASIC_MEMSIZE (128*1024)
-#define LE_IOASIC_MEMALIGN (128*1024)
+/* IOASIC LANCE DMA needs 128KB boundary aligned 128KB chunk */
+#define LE_IOASIC_MEMSIZE (128*1024)
+#define LE_IOASIC_MEMALIGN (128*1024)
+
void
le_ioasic_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
+ struct le_ioasic_softc *sc = (void *)self;
struct ioasicdev_attach_args *d = aux;
- struct le_softc *lesc = (void *)self;
- struct am7990_softc *sc = &lesc->sc_am7990;
+ struct am7990_softc *le = &sc->sc_am7990;
+ bus_space_tag_t ioasic_bst;
+ bus_space_handle_t ioasic_bsh;
+ bus_dma_tag_t dmat;
+ bus_dma_segment_t seg;
+ tc_addr_t tca;
+ u_int32_t ssr;
+ int rseg;
caddr_t le_iomem;
- struct pglist pglist;
- struct vm_page *pg;
- vaddr_t va;
- vsize_t size;
+ ioasic_bst = ((struct ioasic_softc *)parent)->sc_bst;
+ ioasic_bsh = ((struct ioasic_softc *)parent)->sc_bsh;
+ dmat = sc->sc_dmat = ((struct ioasic_softc *)parent)->sc_dmat;
/*
- * XXX - this vm juggling is so wrong. use bus_dma instead!
+ * Allocate a DMA area for the chip.
*/
- size = round_page(LE_IOASIC_MEMSIZE);
- if (uvm_pglistalloc(size, 0, 0, LE_IOASIC_MEMALIGN, 0, &pglist, 1, 0) ||
- uvm_map(kernel_map, &va, size, NULL, UVM_UNKNOWN_OFFSET, 0,
- UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE,
- UVM_ADV_RANDOM, 0)))
- panic("aha_init: could not allocate mailbox");
-
- le_iomem = (caddr_t)va;
- for (pg = TAILQ_FIRST(&pglist); pg != NULL;pg = TAILQ_NEXT(pg, pageq)) {
- pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
- VM_PROT_READ|VM_PROT_WRITE);
- va += PAGE_SIZE;
+ if (bus_dmamem_alloc(dmat, LE_IOASIC_MEMSIZE, LE_IOASIC_MEMALIGN,
+ 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+ printf("can't allocate DMA area for LANCE\n");
+ return;
+ }
+ if (bus_dmamem_map(dmat, &seg, rseg, LE_IOASIC_MEMSIZE,
+ &le_iomem, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
+ printf("can't map DMA area for LANCE\n");
+ bus_dmamem_free(dmat, &seg, rseg);
+ return;
}
- pmap_update(pmap_kernel());
/*
- * XXXEND
+ * Create and load the DMA map for the DMA area.
*/
+ if (bus_dmamap_create(dmat, LE_IOASIC_MEMSIZE, 1,
+ LE_IOASIC_MEMSIZE, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) {
+ printf("can't create DMA map\n");
+ goto bad;
+ }
+ if (bus_dmamap_load(dmat, sc->sc_dmamap,
+ le_iomem, LE_IOASIC_MEMSIZE, NULL, BUS_DMA_NOWAIT)) {
+ printf("can't load DMA map\n");
+ goto bad;
+ }
+ /*
+ * Bind 128KB buffer with IOASIC DMA.
+ */
+ tca = IOASIC_DMA_ADDR(sc->sc_dmamap->dm_segs[0].ds_addr);
+ bus_space_write_4(ioasic_bst, ioasic_bsh, IOASIC_LANCE_DMAPTR, tca);
+ ssr = bus_space_read_4(ioasic_bst, ioasic_bsh, IOASIC_CSR);
+ ssr |= IOASIC_CSR_DMAEN_LANCE;
+ bus_space_write_4(ioasic_bst, ioasic_bsh, IOASIC_CSR, ssr);
- lesc->sc_r1 = (struct lereg1 *)
+ sc->sc_r1 = (struct lereg1 *)
TC_DENSE_TO_SPARSE(TC_PHYS_TO_UNCACHED(d->iada_addr));
- sc->sc_mem = (void *)TC_PHYS_TO_UNCACHED(le_iomem);
-
- sc->sc_copytodesc = le_ioasic_copytobuf_gap2;
- sc->sc_copyfromdesc = le_ioasic_copyfrombuf_gap2;
- sc->sc_copytobuf = le_ioasic_copytobuf_gap16;
- sc->sc_copyfrombuf = le_ioasic_copyfrombuf_gap16;
- sc->sc_zerobuf = le_ioasic_zerobuf_gap16;
+ le->sc_mem = (void *)TC_PHYS_TO_UNCACHED(le_iomem);
+ le->sc_copytodesc = le_ioasic_copytobuf_gap2;
+ le->sc_copyfromdesc = le_ioasic_copyfrombuf_gap2;
+ le->sc_copytobuf = le_ioasic_copytobuf_gap16;
+ le->sc_copyfrombuf = le_ioasic_copyfrombuf_gap16;
+ le->sc_zerobuf = le_ioasic_zerobuf_gap16;
- ioasic_lance_dma_setup(le_iomem); /* XXX more thought */
-
- dec_le_common_attach(sc, ioasic_lance_ether_address());
+ dec_le_common_attach(&sc->sc_am7990,
+ (u_char *)((struct ioasic_softc *)parent)->sc_base
+ + IOASIC_SLOT_2_START);
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_NET,
am7990_intr, sc);
+ return;
+
+ bad:
+ bus_dmamem_unmap(dmat, le_iomem, LE_IOASIC_MEMSIZE);
+ bus_dmamem_free(dmat, &seg, rseg);
}
/*
@@ -161,11 +193,11 @@ le_ioasic_copytobuf_gap2(sc, fromv, boff, len)
struct am7990_softc *sc;
void *fromv;
int boff;
- register int len;
+ int len;
{
volatile caddr_t buf = sc->sc_mem;
- register caddr_t from = fromv;
- register volatile u_int16_t *bptr;
+ caddr_t from = fromv;
+ volatile u_int16_t *bptr;
if (boff & 0x1) {
/* handle unaligned first byte */
@@ -192,9 +224,9 @@ le_ioasic_copyfrombuf_gap2(sc, tov, boff, len)
int boff, len;
{
volatile caddr_t buf = sc->sc_mem;
- register caddr_t to = tov;
- register volatile u_int16_t *bptr;
- register u_int16_t tmp;
+ caddr_t to = tov;
+ volatile u_int16_t *bptr;
+ u_int16_t tmp;
if (boff & 0x1) {
/* handle unaligned first byte */
@@ -226,24 +258,84 @@ le_ioasic_copytobuf_gap16(sc, fromv, boff, len)
struct am7990_softc *sc;
void *fromv;
int boff;
- register int len;
+ int len;
{
volatile caddr_t buf = sc->sc_mem;
- register caddr_t from = fromv;
- register caddr_t bptr;
- register int xfer;
+ caddr_t from = fromv;
+ caddr_t bptr;
bptr = buf + ((boff << 1) & ~0x1f);
boff &= 0xf;
- xfer = min(len, 16 - boff);
- while (len > 0) {
+
+ /*
+ * Dispose of boff so destination of subsequent copies is
+ * 16-byte aligned.
+ */
+ if (boff) {
+ int xfer;
+ xfer = min(len, 16 - boff);
bcopy(from, bptr + boff, xfer);
from += xfer;
bptr += 32;
- boff = 0;
len -= xfer;
- xfer = min(len, 16);
}
+
+ /* Destination of copies is now 16-byte aligned. */
+ if (len >= 16)
+ switch ((u_long)from & (sizeof(u_int32_t) -1)) {
+ case 2:
+ /* Ethernet headers make this the dominant case. */
+ do {
+ u_int32_t *dst = (u_int32_t*)bptr;
+ u_int16_t t0;
+ u_int32_t t1, t2, t3, t4;
+
+ /* read from odd-16-bit-aligned, cached src */
+ t0 = *(u_int16_t*)from;
+ t1 = *(u_int32_t*)(from+2);
+ t2 = *(u_int32_t*)(from+6);
+ t3 = *(u_int32_t*)(from+10);
+ t4 = *(u_int16_t*)(from+14);
+
+ /* DMA buffer is uncached on mips */
+ dst[0] = t0 | (t1 << 16);
+ dst[1] = (t1 >> 16) | (t2 << 16);
+ dst[2] = (t2 >> 16) | (t3 << 16);
+ dst[3] = (t3 >> 16) | (t4 << 16);
+
+ from += 16;
+ bptr += 32;
+ len -= 16;
+ } while (len >= 16);
+ break;
+
+ case 0:
+ do {
+ u_int32_t *src = (u_int32_t*)from;
+ u_int32_t *dst = (u_int32_t*)bptr;
+ u_int32_t t0, t1, t2, t3;
+
+ t0 = src[0]; t1 = src[1]; t2 = src[2]; t3 = src[3];
+ dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
+
+ from += 16;
+ bptr += 32;
+ len -= 16;
+ } while (len >= 16);
+ break;
+
+ default:
+ /* Does odd-aligned case ever happen? */
+ do {
+ bcopy(from, bptr, 16);
+ from += 16;
+ bptr += 32;
+ len -= 16;
+ } while (len >= 16);
+ break;
+ }
+ if (len)
+ bcopy(from, bptr, len);
}
void
@@ -253,21 +345,73 @@ le_ioasic_copyfrombuf_gap16(sc, tov, boff, len)
int boff, len;
{
volatile caddr_t buf = sc->sc_mem;
- register caddr_t to = tov;
- register caddr_t bptr;
- register int xfer;
+ caddr_t to = tov;
+ caddr_t bptr;
bptr = buf + ((boff << 1) & ~0x1f);
boff &= 0xf;
- xfer = min(len, 16 - boff);
- while (len > 0) {
- bcopy(bptr + boff, to, xfer);
+
+ /* Dispose of boff. source of copy is subsequently 16-byte aligned. */
+ if (boff) {
+ int xfer;
+ xfer = min(len, 16 - boff);
+ bcopy(bptr+boff, to, xfer);
to += xfer;
bptr += 32;
- boff = 0;
len -= xfer;
- xfer = min(len, 16);
}
+ if (len >= 16)
+ switch ((u_long)to & (sizeof(u_int32_t) -1)) {
+ case 2:
+ /*
+ * to is aligned to an odd 16-bit boundary. Ethernet headers
+ * make this the dominant case (98% or more).
+ */
+ do {
+ u_int32_t *src = (u_int32_t*)bptr;
+ u_int32_t t0, t1, t2, t3;
+
+ /* read from uncached aligned DMA buf */
+ t0 = src[0]; t1 = src[1]; t2 = src[2]; t3 = src[3];
+
+ /* write to odd-16-bit-word aligned dst */
+ *(u_int16_t *) (to+0) = (u_short) t0;
+ *(u_int32_t *) (to+2) = (t0 >> 16) | (t1 << 16);
+ *(u_int32_t *) (to+6) = (t1 >> 16) | (t2 << 16);
+ *(u_int32_t *) (to+10) = (t2 >> 16) | (t3 << 16);
+ *(u_int16_t *) (to+14) = (t3 >> 16);
+ bptr += 32;
+ to += 16;
+ len -= 16;
+ } while (len > 16);
+ break;
+ case 0:
+ /* 32-bit aligned aligned copy. Rare. */
+ do {
+ u_int32_t *src = (u_int32_t*)bptr;
+ u_int32_t *dst = (u_int32_t*)to;
+ u_int32_t t0, t1, t2, t3;
+
+ t0 = src[0]; t1 = src[1]; t2 = src[2]; t3 = src[3];
+ dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
+ to += 16;
+ bptr += 32;
+ len -= 16;
+ } while (len > 16);
+ break;
+
+ /* XXX Does odd-byte-aligned case ever happen? */
+ default:
+ do {
+ bcopy(bptr, to, 16);
+ to += 16;
+ bptr += 32;
+ len -= 16;
+ } while (len > 16);
+ break;
+ }
+ if (len)
+ bcopy(bptr, to, len);
}
void
@@ -276,8 +420,8 @@ le_ioasic_zerobuf_gap16(sc, boff, len)
int boff, len;
{
volatile caddr_t buf = sc->sc_mem;
- register caddr_t bptr;
- register int xfer;
+ caddr_t bptr;
+ int xfer;
bptr = buf + ((boff << 1) & ~0x1f);
boff &= 0xf;
diff --git a/sys/dev/tc/if_le_tc.c b/sys/dev/tc/if_le_tc.c
index 704449b4ef8..deb0c87ac63 100644
--- a/sys/dev/tc/if_le_tc.c
+++ b/sys/dev/tc/if_le_tc.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_le_tc.c,v 1.5 2002/03/14 01:27:03 millert Exp $ */
-/* $NetBSD: if_le_tc.c,v 1.2 1996/05/07 02:24:57 thorpej Exp $ */
+/* $OpenBSD: if_le_tc.c,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: if_le_tc.c,v 1.12 2001/11/13 06:26:10 lukem Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -71,8 +71,7 @@ le_tc_match(parent, match, aux)
{
struct tc_attach_args *d = aux;
- if (strncmp("PMAD-AA ", d->ta_modname, TC_ROM_LLEN) &&
- strncmp("PMAD-BA ", d->ta_modname, TC_ROM_LLEN))
+ if (strncmp("PMAD-AA ", d->ta_modname, TC_ROM_LLEN) != 0)
return (0);
return (1);
@@ -83,8 +82,8 @@ le_tc_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- register struct le_softc *lesc = (void *)self;
- register struct am7990_softc *sc = &lesc->sc_am7990;
+ struct le_softc *lesc = (void *)self;
+ struct am7990_softc *sc = &lesc->sc_am7990;
struct tc_attach_args *d = aux;
/*
@@ -106,7 +105,8 @@ le_tc_attach(parent, self, aux)
* so DMA setup is not required.
*/
- dec_le_common_attach(sc, (u_char *)(d->ta_addr + LE_OFFSET_ROM + 2));
+ dec_le_common_attach(&lesc->sc_am7990,
+ (u_char *)(d->ta_addr + LE_OFFSET_ROM + 2));
tc_intr_establish(parent, d->ta_cookie, TC_IPL_NET, am7990_intr, sc);
}
diff --git a/sys/dev/tc/if_levar.h b/sys/dev/tc/if_levar.h
index 25843885576..1efab40ebee 100644
--- a/sys/dev/tc/if_levar.h
+++ b/sys/dev/tc/if_levar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_levar.h,v 1.5 2002/03/14 01:27:03 millert Exp $ */
-/* $NetBSD: if_levar.h,v 1.3 1996/05/07 02:24:58 thorpej Exp $ */
+/* $OpenBSD: if_levar.h,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: if_levar.h,v 1.4 1997/03/15 18:12:07 is Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -57,7 +57,7 @@ struct lereg1 {
* Ethernet software status per interface.
*
* Each interface is referenced by a network interface structure,
- * arpcom.ac_if, which the routing code uses to locate the interface.
+ * ethercom.ec_if, which the routing code uses to locate the interface.
* This structure contains the output queue for the interface, its address, ...
*/
struct le_softc {
diff --git a/sys/dev/tc/ioasic_subr.c b/sys/dev/tc/ioasic_subr.c
new file mode 100644
index 00000000000..bb3a4364da8
--- /dev/null
+++ b/sys/dev/tc/ioasic_subr.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: ioasic_subr.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: ioasic_subr.c,v 1.3 2001/11/13 06:26:10 lukem 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/systm.h>
+#include <sys/device.h>
+#include <dev/tc/tcvar.h>
+#include <dev/tc/ioasicvar.h>
+
+int ioasicprint(void *, const char *);
+
+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(vcf, d)
+ void *vcf;
+ struct ioasicdev_attach_args *d;
+{
+ struct cfdata *match = vcf;
+
+ return ((match->ioasiccf_offset == d->iada_offset) ||
+ (match->ioasiccf_offset == IOASIC_OFFSET_UNKNOWN));
+}
+
+void
+ioasic_attach_devs(sc, ioasic_devs, ioasic_ndevs)
+ struct ioasic_softc *sc;
+ struct ioasic_dev *ioasic_devs;
+ int ioasic_ndevs;
+{
+ struct ioasicdev_attach_args idev;
+ int i;
+
+ /*
+ * Try to configure each device.
+ */
+ for (i = 0; i < ioasic_ndevs; i++) {
+ strncpy(idev.iada_modname, ioasic_devs[i].iad_modname,
+ TC_ROM_LLEN);
+ idev.iada_modname[TC_ROM_LLEN] = '\0';
+ idev.iada_offset = ioasic_devs[i].iad_offset;
+ idev.iada_addr = sc->sc_base + ioasic_devs[i].iad_offset;
+ idev.iada_cookie = ioasic_devs[i].iad_cookie;
+
+ /* Tell the autoconfig machinery we've found the hardware. */
+ config_found(&sc->sc_dv, &idev, ioasicprint);
+ }
+}
diff --git a/sys/dev/tc/ioasicreg.h b/sys/dev/tc/ioasicreg.h
new file mode 100644
index 00000000000..067c15a79ab
--- /dev/null
+++ b/sys/dev/tc/ioasicreg.h
@@ -0,0 +1,204 @@
+/* $OpenBSD: ioasicreg.h,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: ioasicreg.h,v 1.6 2000/07/17 02:18:17 thorpej 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
+#define IOASIC_CTR IOASIC_SLOT_1_START+0x1e0 /*3max+/3000*/
+
+/* 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 - 3000 */
+#define IOASIC_CSR_xxx 0x07800000 /* reserved - 3000 */
+#define IOASIC_CSR_DS_xxx 0x0f800000 /* reserved - DS */
+#define IOASIC_CSR_FLOPPY_DIR 0x00400000 /* rw - maxine */
+#define IOASIC_CSR_DMAEN_FLOPPY 0x00200000 /* rw - maxine */
+#define IOASIC_CSR_DMAEN_ISDN_T 0x00100000 /* rw */
+#define IOASIC_CSR_DMAEN_ISDN_R 0x00080000 /* rw */
+#define IOASIC_CSR_SCSI_DIR 0x00040000 /* rw - DS */
+#define IOASIC_CSR_DMAEN_SCSI 0x00020000 /* rw - DS */
+#define IOASIC_CSR_DMAEN_LANCE 0x00010000 /* rw - DS */
+/* low 16 bits are rw gp outputs */
+#define IOASIC_CSR_DIAGDN 0x00008000 /* rw */
+#define IOASIC_CSR_TXDIS_2 0x00004000 /* rw - 3min,3max+ */
+#define IOASIC_CSR_TXDIS_1 0x00002000 /* rw - 3min,3max+ */
+#define IOASIC_CSR_ISDN_ENABLE 0x00001000 /* rw - 3000/maxine */
+#define IOASIC_CSR_SCC_ENABLE 0x00000800 /* rw */
+#define IOASIC_CSR_RTC_ENABLE 0x00000400 /* rw */
+#define IOASIC_CSR_SCSI_ENABLE 0x00000200 /* rw - DS */
+#define IOASIC_CSR_LANCE_ENABLE 0x00000100 /* rw */
+
+/* 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 - maxine */
+#define IOASIC_INTR_ISDN_TXLOAD 0x00400000 /* rz - 3000/maxine */
+#define IOASIC_INTR_ISDN_RXLOAD 0x00200000 /* rz - 3000/maxine */
+#define IOASIC_INTR_ISDN_OVRUN 0x00100000 /* rz - 3000/maxine */
+#define IOASIC_INTR_SCSI_PTR_LOAD 0x00080000 /* rz - DS */
+#define IOASIC_INTR_SCSI_OVRUN 0x00040000 /* rz - DS */
+#define IOASIC_INTR_SCSI_READ_E 0x00020000 /* rz - DS */
+#define IOASIC_INTR_LANCE_READ_E 0x00010000 /* rz - DS */
+
+/* low 16 bits are model-dependent; see also model specific *.h */
+#define IOASIC_INTR_NVR_JUMPER 0x00004000 /* ro */
+#define IOASIC_INTR_ISDN 0x00002000 /* ro - 3000 */
+#define IOASIC_INTR_NRMOD_JUMPER 0x00000400 /* ro */
+#define IOASIC_INTR_SEC_CON 0x00000200 /* ro */
+#define IOASIC_INTR_SCSI 0x00000200 /* ro - DS */
+#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 0x00000008 /* ro - 3000/300 */
+#define IOASIC_INTR_300_OPT0 0x00000004 /* ro - 3000/300 */
+
+/* DMA pointer registers (SCSI, Comm, ...) */
+
+#define IOASIC_DMA_ADDR(p) \
+ ((((p) << 3) & ~0x1f) | (((p) >> 29) & 0x1f))
+#define IOASIC_DMA_BLOCKSIZE 0x1000
+
+/* 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
+
+/*
+ * 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/dev/tc/ioasicvar.h b/sys/dev/tc/ioasicvar.h
index fe00a3fe465..09b95ac8414 100644
--- a/sys/dev/tc/ioasicvar.h
+++ b/sys/dev/tc/ioasicvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ioasicvar.h,v 1.5 2002/03/14 03:16:08 millert Exp $ */
-/* $NetBSD: ioasicvar.h,v 1.2 1996/03/17 21:37:45 jonathan Exp $ */
+/* $OpenBSD: ioasicvar.h,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: ioasicvar.h,v 1.14 2000/10/17 09:45:49 nisimura Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -28,11 +28,16 @@
* rights to redistribute these changes.
*/
-/*
- * IOASIC subdevice attachment information.
- */
+#ifndef _DEV_TC_IOASICVAR_H_
+#define _DEV_TC_IOASICVAR_H_
+
+struct ioasic_dev {
+ char *iad_modname;
+ tc_offset_t iad_offset;
+ void *iad_cookie;
+ u_int32_t iad_intrbits;
+};
-/* Attachment arguments. */
struct ioasicdev_attach_args {
char iada_modname[TC_ROM_LLEN];
tc_offset_t iada_offset;
@@ -45,30 +50,28 @@ struct ioasicdev_attach_args {
#define IOASIC_OFFSET_UNKNOWN -1
-/*
- * The IOASIC (bus) cfdriver, so that subdevices can more
- * easily tell what bus they're on.
- */
-extern struct cfdriver ioasic_cd;
+struct ioasic_softc {
+ struct device sc_dv;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
+ bus_dma_tag_t sc_dmat;
+
+ tc_addr_t sc_base; /* XXX offset XXX */
+};
+extern struct cfdriver ioasic_cd;
/*
* XXX Some drivers need direct access to IOASIC registers.
*/
extern tc_addr_t ioasic_base;
-
-/*
- * Interrupt establishment/disestablishment functions
- */
-void ioasic_intr_establish(struct device *, void *, tc_intrlevel_t,
- int (*)(void *), void *);
+const struct evcnt *ioasic_intr_evcnt(struct device *, void *);
+void ioasic_intr_establish(struct device *, void *,
+ int, int (*)(void *), void *);
void ioasic_intr_disestablish(struct device *, void *);
+int ioasic_submatch(void *, struct ioasicdev_attach_args *);
+void ioasic_attach_devs(struct ioasic_softc *,
+ struct ioasic_dev *, int);
-
-/*
- * Miscellaneous helper functions.
- */
-int ioasic_submatch(struct cfdata *, struct ioasicdev_attach_args *);
-char *ioasic_lance_ether_address(void);
-void ioasic_lance_dma_setup(void *);
+#endif /* _DEV_TC_IOASICVAR_ */
diff --git a/sys/dev/tc/tc.c b/sys/dev/tc/tc.c
index 63a132da7a3..d11a1375ba9 100644
--- a/sys/dev/tc/tc.c
+++ b/sys/dev/tc/tc.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc.c,v 1.11 2002/03/14 03:16:08 millert Exp $ */
-/* $NetBSD: tc.c,v 1.20 1996/10/22 21:37:29 cgd Exp $ */
+/* $OpenBSD: tc.c,v 1.12 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc.c,v 1.29 2001/11/13 06:26:10 lukem Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -36,19 +36,6 @@
#include <dev/tc/tcvar.h>
#include <dev/tc/tcdevs.h>
-#include <machine/autoconf.h> /* for the proto of badaddr() */
-
-struct tc_softc {
- struct device sc_dv;
-
- int sc_speed;
- int sc_nslots;
- struct tc_slotdesc *sc_slots;
-
- void (*sc_intr_establish)(struct device *, void *,
- tc_intrlevel_t, int (*)(void *), void *);
- void (*sc_intr_disestablish)(struct device *, void *);
-};
/* Definition of the driver for autoconfig. */
int tcmatch(struct device *, void *, void *);
@@ -68,13 +55,12 @@ int tc_checkslot(tc_addr_t, char *);
void tc_devinfo(const char *, char *);
int
-tcmatch(parent, cfdata, aux)
+tcmatch(parent, vcf, aux)
struct device *parent;
- void *cfdata;
- void *aux;
+ void *vcf, *aux;
{
- struct cfdata *cf = cfdata;
struct tcbus_attach_args *tba = aux;
+ struct cfdata *cf = vcf;
if (strcmp(tba->tba_busname, cf->cf_driver->cd_name))
return (0);
@@ -105,8 +91,10 @@ tcattach(parent, self, aux)
sc->sc_speed = tba->tba_speed;
sc->sc_nslots = tba->tba_nslots;
sc->sc_slots = tba->tba_slots;
+ sc->sc_intr_evcnt = tba->tba_intr_evcnt;
sc->sc_intr_establish = tba->tba_intr_establish;
sc->sc_intr_disestablish = tba->tba_intr_disestablish;
+ sc->sc_get_dma_tag = tba->tba_get_dma_tag;
/*
* Try to configure each built-in device
@@ -131,9 +119,8 @@ tcattach(parent, self, aux)
* Set up the device attachment information.
*/
strncpy(ta.ta_modname, builtin->tcb_modname, TC_ROM_LLEN);
-#ifdef __alpha__ /* XXX */
ta.ta_memt = tba->tba_memt;
-#endif
+ ta.ta_dmat = (*sc->sc_get_dma_tag)(builtin->tcb_slot);
ta.ta_modname[TC_ROM_LLEN] = '\0';
ta.ta_slot = builtin->tcb_slot;
ta.ta_offset = builtin->tcb_offset;
@@ -174,6 +161,8 @@ tcattach(parent, self, aux)
/*
* Set up the rest of the attachment information.
*/
+ ta.ta_memt = tba->tba_memt;
+ ta.ta_dmat = (*sc->sc_get_dma_tag)(i);
ta.ta_slot = i;
ta.ta_offset = 0;
ta.ta_addr = tcaddr;
@@ -209,12 +198,12 @@ tcprint(aux, pnp)
}
int
-tcsubmatch(parent, match, aux)
+tcsubmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
struct tc_attach_args *d = aux;
+ struct cfdata *cf = vcf;
if ((cf->tccf_slot != TCCF_SLOT_UNKNOWN) &&
(cf->tccf_slot != d->ta_slot))
@@ -223,7 +212,7 @@ tcsubmatch(parent, match, aux)
(cf->tccf_offset != d->ta_offset))
return 0;
- return ((*cf->cf_attach->ca_match)(parent, match, aux));
+ return ((*cf->cf_attach->ca_match)(parent, cf, aux));
}
@@ -273,17 +262,24 @@ tc_checkslot(slotbase, namep)
return (0);
}
+const struct evcnt *
+tc_intr_evcnt(struct device *dev, void *cookie)
+{
+ struct tc_softc *sc = tc_cd.cd_devs[0];
+
+ return ((*sc->sc_intr_evcnt)(dev, cookie));
+}
+
void
tc_intr_establish(dev, cookie, level, handler, arg)
struct device *dev;
void *cookie, *arg;
- tc_intrlevel_t level;
+ int level;
int (*handler)(void *);
{
- struct tc_softc *sc = (struct tc_softc *)dev;
+ struct tc_softc *sc = tc_cd.cd_devs[0];
- (*sc->sc_intr_establish)(sc->sc_dv.dv_parent, cookie, level,
- handler, arg);
+ (*sc->sc_intr_establish)(dev, cookie, level, handler, arg);
}
void
@@ -291,9 +287,9 @@ tc_intr_disestablish(dev, cookie)
struct device *dev;
void *cookie;
{
- struct tc_softc *sc = (struct tc_softc *)dev;
+ struct tc_softc *sc = tc_cd.cd_devs[0];
- (*sc->sc_intr_disestablish)(sc->sc_dv.dv_parent, cookie);
+ (*sc->sc_intr_disestablish)(dev, cookie);
}
#ifdef TCVERBOSE
diff --git a/sys/dev/tc/tcdevs b/sys/dev/tc/tcdevs
index cdf9662c160..0f6558ee15a 100644
--- a/sys/dev/tc/tcdevs
+++ b/sys/dev/tc/tcdevs
@@ -1,5 +1,5 @@
-$OpenBSD: tcdevs,v 1.5 1998/06/23 23:26:18 deraadt Exp $
-/* $NetBSD: tcdevs,v 1.6 1996/08/26 23:39:34 cgd Exp $ */
+$OpenBSD: tcdevs,v 1.6 2002/05/02 22:56:06 miod Exp $
+/* $NetBSD: tcdevs,v 1.17 2000/12/17 13:56:05 ad Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou
@@ -32,21 +32,26 @@ $OpenBSD: tcdevs,v 1.5 1998/06/23 23:26:18 deraadt Exp $
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-+device AV01B-AA lofi DecAudio LoFi audio/isdn
+device AV01B-AA lofi DecAudio \"LoFi\" audio/isdn
+device AV300-AA ??? Video capture option card
device DGLTA-FA otto DGLTA ATM
device FORE_ATM fa Fore TCA-100 ATM
device KZTSA-AA tza TZA FWD SCSI
-device OTTO otto DEC SRC OTTO ATM
+device OTTO otto DEC SRC \"OTTO\" ATM
device PMAD-AA le LANCE Ethernet
-device PMAF-AA fza DEFZA FDDI
-device PMAF-F fta DEFTA FDDI
+device PMAF-AA fza DEC FDDIcontroller 700 (DEFZA; fiber optic)
+device PMAF-FA fta DEFTA FDDI
device PMAG-AA mfb Monochrome Frame Buffer
device PMAG-BA cfb Color Frame Buffer
-device PMAG-CA ga 2D Graphics
-device PMAG-DA gq 3D Graphics (LM)
+device PMAG-CA px 2D Graphics (PX 2DA)
+device PMAG-DA pxg 3D Graphics (PXG LM-3DA)
+device PMAG-FA pxg 3D Graphics (PXG HE-3DA)
+device PMAG-FB pxg 3D Graphics (PXG HE+3DA)
+device PMAGB-FA pxg 3D Graphics (PXG HE+3DA)
+device PMAGB-FB pxg 3D Graphics (PXG HE+3DA)
# the following entry may be incorrect
device PMAG-DV xcfb Maxine Color Frame Buffer
-device PMAG-FA gq 3D Graphics (HE)
+device PMAG-JA ??? 24-plane True Color Frame Buffer (TX)
device PMAGB-BA sfb Smart Frame Buffer
device PMAGD sfbp Smart Frame Buffer Plus, unknown bpp
device PMAGD-AA sfbp Smart Frame Buffer Plus, 8bpp
@@ -55,6 +60,25 @@ device PMAZ-AA asc 53c94 SCSI
device PMAZ-DS tcds 53c94 TCDS SCSI (baseboard)
device PMAZ-FS tcds 53c94 TCDS Fast SCSI (baseboard)
device PMAZB-AA tcds 53c94 TCDS SCSI option card
+device PMAZB-AB tcds 53c94 TCDS SCSI option card
device PMAZC-AA tcds 53c94 TCDS Fast SCSI option card
+device PMTNV-AA ??? Non-volatile RAM option card
device T1D4PKT ds DECWRL Turbochannel T1
device T3PKT tt DECWRL Turbochannel T3
+device PMAT-AA tra DEC TurboChannel Token Ring Controller
+device PMABV-AA vba VME Adapter
+device PMAP-AA ??? Prestoserve
+device KWS_TD ??? Kubota Denali
+
+# the following entries are unconfirmed
+#device PMAD-AB le LANCE Ethernet
+#device PMAF-CA fza DEC FDDIcontroller 700C (DEFZA; copper)
+#device PMAG-DB ??? 8-plane 3D Grahpics (PXG)
+#device PMAG-AB ??? Monochrome Graphics Adapter (MX)
+#device PMAG-JB ??? 24-plane True Color Frame Buffer (TX)
+#device PMAGB-BB ??? 8-plane Color/Grayscale 2D SFB (HX)
+#device PMAGB-BC ??? 8-plane Color/Grayscale 2D SFB (HX)
+#define PMAGB-BD ??? 8-plane Color/Grayscale 2D SFB (HX)
+#define PMAGB-BE ??? 8-plane Color/Grayscale 2D SFB (HX)
+#device PMAGB-JB ??? 24-plane True Color Frame Buffer (TX)
+#device PMAZ-AB asc 53c94 SCSI
diff --git a/sys/dev/tc/tcdevs.h b/sys/dev/tc/tcdevs.h
index eaa29b985ea..9d4329fcb56 100644
--- a/sys/dev/tc/tcdevs.h
+++ b/sys/dev/tc/tcdevs.h
@@ -1,10 +1,12 @@
+/* $OpenBSD: tcdevs.h,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * OpenBSD: tcdevs,v 1.5 1998/06/23 23:26:18 deraadt Exp
+ * OpenBSD
*/
-/* $NetBSD: tcdevs,v 1.6 1996/08/26 23:39:34 cgd Exp $ */
+/* $NetBSD: tcdevs,v 1.17 2000/12/17 13:56:05 ad Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou
@@ -37,6 +39,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define TC_DEVICE_AV01B_AA "lofi"
+#define TC_DESCRIPTION_AV01B_AA "DecAudio \"LoFi\" audio/isdn"
+
+#define TC_DEVICE_AV300_AA "???"
+#define TC_DESCRIPTION_AV300_AA "Video capture option card"
+
#define TC_DEVICE_DGLTA_FA "otto"
#define TC_DESCRIPTION_DGLTA_FA "DGLTA ATM"
@@ -47,16 +55,16 @@
#define TC_DESCRIPTION_KZTSA_AA "TZA FWD SCSI"
#define TC_DEVICE_OTTO "otto"
-#define TC_DESCRIPTION_OTTO "DEC SRC OTTO ATM"
+#define TC_DESCRIPTION_OTTO "DEC SRC \"OTTO\" ATM"
#define TC_DEVICE_PMAD_AA "le"
#define TC_DESCRIPTION_PMAD_AA "LANCE Ethernet"
#define TC_DEVICE_PMAF_AA "fza"
-#define TC_DESCRIPTION_PMAF_AA "DEFZA FDDI"
+#define TC_DESCRIPTION_PMAF_AA "DEC FDDIcontroller 700 (DEFZA; fiber optic)"
-#define TC_DEVICE_PMAF_F "fta"
-#define TC_DESCRIPTION_PMAF_F "DEFTA FDDI"
+#define TC_DEVICE_PMAF_FA "fta"
+#define TC_DESCRIPTION_PMAF_FA "DEFTA FDDI"
#define TC_DEVICE_PMAG_AA "mfb"
#define TC_DESCRIPTION_PMAG_AA "Monochrome Frame Buffer"
@@ -64,17 +72,29 @@
#define TC_DEVICE_PMAG_BA "cfb"
#define TC_DESCRIPTION_PMAG_BA "Color Frame Buffer"
-#define TC_DEVICE_PMAG_CA "ga"
-#define TC_DESCRIPTION_PMAG_CA "2D Graphics"
+#define TC_DEVICE_PMAG_CA "px"
+#define TC_DESCRIPTION_PMAG_CA "2D Graphics (PX 2DA)"
+
+#define TC_DEVICE_PMAG_DA "pxg"
+#define TC_DESCRIPTION_PMAG_DA "3D Graphics (PXG LM-3DA)"
+
+#define TC_DEVICE_PMAG_FA "pxg"
+#define TC_DESCRIPTION_PMAG_FA "3D Graphics (PXG HE-3DA)"
+
+#define TC_DEVICE_PMAG_FB "pxg"
+#define TC_DESCRIPTION_PMAG_FB "3D Graphics (PXG HE+3DA)"
+
+#define TC_DEVICE_PMAGB_FA "pxg"
+#define TC_DESCRIPTION_PMAGB_FA "3D Graphics (PXG HE+3DA)"
-#define TC_DEVICE_PMAG_DA "gq"
-#define TC_DESCRIPTION_PMAG_DA "3D Graphics (LM)"
+#define TC_DEVICE_PMAGB_FB "pxg"
+#define TC_DESCRIPTION_PMAGB_FB "3D Graphics (PXG HE+3DA)"
#define TC_DEVICE_PMAG_DV "xcfb"
#define TC_DESCRIPTION_PMAG_DV "Maxine Color Frame Buffer"
-#define TC_DEVICE_PMAG_FA "gq"
-#define TC_DESCRIPTION_PMAG_FA "3D Graphics (HE)"
+#define TC_DEVICE_PMAG_JA "???"
+#define TC_DESCRIPTION_PMAG_JA "24-plane True Color Frame Buffer (TX)"
#define TC_DEVICE_PMAGB_BA "sfb"
#define TC_DESCRIPTION_PMAGB_BA "Smart Frame Buffer"
@@ -100,11 +120,29 @@
#define TC_DEVICE_PMAZB_AA "tcds"
#define TC_DESCRIPTION_PMAZB_AA "53c94 TCDS SCSI option card"
+#define TC_DEVICE_PMAZB_AB "tcds"
+#define TC_DESCRIPTION_PMAZB_AB "53c94 TCDS SCSI option card"
+
#define TC_DEVICE_PMAZC_AA "tcds"
#define TC_DESCRIPTION_PMAZC_AA "53c94 TCDS Fast SCSI option card"
+#define TC_DEVICE_PMTNV_AA "???"
+#define TC_DESCRIPTION_PMTNV_AA "Non-volatile RAM option card"
+
#define TC_DEVICE_T1D4PKT "ds"
#define TC_DESCRIPTION_T1D4PKT "DECWRL Turbochannel T1"
#define TC_DEVICE_T3PKT "tt"
#define TC_DESCRIPTION_T3PKT "DECWRL Turbochannel T3"
+
+#define TC_DEVICE_PMAT_AA "tra"
+#define TC_DESCRIPTION_PMAT_AA "DEC TurboChannel Token Ring Controller"
+
+#define TC_DEVICE_PMABV_AA "vba"
+#define TC_DESCRIPTION_PMABV_AA "VME Adapter"
+
+#define TC_DEVICE_PMAP_AA "???"
+#define TC_DESCRIPTION_PMAP_AA "Prestoserve"
+
+#define TC_DEVICE_KWS_TD "???"
+#define TC_DESCRIPTION_KWS_TD "Kubota Denali"
diff --git a/sys/dev/tc/tcdevs_data.h b/sys/dev/tc/tcdevs_data.h
index 26bd3621093..c16f2ea9a9f 100644
--- a/sys/dev/tc/tcdevs_data.h
+++ b/sys/dev/tc/tcdevs_data.h
@@ -1,10 +1,12 @@
+/* $OpenBSD: tcdevs_data.h,v 1.6 2002/05/02 22:56:06 miod Exp $ */
+
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * OpenBSD: tcdevs,v 1.5 1998/06/23 23:26:18 deraadt Exp
+ * OpenBSD
*/
-/* $NetBSD: tcdevs,v 1.6 1996/08/26 23:39:34 cgd Exp $ */
+/* $NetBSD: tcdevs,v 1.17 2000/12/17 13:56:05 ad Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou
@@ -39,6 +41,16 @@
struct tc_knowndev tc_knowndevs[] = {
{
+ "AV01B-AA",
+ TC_DEVICE_AV01B_AA,
+ TC_DESCRIPTION_AV01B_AA,
+ },
+ {
+ "AV300-AA",
+ TC_DEVICE_AV300_AA,
+ TC_DESCRIPTION_AV300_AA,
+ },
+ {
"DGLTA-FA",
TC_DEVICE_DGLTA_FA,
TC_DESCRIPTION_DGLTA_FA,
@@ -69,9 +81,9 @@ struct tc_knowndev tc_knowndevs[] = {
TC_DESCRIPTION_PMAF_AA,
},
{
- "PMAF-F ",
- TC_DEVICE_PMAF_F,
- TC_DESCRIPTION_PMAF_F,
+ "PMAF-FA ",
+ TC_DEVICE_PMAF_FA,
+ TC_DESCRIPTION_PMAF_FA,
},
{
"PMAG-AA ",
@@ -94,14 +106,34 @@ struct tc_knowndev tc_knowndevs[] = {
TC_DESCRIPTION_PMAG_DA,
},
{
+ "PMAG-FA ",
+ TC_DEVICE_PMAG_FA,
+ TC_DESCRIPTION_PMAG_FA,
+ },
+ {
+ "PMAG-FB ",
+ TC_DEVICE_PMAG_FB,
+ TC_DESCRIPTION_PMAG_FB,
+ },
+ {
+ "PMAGB-FA",
+ TC_DEVICE_PMAGB_FA,
+ TC_DESCRIPTION_PMAGB_FA,
+ },
+ {
+ "PMAGB-FB",
+ TC_DEVICE_PMAGB_FB,
+ TC_DESCRIPTION_PMAGB_FB,
+ },
+ {
"PMAG-DV ",
TC_DEVICE_PMAG_DV,
TC_DESCRIPTION_PMAG_DV,
},
{
- "PMAG-FA ",
- TC_DEVICE_PMAG_FA,
- TC_DESCRIPTION_PMAG_FA,
+ "PMAG-JA ",
+ TC_DEVICE_PMAG_JA,
+ TC_DESCRIPTION_PMAG_JA,
},
{
"PMAGB-BA",
@@ -144,11 +176,21 @@ struct tc_knowndev tc_knowndevs[] = {
TC_DESCRIPTION_PMAZB_AA,
},
{
+ "PMAZB-AB",
+ TC_DEVICE_PMAZB_AB,
+ TC_DESCRIPTION_PMAZB_AB,
+ },
+ {
"PMAZC-AA",
TC_DEVICE_PMAZC_AA,
TC_DESCRIPTION_PMAZC_AA,
},
{
+ "PMTNV-AA",
+ TC_DEVICE_PMTNV_AA,
+ TC_DESCRIPTION_PMTNV_AA,
+ },
+ {
"T1D4PKT ",
TC_DEVICE_T1D4PKT,
TC_DESCRIPTION_T1D4PKT,
@@ -158,5 +200,25 @@ struct tc_knowndev tc_knowndevs[] = {
TC_DEVICE_T3PKT,
TC_DESCRIPTION_T3PKT,
},
+ {
+ "PMAT-AA ",
+ TC_DEVICE_PMAT_AA,
+ TC_DESCRIPTION_PMAT_AA,
+ },
+ {
+ "PMABV-AA",
+ TC_DEVICE_PMABV_AA,
+ TC_DESCRIPTION_PMABV_AA,
+ },
+ {
+ "PMAP-AA ",
+ TC_DEVICE_PMAP_AA,
+ TC_DESCRIPTION_PMAP_AA,
+ },
+ {
+ "KWS_TD ",
+ TC_DEVICE_KWS_TD,
+ TC_DESCRIPTION_KWS_TD,
+ },
{ NULL, NULL, NULL, }
};
diff --git a/sys/dev/tc/tcds.c b/sys/dev/tc/tcds.c
new file mode 100644
index 00000000000..a69e5c7805f
--- /dev/null
+++ b/sys/dev/tc/tcds.c
@@ -0,0 +1,602 @@
+/* $OpenBSD: tcds.c,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tcds.c,v 1.3 2001/11/13 06:26:10 lukem Exp $ */
+
+/*-
+ * Copyright (c) 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.
+ * 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 <sys/malloc.h>
+
+#ifdef __alpha__
+#include <machine/rpb.h>
+#endif /* __alpha__ */
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <dev/ic/ncr53c9xvar.h>
+
+#include <machine/bus.h>
+
+#ifndef EVCNT_COUNTERS
+#include <machine/intrcnt.h>
+#endif
+
+#include <dev/tc/tcvar.h>
+#include <dev/tc/tcdsreg.h>
+#include <dev/tc/tcdsvar.h>
+
+struct tcds_softc {
+ struct device sc_dv;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
+ bus_dma_tag_t sc_dmat;
+ void *sc_cookie;
+ int sc_flags;
+ struct tcds_slotconfig sc_slots[2];
+};
+
+/* sc_flags */
+#define TCDSF_BASEBOARD 0x01 /* baseboard on DEC 3000 */
+#define TCDSF_FASTSCSI 0x02 /* supports Fast SCSI */
+
+/* Definition of the driver for autoconfig. */
+int tcdsmatch(struct device *, void *, void *);
+void tcdsattach(struct device *, struct device *, void *);
+int tcdsprint(void *, const char *);
+int tcdssubmatch(struct device *, void *, void *);
+
+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 *);
+
+struct tcds_device {
+ const char *td_name;
+ int td_flags;
+} tcds_devices[] = {
+#ifdef __alpha__
+ { "PMAZ-DS ", TCDSF_BASEBOARD },
+ { "PMAZ-FS ", TCDSF_BASEBOARD|TCDSF_FASTSCSI },
+#endif /* __alpha__ */
+ { "PMAZB-AA", 0 },
+ { "PMAZC-AA", TCDSF_FASTSCSI },
+ { NULL, 0 },
+};
+
+struct tcds_device *tcds_lookup(const char *);
+void tcds_params(struct tcds_softc *, int, int *, int *);
+
+struct tcds_device *
+tcds_lookup(modname)
+ const char *modname;
+{
+ struct tcds_device *td;
+
+ for (td = tcds_devices; td->td_name != NULL; td++)
+ if (strncmp(td->td_name, modname, TC_ROM_LLEN) == 0)
+ return (td);
+
+ return (NULL);
+}
+
+int
+tcdsmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata, *aux;
+{
+ struct tc_attach_args *ta = aux;
+
+ return (tcds_lookup(ta->ta_modname) != NULL);
+}
+
+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;
+ struct tcds_device *td;
+ bus_space_handle_t sbsh[2];
+ int i, gpi2;
+ const struct evcnt *pevcnt;
+
+ td = tcds_lookup(ta->ta_modname);
+ if (td == NULL)
+ panic("\ntcdsattach: impossible");
+
+ printf(": TurboChannel Dual SCSI");
+ if (td->td_flags & TCDSF_BASEBOARD)
+ printf(" (baseboard)");
+ printf("\n");
+
+ sc->sc_flags = td->td_flags;
+
+ sc->sc_bst = ta->ta_memt;
+ sc->sc_dmat = ta->ta_dmat;
+
+ /*
+ * Map the device.
+ */
+ if (bus_space_map(sc->sc_bst, ta->ta_addr,
+ (TCDS_SCSI1_OFFSET + 0x100), 0, &sc->sc_bsh)) {
+ printf("%s: unable to map device\n", sc->sc_dv.dv_xname);
+ return;
+ }
+
+ /*
+ * Now, slice off two subregions for the individual NCR SCSI chips.
+ */
+ if (bus_space_subregion(sc->sc_bst, sc->sc_bsh, TCDS_SCSI0_OFFSET,
+ 0x100, &sbsh[0]) ||
+ bus_space_subregion(sc->sc_bst, sc->sc_bsh, TCDS_SCSI1_OFFSET,
+ 0x100, &sbsh[1])) {
+ printf("%s: unable to subregion SCSI chip space\n",
+ sc->sc_dv.dv_xname);
+ return;
+ }
+
+ sc->sc_cookie = ta->ta_cookie;
+
+ pevcnt = tc_intr_evcnt(parent, sc->sc_cookie);
+ 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.
+ */
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_IMER, 0);
+
+ /* XXX Initial contents of CIR? */
+
+ /*
+ * Remember if GPI2 is set in the CIR; we'll need it later.
+ */
+ gpi2 = (bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR) &
+ TCDS_CIR_GPI_2) != 0;
+
+ /*
+ * Set up the per-slot defintions for later use.
+ */
+
+ /* fill in common information first */
+ for (i = 0; i < 2; i++) {
+ char *cp;
+
+ slotc = &sc->sc_slots[i];
+ bzero(slotc, sizeof *slotc); /* clear everything */
+
+ cp = slotc->sc_name;
+ snprintf(cp, sizeof(slotc->sc_name), "chip %d", i);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach_dynamic(&slotc->sc_evcnt, EVCNT_TYPE_INTR,
+ pevcnt, sc->sc_dv.dv_xname, cp);
+#endif
+
+ slotc->sc_slot = i;
+ slotc->sc_bst = sc->sc_bst;
+ slotc->sc_bsh = sc->sc_bsh;
+ 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_SCSI0_DMA_ADDR;
+ slotc->sc_dic = TCDS_SCSI0_DMA_INTR;
+ slotc->sc_dud0 = TCDS_SCSI0_DMA_DUD0;
+ slotc->sc_dud1 = 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_SCSI1_DMA_ADDR;
+ slotc->sc_dic = TCDS_SCSI1_DMA_INTR;
+ slotc->sc_dud0 = TCDS_SCSI1_DMA_DUD0;
+ slotc->sc_dud1 = TCDS_SCSI1_DMA_DUD1;
+
+ /* find the hardware attached to the TCDS ASIC */
+ for (i = 0; i < 2; i++) {
+ tcds_params(sc, i, &tcdsdev.tcdsda_id,
+ &tcdsdev.tcdsda_fast);
+
+ tcdsdev.tcdsda_bst = sc->sc_bst;
+ tcdsdev.tcdsda_bsh = sbsh[i];
+ tcdsdev.tcdsda_dmat = sc->sc_dmat;
+ tcdsdev.tcdsda_chip = i;
+ tcdsdev.tcdsda_sc = &sc->sc_slots[i];
+ /*
+ * Determine the chip frequency. TCDSF_FASTSCSI will be set
+ * for TC option cards. For baseboard chips, GPI2 is set, for a
+ * 25MHz clock, else a 40MHz clock.
+ */
+ if ((sc->sc_flags & TCDSF_BASEBOARD && gpi2 == 0) ||
+ sc->sc_flags & TCDSF_FASTSCSI) {
+ tcdsdev.tcdsda_freq = 40000000;
+ tcdsdev.tcdsda_period = tcdsdev.tcdsda_fast ? 4 : 8;
+ } else {
+ tcdsdev.tcdsda_freq = 25000000;
+ tcdsdev.tcdsda_period = 5;
+ }
+ if (sc->sc_flags & TCDSF_BASEBOARD)
+ tcdsdev.tcdsda_variant = NCR_VARIANT_NCR53C94;
+ else
+ tcdsdev.tcdsda_variant = NCR_VARIANT_NCR53C96;
+
+ tcds_scsi_reset(tcdsdev.tcdsda_sc);
+
+ config_found_sm(self, &tcdsdev, tcdsprint, tcdssubmatch);
+#ifdef __alpha__
+ /*
+ * The second SCSI chip isn't present on the baseboard TCDS
+ * on the DEC Alpha 3000/300 series.
+ */
+ if (sc->sc_flags & TCDSF_BASEBOARD &&
+ cputype == ST_DEC_3000_300)
+ break;
+#endif /* __alpha__ */
+ }
+}
+
+int
+tcdssubmatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct tcdsdev_attach_args *tcdsdev = aux;
+ struct cfdata *cf = vcf;
+
+ if (cf->cf_loc[0] != -1 &&
+ cf->cf_loc[0] != tcdsdev->tcdsda_chip)
+ return (0);
+
+ return ((*cf->cf_attach->ca_match)(parent, vcf, aux));
+}
+
+int
+tcdsprint(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ struct tcdsdev_attach_args *tcdsdev = aux;
+
+ /* Only ASCs can attach to TCDSs; easy. */
+ if (pnp)
+ printf("asc at %s", pnp);
+
+ printf(" chip %d", tcdsdev->tcdsda_chip);
+
+ return (UNCONF);
+}
+
+void
+tcds_intr_establish(tcds, slot, func, arg)
+ struct device *tcds;
+ int slot;
+ int (*func)(void *);
+ void *arg;
+{
+ struct tcds_softc *sc = (struct tcds_softc *)tcds;
+
+ if (sc->sc_slots[slot].sc_intrhand != tcds_intrnull)
+ panic("tcds_intr_establish: chip %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, slot)
+ struct device *tcds;
+ int slot;
+{
+ struct tcds_softc *sc = (struct tcds_softc *)tcds;
+
+ if (sc->sc_slots[slot].sc_intrhand == tcds_intrnull)
+ panic("tcds_intr_disestablish: chip %d missing intr",
+ slot);
+
+ sc->sc_slots[slot].sc_intrhand = tcds_intrnull;
+ sc->sc_slots[slot].sc_intrarg = (void *)(u_long)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 chip %lu\n",
+ (u_long)val);
+}
+
+void
+tcds_scsi_reset(sc)
+ struct tcds_slotconfig *sc;
+{
+ u_int32_t cir;
+
+ tcds_dma_enable(sc, 0);
+ tcds_scsi_enable(sc, 0);
+
+ cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
+ TCDS_CIR_CLR(cir, sc->sc_resetbits);
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, cir);
+
+ DELAY(1);
+
+ cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
+ TCDS_CIR_SET(cir, sc->sc_resetbits);
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, cir);
+
+ tcds_scsi_enable(sc, 1);
+ tcds_dma_enable(sc, 1);
+}
+
+void
+tcds_scsi_enable(sc, on)
+ struct tcds_slotconfig *sc;
+ int on;
+{
+ u_int32_t imer;
+
+ imer = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_IMER);
+
+ if (on)
+ imer |= sc->sc_intrmaskbits;
+ else
+ imer &= ~sc->sc_intrmaskbits;
+
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_IMER, imer);
+}
+
+void
+tcds_dma_enable(sc, on)
+ struct tcds_slotconfig *sc;
+ int on;
+{
+ u_int32_t cir;
+
+ cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
+
+ /* XXX Clear/set IOSLOT/PBS bits. */
+ if (on)
+ TCDS_CIR_SET(cir, sc->sc_dmabits);
+ else
+ TCDS_CIR_CLR(cir, sc->sc_dmabits);
+
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, cir);
+}
+
+int
+tcds_scsi_isintr(sc, clear)
+ struct tcds_slotconfig *sc;
+ int clear;
+{
+ u_int32_t cir;
+
+ cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
+
+ if ((cir & sc->sc_intrbits) != 0) {
+ if (clear) {
+ TCDS_CIR_CLR(cir, sc->sc_intrbits);
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR,
+ cir);
+ }
+ return (1);
+ } else
+ return (0);
+}
+
+int
+tcds_scsi_iserr(sc)
+ struct tcds_slotconfig *sc;
+{
+ u_int32_t cir;
+
+ cir = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
+ return ((cir & sc->sc_errorbits) != 0);
+}
+
+int
+tcds_intr(arg)
+ void *arg;
+{
+ struct tcds_softc *sc = arg;
+ u_int32_t ir, ir0;
+
+ /*
+ * XXX
+ * Copy and clear (gag!) the interrupts.
+ */
+ ir = ir0 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR);
+ TCDS_CIR_CLR(ir0, TCDS_CIR_ALLINTR);
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TCDS_CIR, ir0);
+ tc_syncbus();
+
+#ifdef EVCNT_COUNTERS
+#define INCRINTRCNT(slot) sc->sc_slots[slot].sc_evcnt.ev_count++
+#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("%s: %s", sc->sc_dv.dv_xname, 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);
+}
+
+void
+tcds_params(sc, chip, idp, fastp)
+ struct tcds_softc *sc;
+ int chip, *idp, *fastp;
+{
+ int id, fast;
+ u_int32_t ids;
+
+#ifdef __alpha__
+ if (sc->sc_flags & TCDSF_BASEBOARD) {
+ extern u_int8_t dec_3000_scsiid[], dec_3000_scsifast[];
+
+ id = dec_3000_scsiid[chip];
+ fast = dec_3000_scsifast[chip];
+ } else
+#endif /* __alpha__ */
+ {
+ /*
+ * SCSI IDs are stored in the EEPROM, along with whether or
+ * not the device is "fast". Chip 0 is the high nibble,
+ * chip 1 the low nibble.
+ */
+ ids = bus_space_read_4(sc->sc_bst, sc->sc_bsh, TCDS_EEPROM_IDS);
+ if (chip == 0)
+ ids >>= 4;
+
+ id = ids & 0x7;
+ fast = ids & 0x8;
+ }
+
+ if (id < 0 || id > 7) {
+ printf("%s: WARNING: bad SCSI ID %d for chip %d, using 7\n",
+ sc->sc_dv.dv_xname, id, chip);
+ id = 7;
+ }
+
+ if (fast)
+ printf("%s: fast mode set for chip %d\n",
+ sc->sc_dv.dv_xname, chip);
+
+ *idp = id;
+ *fastp = fast;
+}
diff --git a/sys/arch/alpha/tc/tcdsreg.h b/sys/dev/tc/tcdsreg.h
index 02cfdba2102..974f913a7d1 100644
--- a/sys/arch/alpha/tc/tcdsreg.h
+++ b/sys/dev/tc/tcdsreg.h
@@ -1,5 +1,5 @@
-/* $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 $ */
+/* $OpenBSD: tcdsreg.h,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tcdsreg.h,v 1.1 2000/07/04 02:22:20 nisimura Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -37,6 +37,9 @@
/*
* TCDS register offsets, bit masks.
*/
+#define TCDS_EEPROM 0x000000 /* EEPROM offset */
+#define TCDS_EEPROM_IDS 0x000008 /* SCSI IDs offset in EEPROM */
+
#define TCDS_CIR 0x040000 /* CIR offset */
/*
@@ -48,7 +51,7 @@
#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_2 0x00000040 /* 1 = 25MHz, 0 = 40MHz */
#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 */
@@ -132,7 +135,7 @@ void tcds_scsi_reset(int);
/*
* XXX
- * Start of MACH #defines, minimal changes to port to {Net/Open}BSD.
+ * Start of MACH #defines, minimal changes to port to NetBSD.
*
* The following register is the SCSI control interrupt register. It
* starts, stops and resets scsi DMA. It takes over the SCSI funtions
diff --git a/sys/arch/alpha/tc/tcdsvar.h b/sys/dev/tc/tcdsvar.h
index 5c73d575a94..e1470188d10 100644
--- a/sys/arch/alpha/tc/tcdsvar.h
+++ b/sys/dev/tc/tcdsvar.h
@@ -1,5 +1,5 @@
-/* $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 $ */
+/* $OpenBSD: tcdsvar.h,v 1.1 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tcdsvar.h,v 1.2 2001/08/22 05:00:27 nisimura Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -33,10 +33,14 @@ 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 */
+
+ bus_space_tag_t sc_bst; /* to frob TCDS regs */
+ bus_space_handle_t sc_bsh;
+
int (*sc_intrhand)(void *); /* intr. handler */
void *sc_intrarg; /* intr. handler arg. */
+ struct evcnt sc_evcnt; /* intr. count */
+ char sc_name[8]; /* ev_name */
/*
* Sets of bits in TCDS CIR and IMER that enable/check
@@ -49,64 +53,35 @@ struct tcds_slotconfig {
u_int32_t sc_errorbits;
/*
- * Pointers to slot-specific DMA resources.
+ * Offsets 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;
+ bus_size_t sc_sda;
+ bus_size_t sc_dic;
+ bus_size_t sc_dud0;
+ bus_size_t sc_dud1;
};
struct tcdsdev_attach_args {
- struct tc_attach_args tcdsda_ta;
- struct tcds_slotconfig *tcdsda_sc;
- u_int tcdsda_id;
- u_int tcdsda_freq;
+ bus_space_tag_t tcdsda_bst; /* bus space tag */
+ bus_space_handle_t tcdsda_bsh; /* bus space handle */
+ bus_dma_tag_t tcdsda_dmat; /* bus dma tag */
+ struct tcds_slotconfig *tcdsda_sc; /* slot configuration */
+ int tcdsda_chip; /* chip number */
+ int tcdsda_id; /* SCSI ID */
+ u_int tcdsda_freq; /* chip frequency */
+ int tcdsda_period; /* min. sync period */
+ int tcdsda_variant; /* NCR chip variant */
+ int tcdsda_fast; /* chip does Fast mode */
};
-#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,
+void tcds_intr_establish(struct device *, int,
int (*)(void *), void *);
-void tcds_intr_disestablish(struct device *, void *);
+void tcds_intr_disestablish(struct device *, int);
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;
diff --git a/sys/dev/tc/tcreg.h b/sys/dev/tc/tcreg.h
index 7cfe4de700f..115c749953d 100644
--- a/sys/dev/tc/tcreg.h
+++ b/sys/dev/tc/tcreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcreg.h,v 1.2 1997/11/07 08:07:52 niklas Exp $ */
+/* $OpenBSD: tcreg.h,v 1.3 2002/05/02 22:56:06 miod Exp $ */
/* $NetBSD: tcreg.h,v 1.1 1995/12/20 00:48:36 cgd Exp $ */
/*
diff --git a/sys/dev/tc/tcvar.h b/sys/dev/tc/tcvar.h
index 9725a823a6d..4c563692a76 100644
--- a/sys/dev/tc/tcvar.h
+++ b/sys/dev/tc/tcvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcvar.h,v 1.9 2002/03/14 03:16:08 millert Exp $ */
-/* $NetBSD: tcvar.h,v 1.7 1996/10/22 21:37:31 cgd Exp $ */
+/* $OpenBSD: tcvar.h,v 1.10 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tcvar.h,v 1.17 2000/06/04 19:15:15 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -32,7 +32,7 @@
#define __DEV_TC_TCVAR_H__
/*
- * Definitions for TurboChannel autoconfiguration.
+ * Definitions for TURBOchannel autoconfiguration.
*/
#include <machine/bus.h>
@@ -41,23 +41,16 @@
/*
* Machine-dependent definitions.
*/
-#if !defined(__alpha__)
-ERROR: COMPILING FOR UNSUPPORTED MACHINE, OR MORE THAN ONE.
-#endif
-#ifdef __alpha__
-#include <alpha/tc/tc_machdep.h>
-#endif
+#include <machine/tc_machdep.h>
/*
- * In the long run, the following block will go completely away
- * (i.e. both parts of the #if, including the #include, etc.).
- * For now, the MI TC code still uses the old definitions provided
- * by the pmax port, and not the new definitions provided by the
- * alpha port.
+ * In the long run, the following block will go completely away.
+ * For now, the MI TC code still uses the old TC_IPL_ names
+ * and not the new IPL_ names.
*/
-#ifdef __alpha__
+#if 1
/*
- * On the alpha, map the new definitions to the old.
+ * Map the new definitions to the old.
*/
#include <machine/intr.h>
@@ -68,17 +61,28 @@ ERROR: COMPILING FOR UNSUPPORTED MACHINE, OR MORE THAN ONE.
#define TC_IPL_NET IPL_NET
#define TC_IPL_TTY IPL_TTY
#define TC_IPL_CLOCK IPL_CLOCK
+#endif /* 1 */
-#endif
+struct tc_softc {
+ struct device sc_dv;
+
+ int sc_speed;
+ int sc_nslots;
+ struct tc_slotdesc *sc_slots;
+
+ const struct evcnt *(*sc_intr_evcnt)(struct device *, void *);
+ void (*sc_intr_establish)(struct device *, void *,
+ int, int (*)(void *), void *);
+ void (*sc_intr_disestablish)(struct device *, void *);
+ bus_dma_tag_t (*sc_get_dma_tag)(int);
+};
/*
- * Arguments used to attach TurboChannel busses.
+ * Arguments used to attach TURBOchannel busses.
*/
struct tcbus_attach_args {
char *tba_busname; /* XXX should be common */
-#ifdef __alpha__ /* XXX */
bus_space_tag_t tba_memt;
-#endif
/* Bus information */
u_int tba_speed; /* see TC_SPEED_* below */
@@ -89,18 +93,19 @@ struct tcbus_attach_args {
/* TC bus resource management; XXX will move elsewhere eventually. */
+ const struct evcnt *(*tba_intr_evcnt)(struct device *, void *);
void (*tba_intr_establish)(struct device *, void *,
- tc_intrlevel_t, int (*)(void *), void *);
+ int, int (*)(void *), void *);
void (*tba_intr_disestablish)(struct device *, void *);
+ bus_dma_tag_t (*tba_get_dma_tag)(int);
};
/*
- * Arguments used to attach TurboChannel devices.
+ * Arguments used to attach TURBOchannel devices.
*/
struct tc_attach_args {
-#ifdef __alpha__ /* XXX */
bus_space_tag_t ta_memt;
-#endif
+ bus_dma_tag_t ta_dmat;
char ta_modname[TC_ROM_LLEN+1];
u_int ta_slot;
@@ -111,8 +116,8 @@ struct tc_attach_args {
};
/*
- * Description of TurboChannel slots, provided by machine-dependent
- * code to the TurboChannel bus driver.
+ * Description of TURBOchannel slots, provided by machine-dependent
+ * code to the TURBOchannel bus driver.
*/
struct tc_slotdesc {
tc_addr_t tcs_addr;
@@ -121,8 +126,8 @@ struct tc_slotdesc {
};
/*
- * Description of built-in TurboChannel devices, provided by
- * machine-dependent code to the TurboChannel bus driver.
+ * Description of built-in TURBOchannel devices, provided by
+ * machine-dependent code to the TURBOchannel bus driver.
*/
struct tc_builtin {
char *tcb_modname;
@@ -134,12 +139,16 @@ struct tc_builtin {
/*
* Interrupt establishment functions.
*/
-void tc_intr_establish(struct device *, void *, tc_intrlevel_t,
- int (*)(void *), void *);
+int tc_checkslot(tc_addr_t, char *);
+void tc_devinfo(const char *, char *);
+void tcattach(struct device *, struct device *, void *);
+const struct evcnt *tc_intr_evcnt(struct device *, void *);
+void tc_intr_establish(struct device *, void *, int, int (*)(void *),
+ void *);
void tc_intr_disestablish(struct device *, void *);
/*
- * Easy to remember names for TurboChannel device locators.
+ * Easy to remember names for TURBOchannel device locators.
*/
#define tccf_slot cf_loc[0] /* slot */
#define tccf_offset cf_loc[1] /* offset */
@@ -153,10 +162,4 @@ void tc_intr_disestablish(struct device *, void *);
#define TC_SPEED_12_5_MHZ 0 /* 12.5MHz TC bus */
#define TC_SPEED_25_MHZ 1 /* 25MHz TC bus */
-/*
- * The TurboChannel bus cfdriver, so that subdevices can more
- * easily tell what bus they're on.
- */
-extern struct cfdriver tc_cd;
-
#endif /* __DEV_TC_TCVAR_H__ */